Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d130c55be5 | ||
|
|
0e2100f383 | ||
|
|
26f702b7a4 | ||
|
|
37bd700564 | ||
|
|
684e05109d | ||
|
|
676ae05335 | ||
|
|
a17b431669 | ||
|
|
493893d2e6 | ||
|
|
8976b5aedb | ||
|
|
6e7b09cf6f | ||
|
|
11501ff7bb | ||
|
|
59f0c025e5 | ||
|
|
cebc456bc1 | ||
|
|
2d1b12b5d8 | ||
|
|
bf3fecf5c0 | ||
|
|
5c012ba228 | ||
|
|
5644914fe3 | ||
|
|
b662e4daf9 |
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/
|
||||||
@@ -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)
|
||||||
#
|
NGL_ADD_SUBDIR_GUARDED(TetraIF)
|
||||||
FIND_PACKAGE(RTI QUIET)
|
NGL_ADD_SUBDIR_GUARDED(Z/src)
|
||||||
if(NOT RTI_FOUND)
|
NGL_ADD_SUBDIR_GUARDED(Lts)
|
||||||
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(Z/src)
|
|
||||||
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,64 +15,21 @@ 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)
|
# Excludes: Tools, Application, DDS, Services, most of Proxies, Plugins, Viewer, Projects
|
||||||
# For first release: only build Lts/Common and Lts/Proxies/TrainingAreaBase (tabTelegrams library)
|
message(STATUS "Building Lts/Common and Lts/Proxies/TrainingAreaBase")
|
||||||
# Excludes: Tools, Application, DDS, Services, most of Proxies, Plugins, Viewer, Projects
|
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Common")
|
||||||
message(STATUS "RELEASE_BUILD=ON: Building Lts/Common and Lts/Proxies/TrainingAreaBase")
|
NGL_ADD_SUBDIR_GUARDED(Common)
|
||||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Common")
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(Common)
|
|
||||||
else()
|
|
||||||
message(STATUS "Skipping missing Lts subdirectory: Common")
|
|
||||||
endif()
|
|
||||||
# TrainingAreaBase provides tabTelegrams library needed by TetraIF/CoPrtCnv
|
|
||||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Proxies/TrainingAreaBase")
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(Proxies/TrainingAreaBase)
|
|
||||||
else()
|
|
||||||
message(STATUS "Skipping missing Lts subdirectory: Proxies/TrainingAreaBase")
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
set(LTS_SUBDIRS Tools Application DDS Common Services Proxies Plugins Viewer Projects)
|
message(STATUS "Skipping missing Lts subdirectory: Common")
|
||||||
foreach(dir IN LISTS LTS_SUBDIRS)
|
endif()
|
||||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${dir}")
|
# TrainingAreaBase provides tabTelegrams library needed by TetraIF/CoPrtCnv
|
||||||
# Use guarded add so top-level MIGRATE_MODULE can restrict which Lts subdirs are included
|
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Proxies/TrainingAreaBase")
|
||||||
NGL_ADD_SUBDIR_GUARDED(${dir})
|
NGL_ADD_SUBDIR_GUARDED(Proxies/TrainingAreaBase)
|
||||||
else()
|
else()
|
||||||
message(STATUS "Skipping missing Lts subdirectory: ${dir}")
|
message(STATUS "Skipping missing Lts subdirectory: Proxies/TrainingAreaBase")
|
||||||
endif()
|
|
||||||
|
|
||||||
endforeach()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
IF (BUILD_TESTING)
|
# Export headers included by bare name from module sources (release scope)
|
||||||
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,59 +4,22 @@
|
|||||||
# $Author$
|
# $Author$
|
||||||
#
|
#
|
||||||
|
|
||||||
# RELEASE_BUILD: exclude modules with DDS/RTI dependencies not needed for TetraIF/Z
|
# Core modules needed for TetraIF and Z
|
||||||
# DDS-dependent modules: CodeGen, LtsAppManager, LtsBotan, LtsCoordinate, LtsElevation,
|
ADD_SUBDIRECTORY(CommonUnitTestsPlaceholder)
|
||||||
# LtsLogin, LtsMultiMonitor, LtsPluginManager, LtsPrinting, LtsProjectionWorkstation,
|
ADD_SUBDIRECTORY(httq)
|
||||||
|
ADD_SUBDIRECTORY(LtsAppDescriptor)
|
||||||
|
ADD_SUBDIRECTORY(LtsCommandLineParser)
|
||||||
|
ADD_SUBDIRECTORY(LtsCoordTrans)
|
||||||
|
ADD_SUBDIRECTORY(LtsLicence)
|
||||||
|
ADD_SUBDIRECTORY(LtsNotification)
|
||||||
|
ADD_SUBDIRECTORY(LtsRestClient)
|
||||||
|
ADD_SUBDIRECTORY(LtsSerialPortQuerry)
|
||||||
|
# Excluded: LtsTimeline (depends on LtsWidgets which has DDS dependencies)
|
||||||
|
ADD_SUBDIRECTORY(LtsUtils)
|
||||||
|
ADD_SUBDIRECTORY(LtsWebSocket)
|
||||||
|
ADD_SUBDIRECTORY(PluginInterfaces)
|
||||||
|
ADD_SUBDIRECTORY(ProjectConfig)
|
||||||
|
# Excluded: CodeGen, LtsAppManager, LtsBotan, LtsCoordinate, LtsElevation, LtsLogin,
|
||||||
|
# LtsMultiMonitor, LtsPluginManager, LtsPrinting, LtsProjectionWorkstation,
|
||||||
# LtsScriptTimeline, LtsSession, LtsTimelineClassic, LtsVirtualKeyboard, LtsWidgets,
|
# LtsScriptTimeline, LtsSession, LtsTimelineClassic, LtsVirtualKeyboard, LtsWidgets,
|
||||||
# PluginInterfaces (TopicReplayInterface, RecordReplayPlugin), TopicEditorBase
|
# TopicEditorBase
|
||||||
|
|
||||||
if(RELEASE_BUILD)
|
|
||||||
# Core modules needed for TetraIF and Z
|
|
||||||
ADD_SUBDIRECTORY(CommonUnitTestsPlaceholder)
|
|
||||||
ADD_SUBDIRECTORY(httq)
|
|
||||||
ADD_SUBDIRECTORY(LtsAppDescriptor)
|
|
||||||
ADD_SUBDIRECTORY(LtsCommandLineParser)
|
|
||||||
ADD_SUBDIRECTORY(LtsCoordTrans)
|
|
||||||
ADD_SUBDIRECTORY(LtsLicence)
|
|
||||||
ADD_SUBDIRECTORY(LtsNotification)
|
|
||||||
ADD_SUBDIRECTORY(LtsRestClient)
|
|
||||||
ADD_SUBDIRECTORY(LtsSerialPortQuerry)
|
|
||||||
# Excluded: LtsTimeline (depends on LtsWidgets which has DDS dependencies)
|
|
||||||
ADD_SUBDIRECTORY(LtsUtils)
|
|
||||||
ADD_SUBDIRECTORY(LtsWebSocket)
|
|
||||||
ADD_SUBDIRECTORY(PluginInterfaces)
|
|
||||||
ADD_SUBDIRECTORY(ProjectConfig)
|
|
||||||
# Excluded: CodeGen, LtsAppManager, LtsBotan, LtsCoordinate, LtsElevation, LtsLogin,
|
|
||||||
# LtsMultiMonitor, LtsPluginManager, LtsPrinting, LtsProjectionWorkstation,
|
|
||||||
# LtsScriptTimeline, LtsSession, LtsTimelineClassic, LtsVirtualKeyboard, LtsWidgets,
|
|
||||||
# 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()
|
|
||||||
+9
-7
@@ -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);
|
{
|
||||||
return RUN_ALL_TESTS();
|
::testing::InitGoogleTest(&argc, argv);
|
||||||
}
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
||||||
+4
-6
@@ -1,14 +1,12 @@
|
|||||||
// Stub QtTest smoke test for coordTrans
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
class CoordTransSmokeTest : public QObject
|
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)
|
||||||
+9
-9
@@ -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,12 +6,14 @@
|
|||||||
#include <QtCore/QPointF>
|
#include <QtCore/QPointF>
|
||||||
|
|
||||||
// Minimal stub to satisfy linker requirements
|
// Minimal stub to satisfy linker requirements
|
||||||
namespace LtsCoordTrans {
|
namespace LtsCoordTrans
|
||||||
// Placeholder types
|
{
|
||||||
struct UtmCoordinate {
|
// Placeholder types
|
||||||
static UtmCoordinate fromMgrs(const QString&) { return UtmCoordinate(); }
|
struct UtmCoordinate
|
||||||
QPointF geographic() const { return QPointF(); }
|
{
|
||||||
};
|
static UtmCoordinate fromMgrs(const QString &) { return UtmCoordinate(); }
|
||||||
|
QPointF geographic() const { return QPointF(); }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MOCK_COORD_TRANS_H
|
#endif // MOCK_COORD_TRANS_H
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -9,110 +9,108 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication a(argc, argv);
|
QCoreApplication a(argc, argv);
|
||||||
|
|
||||||
const QStringList args(a.arguments());
|
const QStringList args(a.arguments());
|
||||||
|
|
||||||
if (args.count() != 3)
|
if (args.count() != 3)
|
||||||
|
{
|
||||||
|
printf("usage: %s <current source directory> <apps.json>\n", args.at(0).toStdString().c_str());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString currentSrcDir(a.arguments().at(1));
|
||||||
|
|
||||||
|
const QString appsJsonFilePath(QStringLiteral("%1/%2").arg(currentSrcDir, a.arguments().at(2)));
|
||||||
|
QFile f(appsJsonFilePath);
|
||||||
|
|
||||||
|
if (!f.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
|
printf("LtsAppDescriptorChecker: cannot open apps.json at %s: %s\n", appsJsonFilePath.toStdString().c_str(), f.errorString().toStdString().c_str());
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("LtsAppDescriptorChecker: checking %s\n", appsJsonFilePath.toStdString().c_str());
|
||||||
|
|
||||||
|
QStringList lastErrors;
|
||||||
|
QStringList dummy1;
|
||||||
|
QString dummy2;
|
||||||
|
LtsAppDescriptor::AppDescriptionVector adv = LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(f.readAll(), lastErrors, dummy1, dummy2);
|
||||||
|
|
||||||
|
if (!lastErrors.isEmpty())
|
||||||
|
{
|
||||||
|
printf("LtsAppDescriptorChecker: apps.json at %s invalid:\n%s\n",
|
||||||
|
appsJsonFilePath.toStdString().c_str(),
|
||||||
|
lastErrors.join(QStringLiteral("\r\n\r\n")).toStdString().c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFileInfoList guiPluginFiles;
|
||||||
|
QDirIterator it(QStringLiteral("%1/../../Plugins/").arg(currentSrcDir), QDirIterator::Subdirectories);
|
||||||
|
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
QString filename(it.next());
|
||||||
|
QFileInfo file(filename);
|
||||||
|
|
||||||
|
if (file.isDir())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (file.fileName().endsWith(QStringLiteral("_gui_plugin.h"), Qt::CaseInsensitive))
|
||||||
|
guiPluginFiles.append(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList filenames;
|
||||||
|
filenames.reserve(guiPluginFiles.size());
|
||||||
|
for (const QFileInfo &fi : std::as_const(guiPluginFiles))
|
||||||
|
{
|
||||||
|
filenames += fi.absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList guiPluginIIDs;
|
||||||
|
for (const QFileInfo &fi : std::as_const(guiPluginFiles))
|
||||||
|
{
|
||||||
|
QFile f2(fi.absoluteFilePath());
|
||||||
|
|
||||||
|
if (!f2.open(QFile::ReadOnly))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QTextStream ts(&f2);
|
||||||
|
while (!ts.atEnd())
|
||||||
{
|
{
|
||||||
printf("usage: %s <current source directory> <apps.json>\n", args.at(0).toStdString().c_str());
|
QString line(ts.readLine().trimmed().simplified());
|
||||||
return -1;
|
static QString iidIdentifier(QStringLiteral("Q_PLUGIN_METADATA"));
|
||||||
}
|
|
||||||
|
|
||||||
const QString currentSrcDir(a.arguments().at(1));
|
if (line.contains(iidIdentifier))
|
||||||
|
{
|
||||||
const QString appsJsonFilePath(QStringLiteral("%1/%2").arg(currentSrcDir, a.arguments().at(2)));
|
QRegularExpression re(QStringLiteral("(?<=gui:3:).*(?=\"\\))"));
|
||||||
QFile f(appsJsonFilePath);
|
QRegularExpressionMatch match = re.match(line);
|
||||||
|
if (match.hasMatch())
|
||||||
if (!f.open(QFile::ReadOnly))
|
|
||||||
{
|
|
||||||
printf("LtsAppDescriptorChecker: cannot open apps.json at %s: %s\n", appsJsonFilePath.toStdString().c_str(),
|
|
||||||
f.errorString().toStdString().c_str());
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("LtsAppDescriptorChecker: checking %s\n", appsJsonFilePath.toStdString().c_str());
|
|
||||||
|
|
||||||
QStringList lastErrors;
|
|
||||||
QStringList dummy1;
|
|
||||||
QString dummy2;
|
|
||||||
LtsAppDescriptor::AppDescriptionVector adv =
|
|
||||||
LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(f.readAll(), lastErrors, dummy1, dummy2);
|
|
||||||
|
|
||||||
if (!lastErrors.isEmpty())
|
|
||||||
{
|
|
||||||
printf("LtsAppDescriptorChecker: apps.json at %s invalid:\n%s\n", appsJsonFilePath.toStdString().c_str(),
|
|
||||||
lastErrors.join(QStringLiteral("\r\n\r\n")).toStdString().c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfoList guiPluginFiles;
|
|
||||||
QDirIterator it(QStringLiteral("%1/../../Plugins/").arg(currentSrcDir), QDirIterator::Subdirectories);
|
|
||||||
|
|
||||||
while (it.hasNext())
|
|
||||||
{
|
|
||||||
QString filename(it.next());
|
|
||||||
QFileInfo file(filename);
|
|
||||||
|
|
||||||
if (file.isDir())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (file.fileName().endsWith(QStringLiteral("_gui_plugin.h"), Qt::CaseInsensitive))
|
|
||||||
guiPluginFiles.append(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList filenames;
|
|
||||||
filenames.reserve(guiPluginFiles.size());
|
|
||||||
for (const QFileInfo& fi : std::as_const(guiPluginFiles))
|
|
||||||
{
|
|
||||||
filenames += fi.absoluteFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList guiPluginIIDs;
|
|
||||||
for (const QFileInfo& fi : std::as_const(guiPluginFiles))
|
|
||||||
{
|
|
||||||
QFile f2(fi.absoluteFilePath());
|
|
||||||
|
|
||||||
if (!f2.open(QFile::ReadOnly))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QTextStream ts(&f2);
|
|
||||||
while (!ts.atEnd())
|
|
||||||
{
|
{
|
||||||
QString line(ts.readLine().trimmed().simplified());
|
QString matched = match.captured(0);
|
||||||
static QString iidIdentifier(QStringLiteral("Q_PLUGIN_METADATA"));
|
|
||||||
|
|
||||||
if (line.contains(iidIdentifier))
|
guiPluginIIDs += matched;
|
||||||
{
|
|
||||||
QRegularExpression re(QStringLiteral("(?<=gui:3:).*(?=\"\\))"));
|
|
||||||
QRegularExpressionMatch match = re.match(line);
|
|
||||||
if (match.hasMatch())
|
|
||||||
{
|
|
||||||
QString matched = match.captured(0);
|
|
||||||
|
|
||||||
guiPluginIIDs += matched;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
for (const LtsAppDescriptor::AppDescription& appdesc : std::as_const(adv))
|
for (const LtsAppDescriptor::AppDescription &appdesc : std::as_const(adv))
|
||||||
|
{
|
||||||
|
for (const LtsAppDescriptor::PluginInfo &pi : std::as_const(appdesc.pluginInfos))
|
||||||
{
|
{
|
||||||
for (const LtsAppDescriptor::PluginInfo& pi : std::as_const(appdesc.pluginInfos))
|
if (!guiPluginIIDs.contains(pi.iid))
|
||||||
{
|
{
|
||||||
if (!guiPluginIIDs.contains(pi.iid))
|
printf("LtsAppDescriptorChecker: apps.json at '%s' uses unknown IID '%s'\n", appsJsonFilePath.toStdString().c_str(), pi.iid.toStdString().c_str());
|
||||||
{
|
ok = false;
|
||||||
printf("LtsAppDescriptorChecker: apps.json at '%s' uses unknown IID '%s'\n",
|
}
|
||||||
appsJsonFilePath.toStdString().c_str(), pi.iid.toStdString().c_str());
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return !ok;
|
return !ok;
|
||||||
}
|
}
|
||||||
+116
-122
@@ -11,20 +11,20 @@
|
|||||||
|
|
||||||
namespace LtsAppDescriptor
|
namespace LtsAppDescriptor
|
||||||
{
|
{
|
||||||
static void addOptionToPlugin(PluginInfo& pluginInfo, const PluginInfo::Flag& flag)
|
static void addOptionToPlugin(PluginInfo &pluginInfo, const PluginInfo::Flag &flag)
|
||||||
{
|
{
|
||||||
pluginInfo.flags |= flag;
|
pluginInfo.flags |= flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addOptionToPlugin(QVector<PluginInfo>& pluginInfos, const PluginInfo::Flag& flag, const QString& pluginName)
|
static void addOptionToPlugin(QVector<PluginInfo> &pluginInfos, const PluginInfo::Flag &flag, const QString &pluginName)
|
||||||
{
|
{
|
||||||
for (PluginInfo& pi : pluginInfos)
|
for (PluginInfo &pi : pluginInfos)
|
||||||
{
|
{
|
||||||
if (pi.iid == pluginName)
|
if (pi.iid == pluginName)
|
||||||
{
|
{
|
||||||
addOptionToPlugin(pi, flag);
|
addOptionToPlugin(pi, flag);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginInfo pi;
|
PluginInfo pi;
|
||||||
@@ -32,74 +32,78 @@ static void addOptionToPlugin(QVector<PluginInfo>& pluginInfos, const PluginInfo
|
|||||||
pi.type = PluginInfo::PluginType::GUI;
|
pi.type = PluginInfo::PluginType::GUI;
|
||||||
addOptionToPlugin(pi, flag);
|
addOptionToPlugin(pi, flag);
|
||||||
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);
|
||||||
if (optionsObjectIt != optionsObject.constEnd())
|
if (optionsObjectIt != optionsObject.constEnd())
|
||||||
{
|
{
|
||||||
const QJsonArray plugins((*optionsObjectIt).toObject()[QStringLiteral("Plugins")].toArray());
|
const QJsonArray plugins((*optionsObjectIt).toObject()[QStringLiteral("Plugins")].toArray());
|
||||||
|
|
||||||
for (const auto& pluginElem : plugins)
|
for (const auto &pluginElem : plugins)
|
||||||
|
{
|
||||||
|
const QString pluginName = pluginElem.toString();
|
||||||
|
if (!ignoredPlugins.contains(pluginName))
|
||||||
{
|
{
|
||||||
const QString pluginName = pluginElem.toString();
|
addOptionToPlugin(appDesc.pluginInfos, flag, pluginName);
|
||||||
if (!ignoredPlugins.contains(pluginName))
|
hasPlugins = true;
|
||||||
{
|
|
||||||
addOptionToPlugin(appDesc.pluginInfos, flag, pluginName);
|
|
||||||
hasPlugins = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
App LtsAppDescriptor::appFromInteger(int i)
|
App LtsAppDescriptor::appFromInteger(int i)
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case int(App::Login):
|
case int(App::Login):
|
||||||
case int(App::Situation):
|
case int(App::Situation):
|
||||||
case int(App::ResourceManager):
|
case int(App::ResourceManager):
|
||||||
case int(App::PlanEditor):
|
case int(App::PlanEditor):
|
||||||
case int(App::BuildingViewer):
|
case int(App::BuildingViewer):
|
||||||
case int(App::OC):
|
case int(App::OC):
|
||||||
case int(App::OrgChart):
|
case int(App::OrgChart):
|
||||||
case int(App::Scripts):
|
case int(App::Scripts):
|
||||||
|
|
||||||
case int(App::Snapshot):
|
case int(App::Snapshot):
|
||||||
case int(App::SystemMonitor):
|
case int(App::SystemMonitor):
|
||||||
case int(App::Timeline):
|
case int(App::Timeline):
|
||||||
case int(App::SymbolEditor):
|
case int(App::SymbolEditor):
|
||||||
case int(App::ScriptEditorEssentialsView):
|
case int(App::ScriptEditorEssentialsView):
|
||||||
case int(App::BaseDownloader):
|
case int(App::BaseDownloader):
|
||||||
case int(App::OnlineHelp):
|
case int(App::OnlineHelp):
|
||||||
case int(App::ThpSituationReplay):
|
case int(App::ThpSituationReplay):
|
||||||
case int(App::SituationTablet):
|
case int(App::SituationTablet):
|
||||||
case int(App::SilhouetteEditor):
|
case int(App::SilhouetteEditor):
|
||||||
case int(App::Shootback):
|
case int(App::Shootback):
|
||||||
case int(App::SAAs):
|
case int(App::SAAs):
|
||||||
return static_cast<App>(i);
|
return static_cast<App>(i);
|
||||||
}
|
}
|
||||||
Q_ASSERT_X(false, "LtsAppDescriptor::appFromInteger", qPrintable(QStringLiteral("Unknown app id: %1").arg(i)));
|
Q_ASSERT_X(false, "LtsAppDescriptor::appFromInteger", qPrintable(QStringLiteral("Unknown app id: %1").arg(i)));
|
||||||
return App::Login;
|
return App::Login;
|
||||||
}
|
}
|
||||||
|
|
||||||
AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray& jsonDocument, QStringList& lastErrors,
|
AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray &jsonDocument,
|
||||||
const QStringList& ignoredPlugins,
|
QStringList &lastErrors,
|
||||||
QString& loginPluginIid)
|
const QStringList &ignoredPlugins,
|
||||||
{
|
QString &loginPluginIid)
|
||||||
|
{
|
||||||
|
|
||||||
AppDescriptionVector appDescriptions;
|
AppDescriptionVector appDescriptions;
|
||||||
|
|
||||||
@@ -109,31 +113,28 @@ AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray&
|
|||||||
if (parseError.error != QJsonParseError::NoError)
|
if (parseError.error != QJsonParseError::NoError)
|
||||||
{
|
{
|
||||||
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int column = 0;
|
int column = 0;
|
||||||
QChar x = QLatin1Char('\n');
|
QChar x = QLatin1Char('\n');
|
||||||
|
|
||||||
for (int i = 0; i < jsonDocument.size(); i++)
|
for (int i = 0; i < jsonDocument.size(); i++)
|
||||||
|
{
|
||||||
|
if (i == parseError.offset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (QChar::fromLatin1(jsonDocument[i]) == x)
|
||||||
{
|
{
|
||||||
if (i == parseError.offset)
|
row++;
|
||||||
break;
|
column = 0;
|
||||||
|
|
||||||
if (QChar::fromLatin1(jsonDocument[i]) == x)
|
|
||||||
{
|
|
||||||
row++;
|
|
||||||
column = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
column++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
column++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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())
|
return appDescriptions;
|
||||||
.arg(row + 1)
|
|
||||||
.arg(column + 1));
|
|
||||||
return appDescriptions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QJsonObject root(appsDoc.object());
|
const QJsonObject root(appsDoc.object());
|
||||||
@@ -143,64 +144,57 @@ AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray&
|
|||||||
const QJsonArray appArray(root[QStringLiteral("Apps")].toArray());
|
const QJsonArray appArray(root[QStringLiteral("Apps")].toArray());
|
||||||
if (appArray.isEmpty())
|
if (appArray.isEmpty())
|
||||||
{
|
{
|
||||||
lastErrors.append(QCoreApplication::tr("Invalid json: Could not find 'Apps' array"));
|
lastErrors.append(QCoreApplication::tr("Invalid json: Could not find 'Apps' array"));
|
||||||
return appDescriptions;
|
return appDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& appElem : appArray)
|
for (const auto &appElem : appArray)
|
||||||
{
|
{
|
||||||
AppDescription appDesc;
|
AppDescription appDesc;
|
||||||
const QJsonObject appObject = appElem.toObject();
|
const QJsonObject appObject = appElem.toObject();
|
||||||
|
|
||||||
appDesc.id = appFromInteger(appObject.value(QStringLiteral("Id")).toInt(-1));
|
appDesc.id = appFromInteger(appObject.value(QStringLiteral("Id")).toInt(-1));
|
||||||
if (appDesc.id == App::Login)
|
if (appDesc.id == App::Login)
|
||||||
|
{
|
||||||
|
lastErrors.append(QCoreApplication::tr("App '%1': no App Id or invalid App Id given").arg(appDesc.appName));
|
||||||
|
return appDescriptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
appDesc.appName = appObject.value(QStringLiteral("AppName")).toString();
|
||||||
|
|
||||||
|
const QJsonValue valueActive = appObject.value(QStringLiteral("Active"));
|
||||||
|
if (!valueActive.isUndefined())
|
||||||
|
{
|
||||||
|
if (valueActive.type() != QJsonValue::Type::Bool)
|
||||||
{
|
{
|
||||||
lastErrors.append(QCoreApplication::tr("App '%1': no App Id or invalid App Id given").arg(appDesc.appName));
|
lastErrors.append(QCoreApplication::tr("App '%1': value App.Active is not a bool (%2)").arg(appDesc.appName).arg((int)valueActive.type()));
|
||||||
return appDescriptions;
|
return appDescriptions;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
appDesc.active = valueActive.toBool(false);
|
||||||
|
|
||||||
appDesc.appName = appObject.value(QStringLiteral("AppName")).toString();
|
const QJsonValue valueVisible = appObject.value(QStringLiteral("Visible"));
|
||||||
|
if (!valueVisible.isUndefined() && valueVisible.type() != QJsonValue::Type::Bool)
|
||||||
|
{
|
||||||
|
lastErrors.append(QCoreApplication::tr("App '%1': value App.Visible is not a bool (%2)").arg(appDesc.appName).arg((int)valueVisible.type()));
|
||||||
|
return appDescriptions;
|
||||||
|
}
|
||||||
|
appDesc.visible = valueVisible.toBool(true);
|
||||||
|
|
||||||
const QJsonValue valueActive = appObject.value(QStringLiteral("Active"));
|
const QJsonArray array(appObject.value(QStringLiteral("ACLs")).toArray());
|
||||||
if (!valueActive.isUndefined())
|
for (const QJsonValue &value : array)
|
||||||
{
|
appDesc.requiredAcls.append(value.toInt());
|
||||||
if (valueActive.type() != QJsonValue::Type::Bool)
|
|
||||||
{
|
|
||||||
lastErrors.append(QCoreApplication::tr("App '%1': value App.Active is not a bool (%2)")
|
|
||||||
.arg(appDesc.appName)
|
|
||||||
.arg((int)valueActive.type()));
|
|
||||||
return appDescriptions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
appDesc.active = valueActive.toBool(false);
|
|
||||||
|
|
||||||
const QJsonValue valueVisible = appObject.value(QStringLiteral("Visible"));
|
const QJsonObject optionsObject(appObject.value(QStringLiteral("Options")).toObject());
|
||||||
if (!valueVisible.isUndefined() && valueVisible.type() != QJsonValue::Type::Bool)
|
|
||||||
{
|
|
||||||
lastErrors.append(QCoreApplication::tr("App '%1': value App.Visible is not a bool (%2)")
|
|
||||||
.arg(appDesc.appName)
|
|
||||||
.arg((int)valueVisible.type()));
|
|
||||||
return appDescriptions;
|
|
||||||
}
|
|
||||||
appDesc.visible = valueVisible.toBool(true);
|
|
||||||
|
|
||||||
const QJsonArray array(appObject.value(QStringLiteral("ACLs")).toArray());
|
addOptionsToPlugin(appDesc, QStringLiteral("Payloads"), ignoredPlugins, optionsObject, PluginInfo::Flag::PAYLOAD, lastErrors, false);
|
||||||
for (const QJsonValue& value : array)
|
addOptionsToPlugin(appDesc, QStringLiteral("Actions"), ignoredPlugins, optionsObject, PluginInfo::Flag::ACTIONS, lastErrors, true);
|
||||||
appDesc.requiredAcls.append(value.toInt());
|
addOptionsToPlugin(appDesc, QStringLiteral("Main"), ignoredPlugins, optionsObject, PluginInfo::Flag::MAIN, lastErrors, false);
|
||||||
|
|
||||||
const QJsonObject optionsObject(appObject.value(QStringLiteral("Options")).toObject());
|
appDescriptions.append(appDesc);
|
||||||
|
|
||||||
addOptionsToPlugin(appDesc, QStringLiteral("Payloads"), ignoredPlugins, optionsObject,
|
|
||||||
PluginInfo::Flag::PAYLOAD, lastErrors, false);
|
|
||||||
addOptionsToPlugin(appDesc, QStringLiteral("Actions"), ignoredPlugins, optionsObject, PluginInfo::Flag::ACTIONS,
|
|
||||||
lastErrors, true);
|
|
||||||
addOptionsToPlugin(appDesc, QStringLiteral("Main"), ignoredPlugins, optionsObject, PluginInfo::Flag::MAIN,
|
|
||||||
lastErrors, false);
|
|
||||||
|
|
||||||
appDescriptions.append(appDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return appDescriptions;
|
return appDescriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsAppDescriptor
|
} // namespace LtsAppDescriptor
|
||||||
@@ -14,91 +14,93 @@
|
|||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#ifndef LTSAPPDESCRIPTOR_EXPORT
|
#ifndef LTSAPPDESCRIPTOR_EXPORT
|
||||||
# ifdef BUILD_STATIC_LIBRARIES
|
#ifdef BUILD_STATIC_LIBRARIES
|
||||||
# define LTSAPPDESCRIPTOR_EXPORT
|
#define LTSAPPDESCRIPTOR_EXPORT
|
||||||
# else
|
#else
|
||||||
# if defined(MAKE_LTSAPPDESCRIPTOR_LIB)
|
#if defined(MAKE_LTSAPPDESCRIPTOR_LIB)
|
||||||
# define LTSAPPDESCRIPTOR_EXPORT Q_DECL_EXPORT
|
#define LTSAPPDESCRIPTOR_EXPORT Q_DECL_EXPORT
|
||||||
# else
|
#else
|
||||||
# define LTSAPPDESCRIPTOR_EXPORT Q_DECL_IMPORT
|
#define LTSAPPDESCRIPTOR_EXPORT Q_DECL_IMPORT
|
||||||
# endif
|
#endif
|
||||||
# endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace LtsAppDescriptor
|
namespace LtsAppDescriptor
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class App
|
enum class App
|
||||||
{
|
|
||||||
Login = -1,
|
|
||||||
Situation = 0,
|
|
||||||
ResourceManager = 1,
|
|
||||||
PlanEditor = 2,
|
|
||||||
BuildingViewer = 3,
|
|
||||||
OC = 4,
|
|
||||||
OrgChart = 5,
|
|
||||||
Scripts = 6,
|
|
||||||
// merged into Scripts (aka. ScriptEditor) ScriptPlayer = 7,
|
|
||||||
Snapshot = 8,
|
|
||||||
SystemMonitor = 9,
|
|
||||||
Timeline = 10,
|
|
||||||
SymbolEditor = 11,
|
|
||||||
ScriptEditorEssentialsView = 12,
|
|
||||||
BaseDownloader = 13,
|
|
||||||
OnlineHelp = 14,
|
|
||||||
ThpSituationReplay = 15,
|
|
||||||
SituationTablet = 17,
|
|
||||||
SilhouetteEditor = 18, // for L400P2
|
|
||||||
Shootback = 19, // for L400P2
|
|
||||||
SAAs = 20, //Schnittstelle Adapter Adler
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PluginInfo
|
|
||||||
{
|
|
||||||
enum class PluginType
|
|
||||||
{
|
{
|
||||||
UNKNOWN,
|
Login = -1,
|
||||||
DATA,
|
Situation = 0,
|
||||||
GUI,
|
ResourceManager = 1,
|
||||||
GUI_ELEMENT,
|
PlanEditor = 2,
|
||||||
|
BuildingViewer = 3,
|
||||||
|
OC = 4,
|
||||||
|
OrgChart = 5,
|
||||||
|
Scripts = 6,
|
||||||
|
// merged into Scripts (aka. ScriptEditor) ScriptPlayer = 7,
|
||||||
|
Snapshot = 8,
|
||||||
|
SystemMonitor = 9,
|
||||||
|
Timeline = 10,
|
||||||
|
SymbolEditor = 11,
|
||||||
|
ScriptEditorEssentialsView = 12,
|
||||||
|
BaseDownloader = 13,
|
||||||
|
OnlineHelp = 14,
|
||||||
|
ThpSituationReplay = 15,
|
||||||
|
SituationTablet = 17,
|
||||||
|
SilhouetteEditor = 18, // for L400P2
|
||||||
|
Shootback = 19, // for L400P2
|
||||||
|
SAAs = 20, //Schnittstelle Adapter Adler
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Flag
|
struct PluginInfo
|
||||||
{
|
{
|
||||||
UNKNOWN = 1 << 0,
|
enum class PluginType
|
||||||
ACTIONS = 1 << 1,
|
{
|
||||||
MAIN = 1 << 2,
|
UNKNOWN,
|
||||||
PAYLOAD = 1 << 3,
|
DATA,
|
||||||
OPTION = 1 << 4,
|
GUI,
|
||||||
|
GUI_ELEMENT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class Flag
|
||||||
|
{
|
||||||
|
UNKNOWN = 1 << 0,
|
||||||
|
ACTIONS = 1 << 1,
|
||||||
|
MAIN = 1 << 2,
|
||||||
|
PAYLOAD = 1 << 3,
|
||||||
|
OPTION = 1 << 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
PluginType type = PluginType::UNKNOWN;
|
||||||
|
QString iid;
|
||||||
|
QFlags<Flag> flags;
|
||||||
|
QStringList options;
|
||||||
};
|
};
|
||||||
|
|
||||||
PluginType type = PluginType::UNKNOWN;
|
struct AppDescription
|
||||||
QString iid;
|
{
|
||||||
QFlags<Flag> flags;
|
App id = App::Login;
|
||||||
QStringList options;
|
bool active = false;
|
||||||
};
|
bool visible = true;
|
||||||
|
QString appName;
|
||||||
|
QVector<int> requiredAcls;
|
||||||
|
QVector<PluginInfo> pluginInfos;
|
||||||
|
|
||||||
struct AppDescription
|
bool isValid() const { return !appName.isEmpty(); }
|
||||||
{
|
};
|
||||||
App id = App::Login;
|
|
||||||
bool active = false;
|
|
||||||
bool visible = true;
|
|
||||||
QString appName;
|
|
||||||
QVector<int> requiredAcls;
|
|
||||||
QVector<PluginInfo> pluginInfos;
|
|
||||||
|
|
||||||
bool isValid() const { return !appName.isEmpty(); }
|
typedef QVector<AppDescription> AppDescriptionVector;
|
||||||
};
|
|
||||||
|
|
||||||
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
|
||||||
+377
-381
@@ -13,524 +13,520 @@
|
|||||||
#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();
|
||||||
m_appIndex = QModelIndex();
|
m_appIndex = QModelIndex();
|
||||||
m_pluginIndex = QModelIndex();
|
m_pluginIndex = QModelIndex();
|
||||||
m_fileName = QString();
|
m_fileName = QString();
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
|
|
||||||
connect(m_ui->lvApps, &QListView::clicked, this, &LtsAppDescriptorEditor::onAppsClicked);
|
connect(m_ui->lvApps, &QListView::clicked, this, &LtsAppDescriptorEditor::onAppsClicked);
|
||||||
connect(m_ui->lvPlugins, &QListView::clicked, this, &LtsAppDescriptorEditor::onPluginsClicked);
|
connect(m_ui->lvPlugins, &QListView::clicked, this, &LtsAppDescriptorEditor::onPluginsClicked);
|
||||||
connect(m_ui->lePluginType, &QLineEdit::editingFinished, this, &LtsAppDescriptorEditor::pluginTypeChanged);
|
connect(m_ui->lePluginType, &QLineEdit::editingFinished, this, &LtsAppDescriptorEditor::pluginTypeChanged);
|
||||||
connect(m_ui->pbAddApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onAppAddClicked);
|
connect(m_ui->pbAddApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onAppAddClicked);
|
||||||
connect(m_ui->pbAddPlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onPluginAddClicked);
|
connect(m_ui->pbAddPlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onPluginAddClicked);
|
||||||
connect(m_ui->pbDeleteApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onAppDeleteClicked);
|
connect(m_ui->pbDeleteApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onAppDeleteClicked);
|
||||||
connect(m_ui->pbDeletePlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onPluginDeletedClicked);
|
connect(m_ui->pbDeletePlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onPluginDeletedClicked);
|
||||||
connect(m_ui->pbUpdate, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onUpdateClicked);
|
connect(m_ui->pbUpdate, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onUpdateClicked);
|
||||||
connect(m_ui->pbNewPlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onNewpluginClicked);
|
connect(m_ui->pbNewPlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onNewpluginClicked);
|
||||||
connect(m_ui->pbNewApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onNewAppClicked);
|
connect(m_ui->pbNewApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onNewAppClicked);
|
||||||
connect(m_ui->lePluginName, &QLineEdit::textChanged, this, &LtsAppDescriptorEditor::enableNewPlugin);
|
connect(m_ui->lePluginName, &QLineEdit::textChanged, this, &LtsAppDescriptorEditor::enableNewPlugin);
|
||||||
connect(m_ui->lePluginType, &QLineEdit::textChanged, this, &LtsAppDescriptorEditor::enableNewPlugin);
|
connect(m_ui->lePluginType, &QLineEdit::textChanged, this, &LtsAppDescriptorEditor::enableNewPlugin);
|
||||||
|
|
||||||
m_ui->gbPlugins->setEnabled(false);
|
m_ui->gbPlugins->setEnabled(false);
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
m_ui->pbDeletePlugin->setEnabled(false);
|
||||||
m_ui->pbDeleteApp->setEnabled(false);
|
m_ui->pbDeleteApp->setEnabled(false);
|
||||||
m_ui->pbAddPlugin->setEnabled(false);
|
m_ui->pbAddPlugin->setEnabled(false);
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
m_ui->pbUpdate->setEnabled(false);
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
m_ui->pbNewPlugin->setEnabled(false);
|
||||||
m_ui->pbNewApp->setEnabled(false);
|
m_ui->pbNewApp->setEnabled(false);
|
||||||
QTimer::singleShot(0, this, &LtsAppDescriptorEditor::getAppDescriptionVector);
|
QTimer::singleShot(0, this, &LtsAppDescriptorEditor::getAppDescriptionVector);
|
||||||
}
|
}
|
||||||
|
|
||||||
LtsAppDescriptorEditor::~LtsAppDescriptorEditor()
|
LtsAppDescriptorEditor::~LtsAppDescriptorEditor()
|
||||||
{
|
{
|
||||||
checkSave();
|
checkSave();
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
QFile file;
|
QFile file;
|
||||||
file.setFileName(m_fileName);
|
file.setFileName(m_fileName);
|
||||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||||
QString val(QString::fromUtf8(file.readAll()));
|
QString val(QString::fromUtf8(file.readAll()));
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
QStringList errors;
|
QStringList errors;
|
||||||
m_vector = LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(val.toUtf8(), errors);
|
m_vector = LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(val.toUtf8(), errors);
|
||||||
|
|
||||||
updateAppModel();
|
updateAppModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onAppsClicked(const QModelIndex& index)
|
void LtsAppDescriptorEditor::onAppsClicked(const QModelIndex &index)
|
||||||
{
|
{
|
||||||
m_ui->gbPlugins->setEnabled(true);
|
m_ui->gbPlugins->setEnabled(true);
|
||||||
m_ui->pbDeleteApp->setEnabled(true);
|
m_ui->pbDeleteApp->setEnabled(true);
|
||||||
m_ui->pbAddPlugin->setEnabled(true);
|
m_ui->pbAddPlugin->setEnabled(true);
|
||||||
m_ui->pbNewApp->setEnabled(true);
|
m_ui->pbNewApp->setEnabled(true);
|
||||||
m_appIndex = index;
|
m_appIndex = index;
|
||||||
|
|
||||||
QStringList pluginList;
|
QStringList pluginList;
|
||||||
Q_FOREACH (const LtsAppDescriptor::PluginInfo& reqPlugin, m_vector.at(m_appIndex.row()).requiredPlugins)
|
Q_FOREACH (const LtsAppDescriptor::PluginInfo &reqPlugin, m_vector.at(m_appIndex.row()).requiredPlugins)
|
||||||
{
|
{
|
||||||
LtsAppDescriptor::PluginInfo::PluginType pluginType = reqPlugin.type;
|
LtsAppDescriptor::PluginInfo::PluginType pluginType = reqPlugin.type;
|
||||||
QString type;
|
|
||||||
if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::DATA)
|
|
||||||
type = QLatin1String("data");
|
|
||||||
else if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::GUI)
|
|
||||||
type = QLatin1String("gui");
|
|
||||||
else
|
|
||||||
type = QLatin1String("unknown");
|
|
||||||
|
|
||||||
if (type == QLatin1String("data"))
|
|
||||||
pluginList << QString(type + QLatin1String(": ") + reqPlugin.iid);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QString strFlags;
|
|
||||||
QFlags<LtsAppDescriptor::PluginInfo::Flag> flags = reqPlugin.flags;
|
|
||||||
|
|
||||||
bool actionsFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::ACTIONS);
|
|
||||||
if (actionsFlag)
|
|
||||||
strFlags.append(QLatin1String("actions "));
|
|
||||||
bool mainFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN);
|
|
||||||
if (mainFlag)
|
|
||||||
strFlags.append(QLatin1String("main "));
|
|
||||||
bool payloadFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::PAYLOAD);
|
|
||||||
if (payloadFlag)
|
|
||||||
strFlags.append(QLatin1String("payload "));
|
|
||||||
bool optionalFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::OPTION);
|
|
||||||
if (optionalFlag)
|
|
||||||
strFlags.append(QLatin1String("optional "));
|
|
||||||
|
|
||||||
pluginList << QString(type + QLatin1String(": ") + reqPlugin.iid + QLatin1String(" [ ") + strFlags +
|
|
||||||
QLatin1String("]"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updatePluginModel(pluginList);
|
|
||||||
|
|
||||||
m_ui->chbAppActive->setChecked(m_vector.at(m_appIndex.row()).active);
|
|
||||||
m_ui->leAppName->setText(m_vector.at(m_appIndex.row()).appName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onPluginsClicked(const QModelIndex& index)
|
|
||||||
{
|
|
||||||
m_pluginIndex = index;
|
|
||||||
m_ui->pbDeletePlugin->setEnabled(true);
|
|
||||||
m_ui->pbUpdate->setEnabled(true);
|
|
||||||
m_ui->pbNewPlugin->setEnabled(true);
|
|
||||||
|
|
||||||
const LtsAppDescriptor::PluginInfo plugin = m_vector.at(m_appIndex.row()).requiredPlugins.at(m_pluginIndex.row());
|
|
||||||
QString pluginName = plugin.iid;
|
|
||||||
m_ui->lePluginName->setText(pluginName);
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo::PluginType pluginType = plugin.type;
|
|
||||||
QString type;
|
QString type;
|
||||||
if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::DATA)
|
if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::DATA)
|
||||||
type = QLatin1String("data");
|
type = QLatin1String("data");
|
||||||
else if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::GUI)
|
else if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::GUI)
|
||||||
type = QLatin1String("gui");
|
type = QLatin1String("gui");
|
||||||
else
|
else
|
||||||
type = QLatin1String("unknown");
|
type = QLatin1String("unknown");
|
||||||
m_ui->lePluginType->setText(type);
|
|
||||||
|
|
||||||
if (type == QLatin1String("gui"))
|
if (type == QLatin1String("data"))
|
||||||
{
|
pluginList << QString(type + QLatin1String(": ") + reqPlugin.iid);
|
||||||
m_ui->chbActions->setEnabled(true);
|
|
||||||
m_ui->chbMain->setEnabled(true);
|
|
||||||
m_ui->chbPayload->setEnabled(true);
|
|
||||||
|
|
||||||
QFlags<LtsAppDescriptor::PluginInfo::Flag> flags = plugin.flags;
|
|
||||||
bool actionsFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::ACTIONS);
|
|
||||||
m_ui->chbActions->setChecked(actionsFlag);
|
|
||||||
bool mainFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN);
|
|
||||||
m_ui->chbMain->setChecked(mainFlag);
|
|
||||||
bool payloadFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::PAYLOAD);
|
|
||||||
m_ui->chbPayload->setChecked(payloadFlag);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_ui->chbActions->setChecked(false);
|
QString strFlags;
|
||||||
m_ui->chbActions->setEnabled(false);
|
QFlags<LtsAppDescriptor::PluginInfo::Flag> flags = reqPlugin.flags;
|
||||||
m_ui->chbMain->setChecked(false);
|
|
||||||
m_ui->chbMain->setEnabled(false);
|
bool actionsFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::ACTIONS);
|
||||||
m_ui->chbPayload->setChecked(false);
|
if (actionsFlag)
|
||||||
m_ui->chbPayload->setEnabled(false);
|
strFlags.append(QLatin1String("actions "));
|
||||||
|
bool mainFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN);
|
||||||
|
if (mainFlag)
|
||||||
|
strFlags.append(QLatin1String("main "));
|
||||||
|
bool payloadFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::PAYLOAD);
|
||||||
|
if (payloadFlag)
|
||||||
|
strFlags.append(QLatin1String("payload "));
|
||||||
|
bool optionalFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::OPTION);
|
||||||
|
if (optionalFlag)
|
||||||
|
strFlags.append(QLatin1String("optional "));
|
||||||
|
|
||||||
|
pluginList << QString(type + QLatin1String(": ") + reqPlugin.iid + QLatin1String(" [ ") + strFlags + QLatin1String("]"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
updatePluginModel(pluginList);
|
||||||
|
|
||||||
|
m_ui->chbAppActive->setChecked(m_vector.at(m_appIndex.row()).active);
|
||||||
|
m_ui->leAppName->setText(m_vector.at(m_appIndex.row()).appName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LtsAppDescriptorEditor::onPluginsClicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
m_pluginIndex = index;
|
||||||
|
m_ui->pbDeletePlugin->setEnabled(true);
|
||||||
|
m_ui->pbUpdate->setEnabled(true);
|
||||||
|
m_ui->pbNewPlugin->setEnabled(true);
|
||||||
|
|
||||||
|
const LtsAppDescriptor::PluginInfo plugin = m_vector.at(m_appIndex.row()).requiredPlugins.at(m_pluginIndex.row());
|
||||||
|
QString pluginName = plugin.iid;
|
||||||
|
m_ui->lePluginName->setText(pluginName);
|
||||||
|
|
||||||
|
LtsAppDescriptor::PluginInfo::PluginType pluginType = plugin.type;
|
||||||
|
QString type;
|
||||||
|
if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::DATA)
|
||||||
|
type = QLatin1String("data");
|
||||||
|
else if (pluginType == LtsAppDescriptor::PluginInfo::PluginType::GUI)
|
||||||
|
type = QLatin1String("gui");
|
||||||
|
else
|
||||||
|
type = QLatin1String("unknown");
|
||||||
|
m_ui->lePluginType->setText(type);
|
||||||
|
|
||||||
|
if (type == QLatin1String("gui"))
|
||||||
|
{
|
||||||
|
m_ui->chbActions->setEnabled(true);
|
||||||
|
m_ui->chbMain->setEnabled(true);
|
||||||
|
m_ui->chbPayload->setEnabled(true);
|
||||||
|
|
||||||
|
QFlags<LtsAppDescriptor::PluginInfo::Flag> flags = plugin.flags;
|
||||||
|
bool actionsFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::ACTIONS);
|
||||||
|
m_ui->chbActions->setChecked(actionsFlag);
|
||||||
|
bool mainFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN);
|
||||||
|
m_ui->chbMain->setChecked(mainFlag);
|
||||||
|
bool payloadFlag = flags.testFlag(LtsAppDescriptor::PluginInfo::Flag::PAYLOAD);
|
||||||
|
m_ui->chbPayload->setChecked(payloadFlag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ui->chbActions->setChecked(false);
|
||||||
|
m_ui->chbActions->setEnabled(false);
|
||||||
|
m_ui->chbMain->setChecked(false);
|
||||||
|
m_ui->chbMain->setEnabled(false);
|
||||||
|
m_ui->chbPayload->setChecked(false);
|
||||||
|
m_ui->chbPayload->setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::pluginTypeChanged()
|
void LtsAppDescriptorEditor::pluginTypeChanged()
|
||||||
{
|
{
|
||||||
if (m_ui->lePluginType->text().isEmpty())
|
if (m_ui->lePluginType->text().isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
||||||
{
|
{
|
||||||
m_ui->chbActions->setEnabled(true);
|
m_ui->chbActions->setEnabled(true);
|
||||||
m_ui->chbMain->setEnabled(true);
|
m_ui->chbMain->setEnabled(true);
|
||||||
m_ui->chbPayload->setEnabled(true);
|
m_ui->chbPayload->setEnabled(true);
|
||||||
}
|
}
|
||||||
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
||||||
{
|
{
|
||||||
m_ui->chbActions->setChecked(false);
|
m_ui->chbActions->setChecked(false);
|
||||||
m_ui->chbActions->setEnabled(false);
|
m_ui->chbActions->setEnabled(false);
|
||||||
m_ui->chbMain->setChecked(false);
|
m_ui->chbMain->setChecked(false);
|
||||||
m_ui->chbMain->setEnabled(false);
|
m_ui->chbMain->setEnabled(false);
|
||||||
m_ui->chbPayload->setChecked(false);
|
m_ui->chbPayload->setChecked(false);
|
||||||
m_ui->chbPayload->setEnabled(false);
|
m_ui->chbPayload->setEnabled(false);
|
||||||
}
|
}
|
||||||
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());
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onAppAddClicked()
|
void LtsAppDescriptorEditor::onAppAddClicked()
|
||||||
{
|
{
|
||||||
m_changed = true;
|
m_changed = true;
|
||||||
|
|
||||||
if (m_ui->leAppName->text().isEmpty())
|
if (m_ui->leAppName->text().isEmpty())
|
||||||
{
|
{
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The App needs to have a name."));
|
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The App needs to have a name."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList appList;
|
QStringList appList;
|
||||||
Q_FOREACH (const LtsAppDescriptor::AppDescription& appDesc, m_vector)
|
Q_FOREACH (const LtsAppDescriptor::AppDescription &appDesc, m_vector)
|
||||||
{
|
{
|
||||||
appList << appDesc.appName;
|
appList << appDesc.appName;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescription newApp;
|
LtsAppDescriptor::AppDescription newApp;
|
||||||
newApp.appName = m_ui->leAppName->text();
|
newApp.appName = m_ui->leAppName->text();
|
||||||
newApp.active = m_ui->chbAppActive->isChecked();
|
newApp.active = m_ui->chbAppActive->isChecked();
|
||||||
m_vector.append(newApp);
|
m_vector.append(newApp);
|
||||||
|
|
||||||
updateAppModel();
|
updateAppModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onPluginAddClicked()
|
void LtsAppDescriptorEditor::onPluginAddClicked()
|
||||||
{
|
{
|
||||||
m_changed = true;
|
m_changed = true;
|
||||||
|
|
||||||
if (m_ui->lePluginType->text().isEmpty())
|
if (m_ui->lePluginType->text().isEmpty())
|
||||||
{
|
{
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to contain a type."));
|
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to contain a type."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_ui->lePluginName->text().isEmpty())
|
if (m_ui->lePluginName->text().isEmpty())
|
||||||
{
|
{
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to have a name."));
|
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to have a name."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList pluginList;
|
QStringList pluginList;
|
||||||
Q_FOREACH (const LtsAppDescriptor::PluginInfo& pluginDesc, m_vector.at(m_appIndex.row()).requiredPlugins)
|
Q_FOREACH (const LtsAppDescriptor::PluginInfo &pluginDesc, m_vector.at(m_appIndex.row()).requiredPlugins)
|
||||||
{
|
{
|
||||||
pluginList << pluginDesc.iid;
|
pluginList << pluginDesc.iid;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo newPlugin;
|
LtsAppDescriptor::PluginInfo newPlugin;
|
||||||
|
|
||||||
newPlugin.iid = m_ui->lePluginName->text();
|
newPlugin.iid = m_ui->lePluginName->text();
|
||||||
|
|
||||||
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
||||||
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::GUI;
|
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::GUI;
|
||||||
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
||||||
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
||||||
else
|
else
|
||||||
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::UNKNOWN;
|
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::UNKNOWN;
|
||||||
|
|
||||||
if (m_ui->chbActions->isChecked())
|
if (m_ui->chbActions->isChecked())
|
||||||
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::ACTIONS;
|
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::ACTIONS;
|
||||||
if (m_ui->chbMain->isChecked())
|
if (m_ui->chbMain->isChecked())
|
||||||
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::MAIN;
|
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::MAIN;
|
||||||
if (m_ui->chbPayload->isChecked())
|
if (m_ui->chbPayload->isChecked())
|
||||||
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
||||||
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins.append(newPlugin);
|
m_vector[m_appIndex.row()].requiredPlugins.append(newPlugin);
|
||||||
|
|
||||||
onAppsClicked(m_appIndex);
|
onAppsClicked(m_appIndex);
|
||||||
onNewpluginClicked();
|
onNewpluginClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onAppDeleteClicked()
|
void LtsAppDescriptorEditor::onAppDeleteClicked()
|
||||||
{
|
{
|
||||||
m_changed = true;
|
m_changed = true;
|
||||||
|
|
||||||
if (!m_appIndex.isValid())
|
if (!m_appIndex.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
m_vector.remove(m_appIndex.row());
|
m_vector.remove(m_appIndex.row());
|
||||||
|
|
||||||
updateAppModel();
|
updateAppModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onPluginDeletedClicked()
|
void LtsAppDescriptorEditor::onPluginDeletedClicked()
|
||||||
{
|
{
|
||||||
m_changed = true;
|
m_changed = true;
|
||||||
|
|
||||||
if (!m_pluginIndex.isValid())
|
if (!m_pluginIndex.isValid())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins.remove(m_pluginIndex.row());
|
m_vector[m_appIndex.row()].requiredPlugins.remove(m_pluginIndex.row());
|
||||||
m_pluginIndex = QModelIndex();
|
m_pluginIndex = QModelIndex();
|
||||||
m_ui->lePluginName->setText(QString());
|
m_ui->lePluginName->setText(QString());
|
||||||
m_ui->lePluginType->setText(QString());
|
m_ui->lePluginType->setText(QString());
|
||||||
m_ui->chbActions->setChecked(false);
|
m_ui->chbActions->setChecked(false);
|
||||||
m_ui->chbMain->setChecked(false);
|
m_ui->chbMain->setChecked(false);
|
||||||
m_ui->chbPayload->setChecked(false);
|
m_ui->chbPayload->setChecked(false);
|
||||||
|
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
m_ui->pbDeletePlugin->setEnabled(false);
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
m_ui->pbUpdate->setEnabled(false);
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
m_ui->pbNewPlugin->setEnabled(false);
|
||||||
|
|
||||||
onAppsClicked(m_appIndex);
|
onAppsClicked(m_appIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onUpdateClicked()
|
void LtsAppDescriptorEditor::onUpdateClicked()
|
||||||
{
|
{
|
||||||
m_changed = true;
|
m_changed = true;
|
||||||
|
|
||||||
if (m_ui->lePluginType->text().isEmpty())
|
if (m_ui->lePluginType->text().isEmpty())
|
||||||
{
|
{
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to contain a type."));
|
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to contain a type."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_ui->lePluginName->text().isEmpty())
|
if (m_ui->lePluginName->text().isEmpty())
|
||||||
{
|
{
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to have a name."));
|
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to have a name."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type =
|
else
|
||||||
LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = LtsAppDescriptor::PluginInfo::PluginType::UNKNOWN;
|
||||||
else
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type =
|
|
||||||
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 |= LtsAppDescriptor::PluginInfo::Flag::MAIN;
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |=
|
if (m_ui->chbPayload->isChecked())
|
||||||
LtsAppDescriptor::PluginInfo::Flag::MAIN;
|
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
||||||
if (m_ui->chbPayload->isChecked())
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |=
|
|
||||||
LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
|
||||||
|
|
||||||
onAppsClicked(m_appIndex);
|
onAppsClicked(m_appIndex);
|
||||||
onNewpluginClicked();
|
onNewpluginClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onNewpluginClicked()
|
void LtsAppDescriptorEditor::onNewpluginClicked()
|
||||||
{
|
{
|
||||||
m_ui->lePluginName->setText(QString());
|
m_ui->lePluginName->setText(QString());
|
||||||
m_ui->lePluginType->setText(QString());
|
m_ui->lePluginType->setText(QString());
|
||||||
m_ui->chbActions->setEnabled(true);
|
m_ui->chbActions->setEnabled(true);
|
||||||
m_ui->chbMain->setEnabled(true);
|
m_ui->chbMain->setEnabled(true);
|
||||||
m_ui->chbPayload->setEnabled(true);
|
m_ui->chbPayload->setEnabled(true);
|
||||||
m_ui->chbActions->setChecked(false);
|
m_ui->chbActions->setChecked(false);
|
||||||
m_ui->chbMain->setChecked(false);
|
m_ui->chbMain->setChecked(false);
|
||||||
m_ui->chbPayload->setChecked(false);
|
m_ui->chbPayload->setChecked(false);
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
m_ui->pbUpdate->setEnabled(false);
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
m_ui->pbNewPlugin->setEnabled(false);
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
m_ui->pbDeletePlugin->setEnabled(false);
|
||||||
|
|
||||||
if (m_pluginIndex.isValid())
|
if (m_pluginIndex.isValid())
|
||||||
m_ui->lvPlugins->selectionModel()->select(m_pluginIndex, QItemSelectionModel::Deselect);
|
m_ui->lvPlugins->selectionModel()->select(m_pluginIndex, QItemSelectionModel::Deselect);
|
||||||
m_pluginIndex = QModelIndex();
|
m_pluginIndex = QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onNewAppClicked()
|
void LtsAppDescriptorEditor::onNewAppClicked()
|
||||||
{
|
{
|
||||||
updatePluginModel(QStringList());
|
updatePluginModel(QStringList());
|
||||||
|
|
||||||
m_ui->gbPlugins->setEnabled(false);
|
m_ui->gbPlugins->setEnabled(false);
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
m_ui->pbDeletePlugin->setEnabled(false);
|
||||||
m_ui->pbDeleteApp->setEnabled(false);
|
m_ui->pbDeleteApp->setEnabled(false);
|
||||||
m_ui->pbAddPlugin->setEnabled(false);
|
m_ui->pbAddPlugin->setEnabled(false);
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
m_ui->pbUpdate->setEnabled(false);
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
m_ui->pbNewPlugin->setEnabled(false);
|
||||||
m_ui->leAppName->setText(QString());
|
m_ui->leAppName->setText(QString());
|
||||||
m_ui->chbAppActive->setChecked(false);
|
m_ui->chbAppActive->setChecked(false);
|
||||||
m_ui->lePluginName->setText(QString());
|
m_ui->lePluginName->setText(QString());
|
||||||
m_ui->lePluginType->setText(QString());
|
m_ui->lePluginType->setText(QString());
|
||||||
m_ui->chbActions->setChecked(false);
|
m_ui->chbActions->setChecked(false);
|
||||||
m_ui->chbMain->setChecked(false);
|
m_ui->chbMain->setChecked(false);
|
||||||
m_ui->chbPayload->setChecked(false);
|
m_ui->chbPayload->setChecked(false);
|
||||||
m_ui->pbNewApp->setEnabled(false);
|
m_ui->pbNewApp->setEnabled(false);
|
||||||
|
|
||||||
if (m_appIndex.isValid())
|
if (m_appIndex.isValid())
|
||||||
m_ui->lvApps->selectionModel()->select(m_appIndex, QItemSelectionModel::Deselect);
|
m_ui->lvApps->selectionModel()->select(m_appIndex, QItemSelectionModel::Deselect);
|
||||||
m_appIndex = QModelIndex();
|
m_appIndex = QModelIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::updateAppModel()
|
void LtsAppDescriptorEditor::updateAppModel()
|
||||||
{
|
{
|
||||||
onNewAppClicked();
|
onNewAppClicked();
|
||||||
QStringList appList;
|
QStringList appList;
|
||||||
Q_FOREACH (const LtsAppDescriptor::AppDescription& appDesc, m_vector)
|
Q_FOREACH (const LtsAppDescriptor::AppDescription &appDesc, m_vector)
|
||||||
{
|
{
|
||||||
appList << appDesc.appName;
|
appList << appDesc.appName;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_ui->lvApps->model())
|
if (!m_ui->lvApps->model())
|
||||||
m_ui->lvApps->setModel(new QStringListModel(this));
|
m_ui->lvApps->setModel(new QStringListModel(this));
|
||||||
QStringListModel* m = qobject_cast<QStringListModel*>(m_ui->lvApps->model());
|
QStringListModel *m = qobject_cast<QStringListModel *>(m_ui->lvApps->model());
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
m->setStringList(appList);
|
m->setStringList(appList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::updatePluginModel(const QStringList& list)
|
void LtsAppDescriptorEditor::updatePluginModel(const QStringList &list)
|
||||||
{
|
{
|
||||||
if (!m_ui->lvPlugins->model())
|
if (!m_ui->lvPlugins->model())
|
||||||
m_ui->lvPlugins->setModel(new QStringListModel(this));
|
m_ui->lvPlugins->setModel(new QStringListModel(this));
|
||||||
QStringListModel* m = qobject_cast<QStringListModel*>(m_ui->lvPlugins->model());
|
QStringListModel *m = qobject_cast<QStringListModel *>(m_ui->lvPlugins->model());
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
m->setStringList(list);
|
m->setStringList(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::checkSave()
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
QByteArray jsonByteArray;
|
QByteArray jsonByteArray;
|
||||||
jsonByteArray = LtsAppDescriptor::LtsAppDescriptor::createJson(m_vector);
|
jsonByteArray = LtsAppDescriptor::LtsAppDescriptor::createJson(m_vector);
|
||||||
|
|
||||||
QFile f(fileName);
|
QFile f(fileName);
|
||||||
f.open(QIODevice::WriteOnly);
|
f.open(QIODevice::WriteOnly);
|
||||||
f.write(jsonByteArray);
|
f.write(jsonByteArray);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
|
|
||||||
QMessageBox msgBox(QMessageBox::Information, tr("Success"), tr("Your file has been saved."));
|
QMessageBox msgBox(QMessageBox::Information, tr("Success"), tr("Your file has been saved."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onSaveClicked()
|
void LtsAppDescriptorEditor::onSaveClicked()
|
||||||
{
|
{
|
||||||
const QByteArray jsonByteArray(LtsAppDescriptor::LtsAppDescriptor::createJson(m_vector));
|
const QByteArray jsonByteArray(LtsAppDescriptor::LtsAppDescriptor::createJson(m_vector));
|
||||||
|
|
||||||
QFile f(m_fileName);
|
QFile f(m_fileName);
|
||||||
f.open(QIODevice::WriteOnly);
|
f.open(QIODevice::WriteOnly);
|
||||||
f.write(jsonByteArray);
|
f.write(jsonByteArray);
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
|
|
||||||
QMessageBox msgBox(QMessageBox::Information, tr("Success"), tr("Your file has been saved."));
|
QMessageBox msgBox(QMessageBox::Information, tr("Success"), tr("Your file has been saved."));
|
||||||
msgBox.exec();
|
msgBox.exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onOpenClicked()
|
void LtsAppDescriptorEditor::onOpenClicked()
|
||||||
{
|
{
|
||||||
checkSave();
|
checkSave();
|
||||||
getAppDescriptionVector();
|
getAppDescriptionVector();
|
||||||
m_changed = false;
|
m_changed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onNewClicked()
|
void LtsAppDescriptorEditor::onNewClicked()
|
||||||
{
|
{
|
||||||
checkSave();
|
checkSave();
|
||||||
m_ui->chbActions->setChecked(false);
|
m_ui->chbActions->setChecked(false);
|
||||||
m_ui->chbMain->setChecked(false);
|
m_ui->chbMain->setChecked(false);
|
||||||
m_ui->chbPayload->setChecked(false);
|
m_ui->chbPayload->setChecked(false);
|
||||||
m_ui->chbAppActive->setChecked(false);
|
m_ui->chbAppActive->setChecked(false);
|
||||||
m_ui->leAppName->setText(QString());
|
m_ui->leAppName->setText(QString());
|
||||||
m_ui->lePluginName->setText(QString());
|
m_ui->lePluginName->setText(QString());
|
||||||
m_ui->lePluginType->setText(QString());
|
m_ui->lePluginType->setText(QString());
|
||||||
m_ui->gbPlugins->setEnabled(false);
|
m_ui->gbPlugins->setEnabled(false);
|
||||||
|
|
||||||
m_vector = LtsAppDescriptor::AppDescriptionVector();
|
m_vector = LtsAppDescriptor::AppDescriptionVector();
|
||||||
|
|
||||||
updateAppModel();
|
updateAppModel();
|
||||||
updatePluginModel(QStringList());
|
updatePluginModel(QStringList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::enableNewPlugin()
|
void LtsAppDescriptorEditor::enableNewPlugin()
|
||||||
{
|
{
|
||||||
m_ui->pbNewPlugin->setEnabled(true);
|
m_ui->pbNewPlugin->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onQuitClicked()
|
void LtsAppDescriptorEditor::onQuitClicked()
|
||||||
{
|
{
|
||||||
QApplication::quit();
|
QApplication::quit();
|
||||||
}
|
}
|
||||||
+34
-34
@@ -21,45 +21,45 @@ class Ui_LtsAppDescriptionEditor;
|
|||||||
|
|
||||||
class LTSAPPDESCRIPTOREDITOR_EXPORT LtsAppDescriptorEditor : public QWidget
|
class LTSAPPDESCRIPTOREDITOR_EXPORT LtsAppDescriptorEditor : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LtsAppDescriptorEditor(QWidget* parent = 0);
|
explicit LtsAppDescriptorEditor(QWidget *parent = 0);
|
||||||
~LtsAppDescriptorEditor();
|
~LtsAppDescriptorEditor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui_LtsAppDescriptionEditor* m_ui;
|
Ui_LtsAppDescriptionEditor *m_ui;
|
||||||
LtsAppDescriptor::AppDescriptionVector m_vector;
|
LtsAppDescriptor::AppDescriptionVector m_vector;
|
||||||
QModelIndex m_appIndex;
|
QModelIndex m_appIndex;
|
||||||
QModelIndex m_pluginIndex;
|
QModelIndex m_pluginIndex;
|
||||||
|
|
||||||
QString m_fileName;
|
QString m_fileName;
|
||||||
|
|
||||||
bool m_changed;
|
bool m_changed;
|
||||||
|
|
||||||
void getAppDescriptionVector();
|
void getAppDescriptionVector();
|
||||||
void setupMainWindow();
|
void setupMainWindow();
|
||||||
void updateAppModel();
|
void updateAppModel();
|
||||||
void updatePluginModel(const QStringList& list);
|
void updatePluginModel(const QStringList &list);
|
||||||
void checkSave();
|
void checkSave();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAppsClicked(const QModelIndex& index);
|
void onAppsClicked(const QModelIndex &index);
|
||||||
void onPluginsClicked(const QModelIndex& index);
|
void onPluginsClicked(const QModelIndex &index);
|
||||||
void pluginTypeChanged();
|
void pluginTypeChanged();
|
||||||
void onAppAddClicked();
|
void onAppAddClicked();
|
||||||
void onPluginAddClicked();
|
void onPluginAddClicked();
|
||||||
void onAppDeleteClicked();
|
void onAppDeleteClicked();
|
||||||
void onPluginDeletedClicked();
|
void onPluginDeletedClicked();
|
||||||
void onUpdateClicked();
|
void onUpdateClicked();
|
||||||
void onNewpluginClicked();
|
void onNewpluginClicked();
|
||||||
void onNewAppClicked();
|
void onNewAppClicked();
|
||||||
void enableNewPlugin();
|
void enableNewPlugin();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onSaveClicked();
|
void onSaveClicked();
|
||||||
void onSaveAsClicked();
|
void onSaveAsClicked();
|
||||||
void onOpenClicked();
|
void onOpenClicked();
|
||||||
void onNewClicked();
|
void onNewClicked();
|
||||||
void onQuitClicked();
|
void onQuitClicked();
|
||||||
};
|
};
|
||||||
@@ -7,49 +7,49 @@
|
|||||||
#include <QtWidgets/QMainWindow>
|
#include <QtWidgets/QMainWindow>
|
||||||
#include <QtWidgets/QMenuBar>
|
#include <QtWidgets/QMenuBar>
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
|
|
||||||
QMainWindow* mainWindow = new QMainWindow();
|
QMainWindow *mainWindow = new QMainWindow();
|
||||||
QMenu* fileMenu = mainWindow->menuBar()->addMenu(QObject::tr("&File"));
|
QMenu *fileMenu = mainWindow->menuBar()->addMenu(QObject::tr("&File"));
|
||||||
|
|
||||||
QAction* openAct = new QAction(QObject::tr("&Open"), mainWindow);
|
QAction *openAct = new QAction(QObject::tr("&Open"), mainWindow);
|
||||||
openAct->setShortcuts(QKeySequence::Open);
|
openAct->setShortcuts(QKeySequence::Open);
|
||||||
openAct->setStatusTip(QObject::tr("Open an existing file"));
|
openAct->setStatusTip(QObject::tr("Open an existing file"));
|
||||||
fileMenu->addAction(openAct);
|
fileMenu->addAction(openAct);
|
||||||
|
|
||||||
QAction* newAct = new QAction(QObject::tr("&New"), mainWindow);
|
QAction *newAct = new QAction(QObject::tr("&New"), mainWindow);
|
||||||
newAct->setShortcuts(QKeySequence::New);
|
newAct->setShortcuts(QKeySequence::New);
|
||||||
newAct->setStatusTip(QObject::tr("Create a new App"));
|
newAct->setStatusTip(QObject::tr("Create a new App"));
|
||||||
fileMenu->addAction(newAct);
|
fileMenu->addAction(newAct);
|
||||||
|
|
||||||
QAction* saveAct = new QAction(QObject::tr("&Save"), mainWindow);
|
QAction *saveAct = new QAction(QObject::tr("&Save"), mainWindow);
|
||||||
saveAct->setShortcuts(QKeySequence::Save);
|
saveAct->setShortcuts(QKeySequence::Save);
|
||||||
saveAct->setStatusTip(QObject::tr("Save modified file"));
|
saveAct->setStatusTip(QObject::tr("Save modified file"));
|
||||||
fileMenu->addAction(saveAct);
|
fileMenu->addAction(saveAct);
|
||||||
|
|
||||||
QAction* saveAsAct = new QAction(QObject::tr("&SaveAs"), mainWindow);
|
QAction *saveAsAct = new QAction(QObject::tr("&SaveAs"), mainWindow);
|
||||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
||||||
saveAsAct->setStatusTip(QObject::tr("Save modified file as"));
|
saveAsAct->setStatusTip(QObject::tr("Save modified file as"));
|
||||||
fileMenu->addAction(saveAsAct);
|
fileMenu->addAction(saveAsAct);
|
||||||
|
|
||||||
QAction* quitAct = new QAction(QObject::tr("&Quit"), mainWindow);
|
QAction *quitAct = new QAction(QObject::tr("&Quit"), mainWindow);
|
||||||
quitAct->setShortcuts(QKeySequence::Quit);
|
quitAct->setShortcuts(QKeySequence::Quit);
|
||||||
quitAct->setStatusTip(QObject::tr("Quit the Application"));
|
quitAct->setStatusTip(QObject::tr("Quit the Application"));
|
||||||
fileMenu->addAction(quitAct);
|
fileMenu->addAction(quitAct);
|
||||||
|
|
||||||
LtsAppDescriptorEditor* editor = new LtsAppDescriptorEditor(mainWindow);
|
LtsAppDescriptorEditor *editor = new LtsAppDescriptorEditor(mainWindow);
|
||||||
mainWindow->setCentralWidget(editor);
|
mainWindow->setCentralWidget(editor);
|
||||||
QObject::connect(openAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onOpenClicked);
|
QObject::connect(openAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onOpenClicked);
|
||||||
QObject::connect(newAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onNewClicked);
|
QObject::connect(newAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onNewClicked);
|
||||||
QObject::connect(saveAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onSaveClicked);
|
QObject::connect(saveAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onSaveClicked);
|
||||||
QObject::connect(saveAsAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onSaveAsClicked);
|
QObject::connect(saveAsAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onSaveAsClicked);
|
||||||
QObject::connect(quitAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onQuitClicked);
|
QObject::connect(quitAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onQuitClicked);
|
||||||
|
|
||||||
mainWindow->show();
|
mainWindow->show();
|
||||||
|
|
||||||
int ret = a.exec();
|
int ret = a.exec();
|
||||||
delete mainWindow;
|
delete mainWindow;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
+92
-97
@@ -10,171 +10,166 @@
|
|||||||
|
|
||||||
namespace LtsCommandLineParser
|
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))
|
||||||
{
|
{
|
||||||
const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
|
const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
|
||||||
for (const QHostAddress& address : addresses)
|
for (const QHostAddress &address : addresses)
|
||||||
{
|
{
|
||||||
if (address.isLoopback() || address.isNull())
|
if (address.isLoopback() || address.isNull())
|
||||||
continue;
|
continue;
|
||||||
if (address.protocol() != QAbstractSocket::IPv4Protocol)
|
if (address.protocol() != QAbstractSocket::IPv4Protocol)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
m_generatedDomainId = (address.toIPv4Address() & 0x000000ff) % 232;
|
m_generatedDomainId = (address.toIPv4Address() & 0x000000ff) % 232;
|
||||||
if (m_generatedDomainId == 0)
|
if (m_generatedDomainId == 0)
|
||||||
m_generatedDomainId = s_maxDomainId;
|
m_generatedDomainId = s_maxDomainId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_enabledOptions.testFlag(ExerciseId))
|
if (m_enabledOptions.testFlag(ExerciseId))
|
||||||
addOption({{QStringLiteral("e"), QStringLiteral("exerciseid")},
|
addOption({{QStringLiteral("e"), QStringLiteral("exerciseid")},
|
||||||
QStringLiteral("Default: -1 (invalid, get from lts-cc.conf)"),
|
QStringLiteral("Default: -1 (invalid, get from lts-cc.conf)"),
|
||||||
QStringLiteral("exerciseId"),
|
QStringLiteral("exerciseId"),
|
||||||
QStringLiteral("-1")});
|
QStringLiteral("-1")});
|
||||||
if (m_enabledOptions.testFlag(DomainId))
|
if (m_enabledOptions.testFlag(DomainId))
|
||||||
addOption({{QStringLiteral("d"), QStringLiteral("domainid")},
|
addOption({{QStringLiteral("d"), QStringLiteral("domainid")},
|
||||||
QStringLiteral("Default: ") + QString::number(m_generatedDomainId),
|
QStringLiteral("Default: ") + QString::number(m_generatedDomainId),
|
||||||
QStringLiteral("domainId"),
|
QStringLiteral("domainId"),
|
||||||
QString::number(m_generatedDomainId)});
|
QString::number(m_generatedDomainId)});
|
||||||
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();
|
||||||
|
|
||||||
if (!m_enabledOptions.testFlag(NoVersion))
|
if (!m_enabledOptions.testFlag(NoVersion))
|
||||||
addVersionOption();
|
addVersionOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
int LtsCommandLineParser::domainId() const
|
int LtsCommandLineParser::domainId() const
|
||||||
{
|
{
|
||||||
if (m_domainId == 0 && m_generatedDomainId != 0 && !m_domainIdSetByFunction)
|
if (m_domainId == 0 && m_generatedDomainId != 0 && !m_domainIdSetByFunction)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
"\n\nAttention: using a default domain id != 0 because executable is run inside builddir - default "
|
"\n\nAttention: using a default domain id != 0 because executable is run inside builddir - default "
|
||||||
"domainid is %d\n\n",
|
"domainid is %d\n\n",
|
||||||
m_generatedDomainId);
|
m_generatedDomainId);
|
||||||
#else
|
#else
|
||||||
fprintf(stdout,
|
fprintf(stdout,
|
||||||
"\n\n\e[31mAttention: using a default domain id != 0 because executable is run inside builddir - "
|
"\n\n\e[31mAttention: using a default domain id != 0 because executable is run inside builddir - "
|
||||||
"default domainid is %d\e[0m\n\n",
|
"default domainid is %d\e[0m\n\n",
|
||||||
m_generatedDomainId);
|
m_generatedDomainId);
|
||||||
#endif
|
#endif
|
||||||
return m_generatedDomainId;
|
return m_generatedDomainId;
|
||||||
}
|
}
|
||||||
return m_domainId;
|
return m_domainId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCommandLineParser::setDomainId(int id)
|
void LtsCommandLineParser::setDomainId(int id)
|
||||||
{
|
{
|
||||||
m_domainIdSetByFunction = true;
|
m_domainIdSetByFunction = true;
|
||||||
m_domainId = id;
|
m_domainId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCommandLineParser::iniFileSet() const
|
bool LtsCommandLineParser::iniFileSet() const
|
||||||
{
|
{
|
||||||
if (!m_enabledOptions.testFlag(CustomConfigFile))
|
if (!m_enabledOptions.testFlag(CustomConfigFile))
|
||||||
return false;
|
return false;
|
||||||
return isSet(QStringLiteral("i"));
|
return isSet(QStringLiteral("i"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCommandLineParser::useTcpConnection() const
|
bool LtsCommandLineParser::useTcpConnection() const
|
||||||
{
|
{
|
||||||
if (!m_enabledOptions.testFlag(TcpConnectionUrl))
|
if (!m_enabledOptions.testFlag(TcpConnectionUrl))
|
||||||
return false;
|
return false;
|
||||||
return isSet(QStringLiteral("t"));
|
return isSet(QStringLiteral("t"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl LtsCommandLineParser::tcpConnectionUrl() const
|
QUrl LtsCommandLineParser::tcpConnectionUrl() const
|
||||||
{
|
{
|
||||||
if (!m_enabledOptions.testFlag(TcpConnectionUrl))
|
if (!m_enabledOptions.testFlag(TcpConnectionUrl))
|
||||||
return QUrl();
|
return QUrl();
|
||||||
if (!useTcpConnection())
|
if (!useTcpConnection())
|
||||||
return QUrl();
|
return QUrl();
|
||||||
QString str = value(QStringLiteral("t"));
|
QString str = value(QStringLiteral("t"));
|
||||||
|
|
||||||
str.replace(QLatin1String("tcpv4_lan"), QLatin1String("tcpv4lan"));
|
str.replace(QLatin1String("tcpv4_lan"), QLatin1String("tcpv4lan"));
|
||||||
QUrl url = QUrl::fromUserInput(str);
|
QUrl url = QUrl::fromUserInput(str);
|
||||||
if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("file"))
|
if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("file"))
|
||||||
url.setScheme(QStringLiteral("tcpv4lan"));
|
url.setScheme(QStringLiteral("tcpv4lan"));
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCommandLineParser::init(bool bParseHelp)
|
bool LtsCommandLineParser::init(bool bParseHelp)
|
||||||
{
|
{
|
||||||
if (!parse(QCoreApplication::arguments()))
|
if (!parse(QCoreApplication::arguments()))
|
||||||
{
|
{
|
||||||
fprintf(stdout, "\nBad option: %s \n", qPrintable(errorText()));
|
fprintf(stdout, "\nBad option: %s \n", qPrintable(errorText()));
|
||||||
if (!m_unitModuleTestMode)
|
if (!m_unitModuleTestMode)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_enabledOptions.testFlag(ExerciseId))
|
if (m_enabledOptions.testFlag(ExerciseId))
|
||||||
m_exerciseId = value(QStringLiteral("e")).toInt();
|
m_exerciseId = value(QStringLiteral("e")).toInt();
|
||||||
if (m_enabledOptions.testFlag(DomainId))
|
if (m_enabledOptions.testFlag(DomainId))
|
||||||
m_domainId = value(QStringLiteral("d")).toInt();
|
m_domainId = value(QStringLiteral("d")).toInt();
|
||||||
if (m_enabledOptions.testFlag(CustomConfigFile))
|
if (m_enabledOptions.testFlag(CustomConfigFile))
|
||||||
m_iniFile = value(QStringLiteral("i"));
|
m_iniFile = value(QStringLiteral("i"));
|
||||||
|
|
||||||
if (bParseHelp && isSet(QStringLiteral("h")))
|
if (bParseHelp && isSet(QStringLiteral("h")))
|
||||||
showHelp();
|
showHelp();
|
||||||
if (!m_unitModuleTestMode && isSet(QStringLiteral("v")))
|
if (!m_unitModuleTestMode && isSet(QStringLiteral("v")))
|
||||||
showVersion();
|
showVersion();
|
||||||
if (!domainIdProvided())
|
if (!domainIdProvided())
|
||||||
{
|
{
|
||||||
const QString iniFile = m_iniFile.isEmpty() ? NGL::findProjectConfigFile() : m_iniFile;
|
const QString iniFile = m_iniFile.isEmpty() ? NGL::findProjectConfigFile() : m_iniFile;
|
||||||
if (!iniFile.isEmpty())
|
if (!iniFile.isEmpty())
|
||||||
{
|
{
|
||||||
QSettings s(iniFile, QSettings::IniFormat);
|
QSettings s(iniFile, QSettings::IniFormat);
|
||||||
bool bOk;
|
bool bOk;
|
||||||
int domainId = s.value(QStringLiteral("Global/DomainId"), m_domainId).toInt(&bOk);
|
int domainId = s.value(QStringLiteral("Global/DomainId"), m_domainId).toInt(&bOk);
|
||||||
if (bOk && domainId > 0 && domainId <= s_maxDomainId)
|
if (bOk && domainId > 0 && domainId <= s_maxDomainId)
|
||||||
m_domainId = domainId;
|
m_domainId = domainId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCommandLineParser::showHelp(int exitCode)
|
void LtsCommandLineParser::showHelp(int exitCode)
|
||||||
{
|
{
|
||||||
if (!m_additionalHelpStr.isEmpty())
|
if (!m_additionalHelpStr.isEmpty())
|
||||||
fprintf(stdout, "%s", qPrintable(m_additionalHelpStr));
|
fprintf(stdout, "%s", qPrintable(m_additionalHelpStr));
|
||||||
|
|
||||||
QCommandLineParser::showHelp(exitCode);
|
QCommandLineParser::showHelp(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCommandLineParser::domainIdProvided() const
|
bool LtsCommandLineParser::domainIdProvided() const
|
||||||
{
|
{
|
||||||
if (!m_enabledOptions.testFlag(DomainId))
|
if (!m_enabledOptions.testFlag(DomainId))
|
||||||
return false;
|
return false;
|
||||||
return isSet(QStringLiteral("d"));
|
return isSet(QStringLiteral("d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCommandLineParser::exerciseIdProvided() const
|
bool LtsCommandLineParser::exerciseIdProvided() const
|
||||||
{
|
{
|
||||||
if (!m_enabledOptions.testFlag(ExerciseId))
|
if (!m_enabledOptions.testFlag(ExerciseId))
|
||||||
return false;
|
return false;
|
||||||
return isSet(QStringLiteral("e"));
|
return isSet(QStringLiteral("e"));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsCommandLineParser
|
} // namespace LtsCommandLineParser
|
||||||
+17
-25
@@ -10,34 +10,29 @@ class QUrl;
|
|||||||
|
|
||||||
namespace LtsCommandLineParser
|
namespace LtsCommandLineParser
|
||||||
{
|
{
|
||||||
class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLineParser
|
class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLineParser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum ProvideCommandLineParameterOptions {
|
enum ProvideCommandLineParameterOptions
|
||||||
None = 0x0000,
|
{
|
||||||
CreateDomainIdFromIp = 0x0001,
|
None = 0x0000,
|
||||||
DomainId = 0x0002,
|
CreateDomainIdFromIp = 0x0001,
|
||||||
ExerciseId = 0x0004,
|
DomainId = 0x0002,
|
||||||
CustomConfigFile = 0x0008,
|
ExerciseId = 0x0004,
|
||||||
TcpConnectionUrl = 0x0010,
|
CustomConfigFile = 0x0008,
|
||||||
NoVersion = 0x0020
|
TcpConnectionUrl = 0x0010,
|
||||||
|
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;
|
||||||
@@ -64,6 +56,6 @@ class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLinePars
|
|||||||
bool m_domainIdSetByFunction{false};
|
bool m_domainIdSetByFunction{false};
|
||||||
bool m_unitModuleTestMode{false};
|
bool m_unitModuleTestMode{false};
|
||||||
QString m_iniFile;
|
QString m_iniFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsCommandLineParser
|
} // namespace LtsCommandLineParser
|
||||||
@@ -5,60 +5,70 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc < 3 || argc > 5)
|
if (argc < 3 || argc > 5)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s <lon_degree> <lat_degree> [<precision>]\n", argv[0]);
|
fprintf(stderr, "Usage: %s <lon_degree> <lat_degree> [<precision>]\n", argv[0]);
|
||||||
fprintf(stderr, "Usage: %s <lon_rad> <lat_rad> -r [<precision>]\n", argv[0]);
|
fprintf(stderr, "Usage: %s <lon_rad> <lat_rad> -r [<precision>]\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lonLatInRad = false;
|
bool lonLatInRad = false;
|
||||||
double lon = atof(argv[1]);
|
double lon = atof(argv[1]);
|
||||||
double lat = atof(argv[2]);
|
double lat = atof(argv[2]);
|
||||||
int prec = 5;
|
int prec = 5;
|
||||||
if (argc >= 4)
|
if (argc >= 4)
|
||||||
|
{
|
||||||
|
int precArgId = -1;
|
||||||
|
if (strcmp(argv[3], "-r") == 0)
|
||||||
{
|
{
|
||||||
int precArgId = -1;
|
lonLatInRad = true;
|
||||||
if (strcmp(argv[3], "-r") == 0)
|
if (argc == 5)
|
||||||
{
|
precArgId = 4;
|
||||||
lonLatInRad = true;
|
|
||||||
if (argc == 5)
|
|
||||||
precArgId = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
precArgId = 3;
|
|
||||||
if (precArgId > 0)
|
|
||||||
prec = atoi(argv[precArgId]);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
precArgId = 3;
|
||||||
|
if (precArgId > 0)
|
||||||
|
prec = atoi(argv[precArgId]);
|
||||||
|
}
|
||||||
|
|
||||||
std::string mgrs;
|
std::string mgrs;
|
||||||
|
|
||||||
int zone;
|
int zone;
|
||||||
bool northp;
|
bool northp;
|
||||||
double x, y;
|
double x, y;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const double latDeg = lonLatInRad ? lat * 180 / M_PI : lat;
|
const double latDeg = lonLatInRad ? lat * 180 / M_PI : lat;
|
||||||
const double lonDeg = lonLatInRad ? lon * 180 / M_PI : lon;
|
const double lonDeg = lonLatInRad ? lon * 180 / M_PI : lon;
|
||||||
GeographicLib::UTMUPS::Forward(latDeg, lonDeg, zone, northp, x, y);
|
GeographicLib::UTMUPS::Forward(latDeg, lonDeg, zone, northp, x, y);
|
||||||
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error converting %9.6f, %9.6f to MGRS coords\n", lat, lon);
|
fprintf(stderr, "Error converting %9.6f, %9.6f to MGRS coords\n", lat, lon);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
std::string part1, part2, part3, part4;
|
std::string part1, part2, part3, part4;
|
||||||
part1 = mgrs.substr(0, 3);
|
part1 = mgrs.substr(0, 3);
|
||||||
part2 = mgrs.substr(3, 2);
|
part2 = mgrs.substr(3, 2);
|
||||||
if (prec > 0)
|
if (prec > 0)
|
||||||
{
|
{
|
||||||
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",
|
||||||
return 0;
|
lon,
|
||||||
|
lat,
|
||||||
|
part1.c_str(),
|
||||||
|
part2.c_str(),
|
||||||
|
part3.c_str(),
|
||||||
|
part4.c_str(),
|
||||||
|
zone,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
northp ? 'N' : 'S');
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -15,110 +15,108 @@
|
|||||||
namespace LtsCoordTrans
|
namespace LtsCoordTrans
|
||||||
{
|
{
|
||||||
|
|
||||||
static long s_conversion_counter_MGRS_Forward = 0;
|
static long s_conversion_counter_MGRS_Forward = 0;
|
||||||
static long s_conversion_counter_MGRS_Reverse = 0;
|
static long s_conversion_counter_MGRS_Reverse = 0;
|
||||||
|
|
||||||
static long s_conversion_counter_WGS84_Forward = 0;
|
static long s_conversion_counter_WGS84_Forward = 0;
|
||||||
static long s_conversion_counter_WGS84_Reverse = 0;
|
static long s_conversion_counter_WGS84_Reverse = 0;
|
||||||
|
|
||||||
static long s_conversion_counter_UTMUPS_Forward = 0;
|
static long s_conversion_counter_UTMUPS_Forward = 0;
|
||||||
static long s_conversion_counter_UTMUPS_Reverse = 0;
|
static long s_conversion_counter_UTMUPS_Reverse = 0;
|
||||||
|
|
||||||
inline void incrementCounter(long& counterRef)
|
inline void incrementCounter(long &counterRef)
|
||||||
{
|
{
|
||||||
#ifdef LTS_DEBUG
|
#ifdef LTS_DEBUG
|
||||||
++counterRef;
|
++counterRef;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline std::string cleanupMgrsString(const QString& in)
|
static inline std::string cleanupMgrsString(const QString &in)
|
||||||
{
|
{
|
||||||
const QByteArray ba(in.toLatin1());
|
const QByteArray ba(in.toLatin1());
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.reserve(ba.size());
|
ret.reserve(ba.size());
|
||||||
for (const char c : ba)
|
for (const char c : ba)
|
||||||
{
|
{
|
||||||
if (c != ' ')
|
if (c != ' ')
|
||||||
ret += c;
|
ret += c;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString UtmCoordinate::mgrs(int prec, bool withSpaces) const
|
QString UtmCoordinate::mgrs(int prec, bool withSpaces) const
|
||||||
{
|
{
|
||||||
if (prec < 0)
|
if (prec < 0)
|
||||||
prec = 0;
|
prec = 0;
|
||||||
if (prec > 11)
|
if (prec > 11)
|
||||||
prec = 11;
|
prec = 11;
|
||||||
|
|
||||||
std::string mgrs;
|
std::string mgrs;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
||||||
incrementCounter(s_conversion_counter_MGRS_Forward);
|
incrementCounter(s_conversion_counter_MGRS_Forward);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error while calculating mgrs from utm %d, %9.6f, %9.6f: %s\n", zone, x, y, e.what());
|
fprintf(stderr, "Error while calculating mgrs from utm %d, %9.6f, %9.6f: %s\n", zone, x, y, e.what());
|
||||||
mgrs.clear();
|
mgrs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ret;
|
QString ret;
|
||||||
if (withSpaces && mgrs.size() == static_cast<size_t>(5 + 2 * prec))
|
if (withSpaces && mgrs.size() == static_cast<size_t>(5 + 2 * prec))
|
||||||
{
|
{
|
||||||
|
|
||||||
const char* ptr = mgrs.c_str();
|
const char *ptr = mgrs.c_str();
|
||||||
|
|
||||||
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
|
||||||
ret = QString::fromLatin1(mgrs.c_str(), mgrs.size());
|
ret = QString::fromLatin1(mgrs.c_str(), mgrs.size());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF UtmCoordinate::toPoint() const
|
QPointF UtmCoordinate::toPoint() const
|
||||||
{
|
{
|
||||||
return {x, y};
|
return {x, y};
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF UtmCoordinate::geographic(double offsetX, double offsetY) const
|
QPointF UtmCoordinate::geographic(double offsetX, double offsetY) const
|
||||||
{
|
{
|
||||||
QPointF ret;
|
QPointF ret;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GeographicLib::UTMUPS::Reverse(zone, northp, x + offsetX, y + offsetY, ret.ry(), ret.rx());
|
GeographicLib::UTMUPS::Reverse(zone, northp, x + offsetX, y + offsetY, ret.ry(), ret.rx());
|
||||||
incrementCounter(s_conversion_counter_UTMUPS_Reverse);
|
incrementCounter(s_conversion_counter_UTMUPS_Reverse);
|
||||||
}
|
}
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF UtmCoordinate::geographic(const QPointF& offset) const
|
QPointF UtmCoordinate::geographic(const QPointF &offset) const
|
||||||
{
|
{
|
||||||
return geographic(offset.x(), offset.y());
|
return geographic(offset.x(), offset.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF UtmCoordinate::relativeTo(const UtmCoordinate& other) const
|
QPointF UtmCoordinate::relativeTo(const UtmCoordinate &other) const
|
||||||
{
|
{
|
||||||
if (zone == other.zone)
|
if (zone == other.zone)
|
||||||
return QPointF(x - other.x, y - other.y);
|
return QPointF(x - other.x, y - other.y);
|
||||||
|
|
||||||
UtmCoordinate otherInMyZone = fromGeographic(other.geographic(), zone);
|
UtmCoordinate otherInMyZone = fromGeographic(other.geographic(), zone);
|
||||||
return QPointF(x - otherInMyZone.x, y - otherInMyZone.y);
|
return QPointF(x - otherInMyZone.x, y - otherInMyZone.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
UtmCoordinate UtmCoordinate::fromGeographic(double lon, double lat, int setZone)
|
UtmCoordinate UtmCoordinate::fromGeographic(double lon, double lat, int setZone)
|
||||||
{
|
{
|
||||||
|
|
||||||
lon *= rad2deg();
|
lon *= rad2deg();
|
||||||
lat *= rad2deg();
|
lat *= rad2deg();
|
||||||
@@ -127,81 +125,81 @@ UtmCoordinate UtmCoordinate::fromGeographic(double lon, double lat, int setZone)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
GeographicLib::UTMUPS::Forward(lat, lon, ret.zone, ret.northp, ret.x, ret.y, setZone);
|
GeographicLib::UTMUPS::Forward(lat, lon, ret.zone, ret.northp, ret.x, ret.y, setZone);
|
||||||
incrementCounter(s_conversion_counter_UTMUPS_Forward);
|
incrementCounter(s_conversion_counter_UTMUPS_Forward);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error while calculating mgrs base point from %9.6f, %9.6f: %s\n", lat, lon, e.what());
|
fprintf(stderr, "Error while calculating mgrs base point from %9.6f, %9.6f: %s\n", lat, lon, e.what());
|
||||||
ret = UtmCoordinate();
|
ret = UtmCoordinate();
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
UtmCoordinate UtmCoordinate::fromGeographic(const QPointF& lonLat, int setZone)
|
UtmCoordinate UtmCoordinate::fromGeographic(const QPointF &lonLat, int setZone)
|
||||||
{
|
{
|
||||||
return fromGeographic(lonLat.x(), lonLat.y(), setZone);
|
return fromGeographic(lonLat.x(), lonLat.y(), setZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
UtmCoordinate UtmCoordinate::fromMgrs(const QString& mgrs)
|
UtmCoordinate UtmCoordinate::fromMgrs(const QString &mgrs)
|
||||||
{
|
{
|
||||||
UtmCoordinate utm;
|
UtmCoordinate utm;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int prec;
|
int prec;
|
||||||
|
|
||||||
GeographicLib::MGRS::Reverse(cleanupMgrsString(mgrs), utm.zone, utm.northp, utm.x, utm.y, prec, true);
|
GeographicLib::MGRS::Reverse(cleanupMgrsString(mgrs), utm.zone, utm.northp, utm.x, utm.y, prec, true);
|
||||||
incrementCounter(s_conversion_counter_MGRS_Reverse);
|
incrementCounter(s_conversion_counter_MGRS_Reverse);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error while converting mgrs coordinate %s to utm: %s\n", qPrintable(mgrs), e.what());
|
fprintf(stderr, "Error while converting mgrs coordinate %s to utm: %s\n", qPrintable(mgrs), e.what());
|
||||||
utm = UtmCoordinate();
|
utm = UtmCoordinate();
|
||||||
}
|
}
|
||||||
return utm;
|
return utm;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString mgrsFromGeographic(double lon, double lat, int prec, bool withSpaces)
|
QString mgrsFromGeographic(double lon, double lat, int prec, bool withSpaces)
|
||||||
{
|
{
|
||||||
return UtmCoordinate::fromGeographic(lon, lat, -1).mgrs(prec, withSpaces);
|
return UtmCoordinate::fromGeographic(lon, lat, -1).mgrs(prec, withSpaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF geographicFromMgrs(const QString& mgrs)
|
QPointF geographicFromMgrs(const QString &mgrs)
|
||||||
{
|
{
|
||||||
return UtmCoordinate::fromMgrs(mgrs).geographic();
|
return UtmCoordinate::fromMgrs(mgrs).geographic();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<UtmCoordinate>& staticDefaultSquaresHelper()
|
QVector<UtmCoordinate> &staticDefaultSquaresHelper()
|
||||||
{
|
{
|
||||||
static QVector<UtmCoordinate> s_defaultMgrsSquares;
|
static QVector<UtmCoordinate> s_defaultMgrsSquares;
|
||||||
return s_defaultMgrsSquares;
|
return s_defaultMgrsSquares;
|
||||||
}
|
}
|
||||||
|
|
||||||
UtmCoordinate& staticPreferedMgrsSquareHelper()
|
UtmCoordinate &staticPreferedMgrsSquareHelper()
|
||||||
{
|
{
|
||||||
static UtmCoordinate s_preferedMgrsSquare;
|
static UtmCoordinate s_preferedMgrsSquare;
|
||||||
return s_preferedMgrsSquare;
|
return s_preferedMgrsSquare;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<UtmCoordinate>& staticMgrsSquaresWithOffsetsHelper()
|
QVector<UtmCoordinate> &staticMgrsSquaresWithOffsetsHelper()
|
||||||
{
|
{
|
||||||
static QVector<UtmCoordinate> s_mgrsSquaresWithOffsets;
|
static QVector<UtmCoordinate> s_mgrsSquaresWithOffsets;
|
||||||
return s_mgrsSquaresWithOffsets;
|
return s_mgrsSquaresWithOffsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF addMarginToArea(const QRectF& rect_LatLon_radiant, const QSize& marginMeter)
|
QRectF addMarginToArea(const QRectF &rect_LatLon_radiant, const QSize &marginMeter)
|
||||||
{
|
{
|
||||||
double lonMin, lonMax, latMin, latMmax;
|
double lonMin, lonMax, latMin, latMmax;
|
||||||
rect_LatLon_radiant.normalized().getCoords(&lonMin, &latMin, &lonMax, &latMmax);
|
rect_LatLon_radiant.normalized().getCoords(&lonMin, &latMin, &lonMax, &latMmax);
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate basePoint;
|
LtsCoordTrans::UtmCoordinate basePoint;
|
||||||
{
|
{
|
||||||
|
|
||||||
const QPointF centerRad = rect_LatLon_radiant.center();
|
const QPointF centerRad = rect_LatLon_radiant.center();
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(centerRad.x(), centerRad.y(), -1);
|
QString mgrs = LtsCoordTrans::mgrsFromGeographic(centerRad.x(), centerRad.y(), -1);
|
||||||
mgrs += QStringLiteral("00000000000000");
|
mgrs += QStringLiteral("00000000000000");
|
||||||
|
|
||||||
basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(mgrs);
|
basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(mgrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin, basePoint.zone));
|
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin, basePoint.zone));
|
||||||
@@ -215,27 +213,26 @@ QRectF addMarginToArea(const QRectF& rect_LatLon_radiant, const QSize& marginMet
|
|||||||
|
|
||||||
QRectF res = QRectF(topLeft, bottomRight);
|
QRectF res = QRectF(topLeft, bottomRight);
|
||||||
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);
|
||||||
|
|
||||||
if (setAsDefaultSquares)
|
if (setAsDefaultSquares)
|
||||||
staticDefaultSquaresHelper() = ret;
|
staticDefaultSquaresHelper() = ret;
|
||||||
|
|
||||||
if (setAsPreferedSquare)
|
if (setAsPreferedSquare)
|
||||||
staticPreferedMgrsSquareHelper() = LtsCoordTrans::UtmCoordinate::fromGeographic(rect.center());
|
staticPreferedMgrsSquareHelper() = LtsCoordTrans::UtmCoordinate::fromGeographic(rect.center());
|
||||||
|
|
||||||
if (setAsSquareWithMargin)
|
if (setAsSquareWithMargin)
|
||||||
staticMgrsSquaresWithOffsetsHelper() = ret;
|
staticMgrsSquaresWithOffsetsHelper() = ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF& rect)
|
QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF &rect)
|
||||||
{
|
{
|
||||||
QVector<UtmCoordinate> ret;
|
QVector<UtmCoordinate> ret;
|
||||||
QVector<QString> tmpMgrsSquares;
|
QVector<QString> tmpMgrsSquares;
|
||||||
|
|
||||||
@@ -244,19 +241,19 @@ QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF& rect)
|
|||||||
|
|
||||||
bool withInSingleUtmSquare = true;
|
bool withInSingleUtmSquare = true;
|
||||||
{
|
{
|
||||||
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax));
|
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax));
|
||||||
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin));
|
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin));
|
||||||
withInSingleUtmSquare = upperRight.zone == lowerLeft.zone;
|
withInSingleUtmSquare = upperRight.zone == lowerLeft.zone;
|
||||||
}
|
}
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate basePoint;
|
LtsCoordTrans::UtmCoordinate basePoint;
|
||||||
{
|
{
|
||||||
|
|
||||||
QPointF centerRad = rect.center();
|
QPointF centerRad = rect.center();
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(centerRad.x(), centerRad.y(), -1);
|
QString mgrs = LtsCoordTrans::mgrsFromGeographic(centerRad.x(), centerRad.y(), -1);
|
||||||
mgrs += QStringLiteral("00000000000000");
|
mgrs += QStringLiteral("00000000000000");
|
||||||
|
|
||||||
basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(mgrs);
|
basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(mgrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax, basePoint.zone));
|
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax, basePoint.zone));
|
||||||
@@ -268,180 +265,173 @@ QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF& rect)
|
|||||||
const int increment = withInSingleUtmSquare ? 10000 : 1000;
|
const int increment = withInSingleUtmSquare ? 10000 : 1000;
|
||||||
for (double x = 0; x <= maxX + increment; x += increment)
|
for (double x = 0; x <= maxX + increment; x += increment)
|
||||||
{
|
{
|
||||||
const double xOfs = std::min(x, maxX);
|
const double xOfs = std::min(x, maxX);
|
||||||
for (double y = 0; y <= maxY + increment; y += increment)
|
for (double y = 0; y <= maxY + increment; y += increment)
|
||||||
|
{
|
||||||
|
const double yOfs = std::min(y, maxY);
|
||||||
|
|
||||||
|
const UtmCoordinate utm(UtmCoordinate::fromGeographic(lowerLeft.geographic(xOfs, yOfs)));
|
||||||
|
const QString mgrs(utm.mgrs(0));
|
||||||
|
|
||||||
|
if (!tmpMgrsSquares.contains(mgrs))
|
||||||
{
|
{
|
||||||
const double yOfs = std::min(y, maxY);
|
tmpMgrsSquares += mgrs;
|
||||||
|
ret += utm;
|
||||||
const UtmCoordinate utm(UtmCoordinate::fromGeographic(lowerLeft.geographic(xOfs, yOfs)));
|
|
||||||
const QString mgrs(utm.mgrs(0));
|
|
||||||
|
|
||||||
if (!tmpMgrsSquares.contains(mgrs))
|
|
||||||
{
|
|
||||||
tmpMgrsSquares += mgrs;
|
|
||||||
ret += utm;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList getMgrsSurroundingSquares(const QRectF& geoRect, const QSize& offsetMeter)
|
QStringList getMgrsSurroundingSquares(const QRectF &geoRect, const QSize &offsetMeter)
|
||||||
{
|
{
|
||||||
|
|
||||||
const QVector<UtmCoordinate> mainUtms = getMgrsSquaresInternal(geoRect);
|
const QVector<UtmCoordinate> mainUtms = getMgrsSquaresInternal(geoRect);
|
||||||
QStringList mainSquares;
|
QStringList mainSquares;
|
||||||
mainSquares.reserve(mainUtms.count());
|
mainSquares.reserve(mainUtms.count());
|
||||||
for (const auto& utm : mainUtms)
|
for (const auto &utm : mainUtms)
|
||||||
mainSquares.append(utm.mgrs(0));
|
mainSquares.append(utm.mgrs(0));
|
||||||
|
|
||||||
const QRectF rectWithOffset = addMarginToArea(geoRect, offsetMeter);
|
const QRectF rectWithOffset = addMarginToArea(geoRect, offsetMeter);
|
||||||
|
|
||||||
QVector<UtmCoordinate> mainUtmsWithOffset = getMgrsSquaresInternal(rectWithOffset);
|
QVector<UtmCoordinate> mainUtmsWithOffset = getMgrsSquaresInternal(rectWithOffset);
|
||||||
QStringList mainSquaresWithOffset;
|
QStringList mainSquaresWithOffset;
|
||||||
mainSquaresWithOffset.reserve(mainUtmsWithOffset.count());
|
mainSquaresWithOffset.reserve(mainUtmsWithOffset.count());
|
||||||
for (const auto& utm : std::as_const(mainUtmsWithOffset))
|
for (const auto &utm : std::as_const(mainUtmsWithOffset))
|
||||||
mainSquaresWithOffset.append(utm.mgrs(0));
|
mainSquaresWithOffset.append(utm.mgrs(0));
|
||||||
|
|
||||||
QStringList surroundingSquares;
|
QStringList surroundingSquares;
|
||||||
surroundingSquares.reserve(mainSquaresWithOffset.count());
|
surroundingSquares.reserve(mainSquaresWithOffset.count());
|
||||||
for (const auto& mgrs0 : mainSquaresWithOffset)
|
for (const auto &mgrs0 : mainSquaresWithOffset)
|
||||||
{
|
{
|
||||||
if (!mainSquares.contains(mgrs0))
|
if (!mainSquares.contains(mgrs0))
|
||||||
surroundingSquares.append(mgrs0);
|
surroundingSquares.append(mgrs0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return surroundingSquares;
|
return surroundingSquares;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<UtmCoordinate> defaultMgrsSquareWithOffsets()
|
QVector<UtmCoordinate> defaultMgrsSquareWithOffsets()
|
||||||
{
|
{
|
||||||
return staticMgrsSquaresWithOffsetsHelper();
|
return staticMgrsSquaresWithOffsetsHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDefaultMgrsSquares(const QVector<QString>& squares)
|
void setDefaultMgrsSquares(const QVector<QString> &squares)
|
||||||
{
|
{
|
||||||
QVector<UtmCoordinate> coords;
|
QVector<UtmCoordinate> coords;
|
||||||
coords.reserve(squares.size());
|
coords.reserve(squares.size());
|
||||||
for (const QString& s : squares)
|
for (const QString &s : squares)
|
||||||
coords += UtmCoordinate::fromMgrs(s + QStringLiteral("00000000000000"));
|
coords += UtmCoordinate::fromMgrs(s + QStringLiteral("00000000000000"));
|
||||||
staticDefaultSquaresHelper() = coords;
|
staticDefaultSquaresHelper() = coords;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<UtmCoordinate> defaultMgrsSquares()
|
QVector<UtmCoordinate> defaultMgrsSquares()
|
||||||
{
|
{
|
||||||
return staticDefaultSquaresHelper();
|
return staticDefaultSquaresHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
UtmCoordinate preferedMgrsSquare()
|
UtmCoordinate preferedMgrsSquare()
|
||||||
{
|
{
|
||||||
return staticPreferedMgrsSquareHelper();
|
return staticPreferedMgrsSquareHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lonLatAltToGeocentric(double lon, double lat, double altitude, double& xOut, double& yOut, double& zOut)
|
bool lonLatAltToGeocentric(double lon, double lat, double altitude, double &xOut, double &yOut, double &zOut)
|
||||||
{
|
{
|
||||||
|
|
||||||
lon *= rad2deg();
|
lon *= rad2deg();
|
||||||
lat *= rad2deg();
|
lat *= rad2deg();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GeographicLib::Geocentric::WGS84().Forward(lat, lon, altitude, xOut, yOut, zOut);
|
GeographicLib::Geocentric::WGS84().Forward(lat, lon, altitude, xOut, yOut, zOut);
|
||||||
incrementCounter(s_conversion_counter_WGS84_Forward);
|
incrementCounter(s_conversion_counter_WGS84_Forward);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
xOut = 0;
|
xOut = 0;
|
||||||
yOut = 0;
|
yOut = 0;
|
||||||
zOut = 0;
|
zOut = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool geocentric2LonLatAlt(double x, double y, double z, double& lon, double& lat, double& altitude)
|
bool geocentric2LonLatAlt(double x, double y, double z, double &lon, double &lat, double &altitude)
|
||||||
{
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GeographicLib::Geocentric::WGS84().Reverse(x, y, z, lat, lon, altitude);
|
GeographicLib::Geocentric::WGS84().Reverse(x, y, z, lat, lon, altitude);
|
||||||
incrementCounter(s_conversion_counter_WGS84_Reverse);
|
incrementCounter(s_conversion_counter_WGS84_Reverse);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
lon = 0;
|
lon = 0;
|
||||||
lat = 0;
|
lat = 0;
|
||||||
altitude = 0;
|
altitude = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
lon *= deg2rad();
|
lon *= deg2rad();
|
||||||
lat *= deg2rad();
|
lat *= deg2rad();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
double distance(const QPointF& p1, const QPointF& p2)
|
double distance(const QPointF &p1, const QPointF &p2)
|
||||||
{
|
{
|
||||||
return distance(p1.x(), p1.y(), p2.x(), p2.y());
|
return distance(p1.x(), p1.y(), p2.x(), p2.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
double squareDistance(const QPointF& p1, const QPointF& p2)
|
double squareDistance(const QPointF &p1, const QPointF &p2)
|
||||||
{
|
{
|
||||||
return squareDistance(p1.x(), p1.y(), p2.x(), p2.y());
|
return squareDistance(p1.x(), p1.y(), p2.x(), p2.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
{
|
{
|
||||||
return s_conversion_counter_MGRS_Forward;
|
return s_conversion_counter_MGRS_Forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getConversionCounter_MGRS_Reverse()
|
long getConversionCounter_MGRS_Reverse()
|
||||||
{
|
{
|
||||||
return s_conversion_counter_MGRS_Reverse;
|
return s_conversion_counter_MGRS_Reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getConversionCounter_WGS84_Forward()
|
long getConversionCounter_WGS84_Forward()
|
||||||
{
|
{
|
||||||
return s_conversion_counter_WGS84_Forward;
|
return s_conversion_counter_WGS84_Forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getConversionCounter_WGS84_Reverse()
|
long getConversionCounter_WGS84_Reverse()
|
||||||
{
|
{
|
||||||
return s_conversion_counter_WGS84_Reverse;
|
return s_conversion_counter_WGS84_Reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getConversionCounter_UTMUPS_Forward()
|
long getConversionCounter_UTMUPS_Forward()
|
||||||
{
|
{
|
||||||
return s_conversion_counter_UTMUPS_Forward;
|
return s_conversion_counter_UTMUPS_Forward;
|
||||||
}
|
}
|
||||||
|
|
||||||
long getConversionCounter_UTMUPS_Reverse()
|
long getConversionCounter_UTMUPS_Reverse()
|
||||||
{
|
{
|
||||||
return s_conversion_counter_UTMUPS_Reverse;
|
return s_conversion_counter_UTMUPS_Reverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsCoordTrans
|
} // namespace LtsCoordTrans
|
||||||
@@ -14,23 +14,23 @@ class QString;
|
|||||||
namespace LtsCoordTrans
|
namespace LtsCoordTrans
|
||||||
{
|
{
|
||||||
|
|
||||||
inline Q_CONSTEXPR double pi()
|
inline Q_CONSTEXPR double pi()
|
||||||
{
|
{
|
||||||
return M_PI;
|
return M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Q_CONSTEXPR double deg2rad()
|
inline Q_CONSTEXPR double deg2rad()
|
||||||
{
|
{
|
||||||
return pi() / 180.;
|
return pi() / 180.;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Q_CONSTEXPR double rad2deg()
|
inline Q_CONSTEXPR double rad2deg()
|
||||||
{
|
{
|
||||||
return 1. / deg2rad();
|
return 1. / deg2rad();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LTSCOORDTRANS_EXPORT UtmCoordinate
|
struct LTSCOORDTRANS_EXPORT UtmCoordinate
|
||||||
{
|
{
|
||||||
int zone = -1;
|
int zone = -1;
|
||||||
bool northp = true;
|
bool northp = true;
|
||||||
double x = 0.;
|
double x = 0.;
|
||||||
@@ -38,152 +38,146 @@ 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;
|
||||||
|
|
||||||
QPointF geographic(double offsetX = 0., double offsetY = 0.) const;
|
QPointF geographic(double offsetX = 0., double offsetY = 0.) const;
|
||||||
|
|
||||||
QPointF geographic(const QPointF& offset) const;
|
QPointF geographic(const QPointF &offset) const;
|
||||||
|
|
||||||
QPointF relativeTo(const UtmCoordinate& other) const;
|
QPointF relativeTo(const UtmCoordinate &other) const;
|
||||||
|
|
||||||
static UtmCoordinate fromGeographic(double lon, double lat, int setZone = -1);
|
static UtmCoordinate fromGeographic(double lon, double lat, int setZone = -1);
|
||||||
|
|
||||||
static UtmCoordinate fromGeographic(const QPointF& lonLat, int setZone = -1);
|
static UtmCoordinate fromGeographic(const QPointF &lonLat, int setZone = -1);
|
||||||
|
|
||||||
static UtmCoordinate fromMgrs(const QString& mgrs);
|
static UtmCoordinate fromMgrs(const QString &mgrs);
|
||||||
};
|
};
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QString mgrsFromGeographic(double lon, double lat, int prec = 5, bool withSpaces = true);
|
LTSCOORDTRANS_EXPORT QString mgrsFromGeographic(double lon, double lat, int prec = 5, bool withSpaces = true);
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QPointF geographicFromMgrs(const QString& mgrs);
|
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);
|
||||||
|
|
||||||
QStringList getMgrsSurroundingSquares(const QRectF& geoRect, const QSize& offsetMeter);
|
QStringList getMgrsSurroundingSquares(const QRectF &geoRect, const QSize &offsetMeter);
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> defaultMgrsSquareWithOffsets();
|
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> defaultMgrsSquareWithOffsets();
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT void setDefaultMgrsSquares(const QVector<QString>& squares);
|
LTSCOORDTRANS_EXPORT void setDefaultMgrsSquares(const QVector<QString> &squares);
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> defaultMgrsSquares();
|
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)
|
||||||
{
|
{
|
||||||
if (p1.zone != p2.zone)
|
if (p1.zone != p2.zone)
|
||||||
{
|
{
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
return std::nan("");
|
return std::nan("");
|
||||||
}
|
}
|
||||||
return std::pow(p1.x - p2.x, 2) + std::pow(p1.y - p2.y, 2);
|
return std::pow(p1.x - p2.x, 2) + std::pow(p1.y - p2.y, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT double squareDistance(const QPointF& p1, const QPointF& p2);
|
LTSCOORDTRANS_EXPORT double squareDistance(const QPointF &p1, const QPointF &p2);
|
||||||
|
|
||||||
inline double squareDistance(const double lon1, const double lat1, const double lon2, const double lat2)
|
inline double squareDistance(const double lon1, const double lat1, const double lon2, const double lat2)
|
||||||
{
|
{
|
||||||
const auto p1(UtmCoordinate::fromGeographic(lon1, lat1));
|
const auto p1(UtmCoordinate::fromGeographic(lon1, lat1));
|
||||||
const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone));
|
const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone));
|
||||||
return squareDistance(p1, p2);
|
return squareDistance(p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double squareDistance(const UtmCoordinate& p1, const double lon2, const double lat2)
|
inline double squareDistance(const UtmCoordinate &p1, const double lon2, const double lat2)
|
||||||
{
|
{
|
||||||
const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone));
|
const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone));
|
||||||
return squareDistance(p1, p2);
|
return squareDistance(p1, p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double distance(const UtmCoordinate& p1, const UtmCoordinate& p2)
|
inline double distance(const UtmCoordinate &p1, const UtmCoordinate &p2)
|
||||||
{
|
{
|
||||||
if (p1.zone != p2.zone)
|
if (p1.zone != p2.zone)
|
||||||
{
|
{
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
return std::nan("");
|
return std::nan("");
|
||||||
}
|
}
|
||||||
return sqrt(squareDistance(p1, p2));
|
return sqrt(squareDistance(p1, p2));
|
||||||
}
|
}
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT double distance(const QPointF& p1, const QPointF& p2);
|
LTSCOORDTRANS_EXPORT double distance(const QPointF &p1, const QPointF &p2);
|
||||||
|
|
||||||
inline double distance(const double lon1, const double lat1, const double lon2, const double lat2)
|
inline double distance(const double lon1, const double lat1, const double lon2, const double lat2)
|
||||||
{
|
{
|
||||||
return sqrt(squareDistance(lon1, lat1, lon2, lat2));
|
return sqrt(squareDistance(lon1, lat1, lon2, lat2));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double distance(const UtmCoordinate& p1, const double lon2, const double lat2)
|
inline double distance(const UtmCoordinate &p1, const double lon2, const double lat2)
|
||||||
{
|
{
|
||||||
return sqrt(squareDistance(p1, lon2, lat2));
|
return sqrt(squareDistance(p1, lon2, lat2));
|
||||||
}
|
}
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT void dumpConversionCounter();
|
LTSCOORDTRANS_EXPORT void dumpConversionCounter();
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Forward();
|
LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Forward();
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Reverse();
|
LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Reverse();
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Forward();
|
LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Forward();
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Reverse();
|
LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Reverse();
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Forward();
|
LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Forward();
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Reverse();
|
LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Reverse();
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT std::ostream& operator<<(std::ostream& stream, const UtmCoordinate& coord);
|
LTSCOORDTRANS_EXPORT std::ostream &operator<<(std::ostream &stream, const UtmCoordinate &coord);
|
||||||
|
|
||||||
class LTSCOORDTRANS_EXPORT UtmCoordinate3D : public LtsCoordTrans::UtmCoordinate
|
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;
|
||||||
x = utm2d.x;
|
x = utm2d.x;
|
||||||
y = utm2d.y;
|
y = utm2d.y;
|
||||||
zValue = _zValue;
|
zValue = _zValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
zone = -1;
|
zone = -1;
|
||||||
northp = true;
|
northp = true;
|
||||||
|
|
||||||
x = 0.;
|
x = 0.;
|
||||||
y = 0.;
|
y = 0.;
|
||||||
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("")};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsCoordTrans
|
} // namespace LtsCoordTrans
|
||||||
+271
-257
@@ -13,7 +13,7 @@ QTEST_MAIN(coordtrans_test)
|
|||||||
|
|
||||||
void coordtrans_test::initTestCase()
|
void coordtrans_test::initTestCase()
|
||||||
{
|
{
|
||||||
qDebug("sizeof(UtmCoordinate) = %lu", sizeof(LtsCoordTrans::UtmCoordinate));
|
qDebug("sizeof(UtmCoordinate) = %lu", sizeof(LtsCoordTrans::UtmCoordinate));
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::cleanupTestCase() {}
|
void coordtrans_test::cleanupTestCase() {}
|
||||||
@@ -21,380 +21,394 @@ void coordtrans_test::cleanupTestCase() {}
|
|||||||
void coordtrans_test::testFromGeographic()
|
void coordtrans_test::testFromGeographic()
|
||||||
{
|
{
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate utm;
|
LtsCoordTrans::UtmCoordinate utm;
|
||||||
QPointF lonlat;
|
QPointF lonlat;
|
||||||
|
|
||||||
lonlat = QPointF(8.6264954126, 53.1138437183) * LtsCoordTrans::deg2rad();
|
lonlat = QPointF(8.6264954126, 53.1138437183) * LtsCoordTrans::deg2rad();
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("32U MD"));
|
QCOMPARE(utm.mgrs(0), QStringLiteral("32U MD"));
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
||||||
QCOMPARE(utm.mgrs(8), QStringLiteral("32U MD 74999999 84999999"));
|
QCOMPARE(utm.mgrs(8), QStringLiteral("32U MD 74999999 84999999"));
|
||||||
|
|
||||||
lonlat = QPointF(11.3003696521, 52.8224535191) * LtsCoordTrans::deg2rad();
|
lonlat = QPointF(11.3003696521, 52.8224535191) * LtsCoordTrans::deg2rad();
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("32U PD"));
|
QCOMPARE(utm.mgrs(0), QStringLiteral("32U PD"));
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
||||||
QCOMPARE(utm.mgrs(5), QStringLiteral("32U PD 55000 55000"));
|
QCOMPARE(utm.mgrs(5), QStringLiteral("32U PD 55000 55000"));
|
||||||
|
|
||||||
lonlat = QPointF(54.8821607021, 24.2631973752) * LtsCoordTrans::deg2rad();
|
lonlat = QPointF(54.8821607021, 24.2631973752) * LtsCoordTrans::deg2rad();
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("40R BM"));
|
QCOMPARE(utm.mgrs(0), QStringLiteral("40R BM"));
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
||||||
QCOMPARE(utm.mgrs(5), QStringLiteral("40R BM 85000 85000"));
|
QCOMPARE(utm.mgrs(5), QStringLiteral("40R BM 85000 85000"));
|
||||||
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("40R BM 00000 00000"));
|
utm = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("40R BM 00000 00000"));
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("40Q BM"));
|
QCOMPARE(utm.mgrs(0), QStringLiteral("40Q BM"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testMgrsFromGeographic()
|
void coordtrans_test::testMgrsFromGeographic()
|
||||||
{
|
{
|
||||||
|
|
||||||
QString mgrs;
|
QString mgrs;
|
||||||
QPointF lonlat;
|
QPointF lonlat;
|
||||||
|
|
||||||
lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
||||||
mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9);
|
mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9);
|
||||||
QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000"));
|
QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000"));
|
||||||
|
|
||||||
mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 8, false);
|
mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 8, false);
|
||||||
QCOMPARE(mgrs, QStringLiteral("32UMD7450000084000000"));
|
QCOMPARE(mgrs, QStringLiteral("32UMD7450000084000000"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testRelativeMetricalOffet_data()
|
void coordtrans_test::testRelativeMetricalOffet_data()
|
||||||
{
|
{
|
||||||
|
|
||||||
QTest::addColumn<QPoint>("offset");
|
QTest::addColumn<QPoint>("offset");
|
||||||
QTest::addColumn<QString>("correctMgrs");
|
QTest::addColumn<QString>("correctMgrs");
|
||||||
|
|
||||||
QTest::newRow("set 1") << QPoint(5, 5) << QStringLiteral("32U PD 99995 99995");
|
QTest::newRow("set 1") << QPoint(5, 5) << QStringLiteral("32U PD 99995 99995");
|
||||||
|
|
||||||
QTest::newRow("set 2") << QPoint(100, 100) << QStringLiteral("32U QE 00090 00090");
|
QTest::newRow("set 2") << QPoint(100, 100) << QStringLiteral("32U QE 00090 00090");
|
||||||
QTest::newRow("set 3") << QPoint(500, 500) << QStringLiteral("32U QE 00490 00490");
|
QTest::newRow("set 3") << QPoint(500, 500) << QStringLiteral("32U QE 00490 00490");
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testRelativeMetricalOffet()
|
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();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
LtsCoordTrans::UtmCoordinate utmRaw;
|
LtsCoordTrans::UtmCoordinate utmRaw;
|
||||||
utmRaw.x = utmRef.x + offset.x();
|
utmRaw.x = utmRef.x + offset.x();
|
||||||
utmRaw.y = utmRef.y + offset.y();
|
utmRaw.y = utmRef.y + offset.y();
|
||||||
utmRaw.zone = utmRef.zone;
|
utmRaw.zone = utmRef.zone;
|
||||||
qDebug() << "offset = " << offset << " - utmRaw = " << utmRaw.mgrs();
|
qDebug() << "offset = " << offset << " - utmRaw = " << utmRaw.mgrs();
|
||||||
|
|
||||||
QCOMPARE(utmRaw.mgrs(), correctMgrs);
|
QCOMPARE(utmRaw.mgrs(), correctMgrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const LtsCoordTrans::UtmCoordinate utmSimple(utmRef.zone, utmRef.x + offset.x(), utmRef.y + offset.y());
|
const LtsCoordTrans::UtmCoordinate utmSimple(utmRef.zone, utmRef.x + offset.x(), utmRef.y + offset.y());
|
||||||
|
|
||||||
qDebug() << "offset = " << offset << " - utmSimple = " << utmSimple.mgrs();
|
qDebug() << "offset = " << offset << " - utmSimple = " << utmSimple.mgrs();
|
||||||
QCOMPARE(utmSimple.mgrs(), correctMgrs);
|
QCOMPARE(utmSimple.mgrs(), correctMgrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF createArea(const QString& base, int xCenter, int yCenter, int width, int height)
|
QRectF createArea(const QString &base, int xCenter, int yCenter, int width, 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()));
|
|
||||||
|
|
||||||
QRectF rect(topLeft, bottomRight);
|
QRectF rect(topLeft, bottomRight);
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testAddMarginToArea()
|
void coordtrans_test::testAddMarginToArea()
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
qDebug() << "Altmark";
|
qDebug() << "Altmark";
|
||||||
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();
|
|
||||||
|
|
||||||
QVERIFY2(area1Increased.topLeft().x() < area.topLeft().x(), "addMarginToArea topLeft X failed");
|
QVERIFY2(area1Increased.topLeft().x() < area.topLeft().x(), "addMarginToArea topLeft X failed");
|
||||||
QVERIFY2(area1Increased.topLeft().y() < area.topLeft().y(), "addMarginToArea topLeft Y failed");
|
QVERIFY2(area1Increased.topLeft().y() < area.topLeft().y(), "addMarginToArea topLeft Y failed");
|
||||||
|
|
||||||
QVERIFY2(area1Increased.bottomRight().x() > area.bottomRight().x(), "addMarginToArea bottomRight X failed");
|
QVERIFY2(area1Increased.bottomRight().x() > area.bottomRight().x(), "addMarginToArea bottomRight X failed");
|
||||||
QVERIFY2(area1Increased.bottomRight().y() > area.bottomRight().y(), "addMarginToArea bottomRight Y failed");
|
QVERIFY2(area1Increased.bottomRight().y() > area.bottomRight().y(), "addMarginToArea bottomRight Y failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
qDebug() << "Luxemburg";
|
qDebug() << "Luxemburg";
|
||||||
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();
|
|
||||||
|
|
||||||
QVERIFY2(area1Increased.topLeft().x() < area.topLeft().x(), "addMarginToArea topLeft X failed");
|
QVERIFY2(area1Increased.topLeft().x() < area.topLeft().x(), "addMarginToArea topLeft X failed");
|
||||||
QVERIFY2(area1Increased.topLeft().y() < area.topLeft().y(), "addMarginToArea topLeft Y failed");
|
QVERIFY2(area1Increased.topLeft().y() < area.topLeft().y(), "addMarginToArea topLeft Y failed");
|
||||||
|
|
||||||
QVERIFY2(area1Increased.bottomRight().x() > area.bottomRight().x(), "addMarginToArea bottomRight X failed");
|
QVERIFY2(area1Increased.bottomRight().x() > area.bottomRight().x(), "addMarginToArea bottomRight X failed");
|
||||||
QVERIFY2(area1Increased.bottomRight().y() > area.bottomRight().y(), "addMarginToArea bottomRight Y failed");
|
QVERIFY2(area1Increased.bottomRight().y() > area.bottomRight().y(), "addMarginToArea bottomRight Y failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testIncreaseRect()
|
void coordtrans_test::testIncreaseRect()
|
||||||
{
|
{
|
||||||
|
|
||||||
QPointF lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
QPointF lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
||||||
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;
|
||||||
|
|
||||||
{
|
{
|
||||||
QPointF topLeftGeo = centerPoint.geographic(-1111, 2222);
|
QPointF topLeftGeo = centerPoint.geographic(-1111, 2222);
|
||||||
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) << bottomRightUtm.y;
|
||||||
qDebug() << "bottomRightUtm: " << bottomRightUtm.x << " - " << qSetRealNumberPrecision(15)
|
}
|
||||||
<< bottomRightUtm.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
topLeftUtm2.x = centerPoint.x - 1111;
|
topLeftUtm2.x = centerPoint.x - 1111;
|
||||||
topLeftUtm2.y = centerPoint.y + 2222;
|
topLeftUtm2.y = centerPoint.y + 2222;
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate bottomRightUtm2;
|
LtsCoordTrans::UtmCoordinate bottomRightUtm2;
|
||||||
bottomRightUtm2.x = centerPoint.x + 3000;
|
bottomRightUtm2.x = centerPoint.x + 3000;
|
||||||
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");
|
||||||
QVERIFY2(qFuzzyCompare(topLeftUtm.y, topLeftUtm2.y), "testIncreaseRect y failed");
|
QVERIFY2(qFuzzyCompare(topLeftUtm.y, topLeftUtm2.y), "testIncreaseRect y failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testIncreaseRect2()
|
void coordtrans_test::testIncreaseRect2()
|
||||||
{
|
{
|
||||||
|
|
||||||
QPointF lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
QPointF lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
||||||
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"));
|
||||||
|
|
||||||
QRectF myRect;
|
QRectF myRect;
|
||||||
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);
|
||||||
myRect = QRectF(topLeftGeo, bottomRightGeo).normalized();
|
myRect = QRectF(topLeftGeo, bottomRightGeo).normalized();
|
||||||
|
|
||||||
qDebug() << "myRect : " << myRect;
|
qDebug() << "myRect : " << myRect;
|
||||||
qDebug() << "myRect center : " << myRect.center();
|
qDebug() << "myRect center : " << myRect.center();
|
||||||
qDebug() << "myRect height : " << myRect.height();
|
qDebug() << "myRect height : " << myRect.height();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const QPointF centerGeo = myRect.center();
|
const QPointF centerGeo = myRect.center();
|
||||||
const LtsCoordTrans::UtmCoordinate centerUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(centerGeo);
|
const LtsCoordTrans::UtmCoordinate centerUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(centerGeo);
|
||||||
|
|
||||||
QPointF topLeftGeo = centerUtm.geographic(-6000, 4000);
|
QPointF topLeftGeo = centerUtm.geographic(-6000, 4000);
|
||||||
QPointF bottomRightGeo = centerUtm.geographic(6000, -4000);
|
QPointF bottomRightGeo = centerUtm.geographic(6000, -4000);
|
||||||
|
|
||||||
myRectIncreased = QRectF(topLeftGeo, bottomRightGeo).normalized();
|
myRectIncreased = QRectF(topLeftGeo, bottomRightGeo).normalized();
|
||||||
|
|
||||||
qDebug() << "myRectIncreased : " << myRectIncreased;
|
qDebug() << "myRectIncreased : " << myRectIncreased;
|
||||||
qDebug() << "myRectIncreased center: " << myRectIncreased.center();
|
qDebug() << "myRectIncreased center: " << myRectIncreased.center();
|
||||||
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testGeographicFromMgrs()
|
void coordtrans_test::testGeographicFromMgrs()
|
||||||
{
|
{
|
||||||
|
|
||||||
QString mgrs(QStringLiteral("32UPD7654398765"));
|
QString mgrs(QStringLiteral("32UPD7654398765"));
|
||||||
|
|
||||||
QPointF geographic = LtsCoordTrans::geographicFromMgrs(mgrs);
|
QPointF geographic = LtsCoordTrans::geographicFromMgrs(mgrs);
|
||||||
QCOMPARE(geographic, QPointF(11.6436815550, 53.2088411454) * LtsCoordTrans::deg2rad());
|
QCOMPARE(geographic, QPointF(11.6436815550, 53.2088411454) * LtsCoordTrans::deg2rad());
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
{QStringLiteral("32U MD"), QStringLiteral("32U ME"), QStringLiteral("32U ND"), QStringLiteral("32U NE")});
|
21000,
|
||||||
|
21000,
|
||||||
|
{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, {QStringLiteral("40R CN"), QStringLiteral("40R DN")});
|
||||||
checkArea(QStringLiteral("40R DN 0000000000"), 500, 95500, 12000, 7000,
|
checkArea(QStringLiteral("40R DN 0000000000"),
|
||||||
{QStringLiteral("40R CN"), QStringLiteral("40R DN")});
|
500,
|
||||||
checkArea(QStringLiteral("40R DN 0000000000"), 500, 96760, 30000, 30000,
|
96760,
|
||||||
{QStringLiteral("40R CN"), QStringLiteral("40R CP"), QStringLiteral("40R DN"), QStringLiteral("40R DP")});
|
30000,
|
||||||
checkArea(QStringLiteral("40R BM 0000000000"), 59000, 59500, 46000, 40000,
|
30000,
|
||||||
{QStringLiteral("40Q BM"), QStringLiteral("40R BM")});
|
{QStringLiteral("40R CN"), QStringLiteral("40R CP"), QStringLiteral("40R DN"), QStringLiteral("40R DP")});
|
||||||
|
checkArea(QStringLiteral("40R BM 0000000000"), 59000, 59500, 46000, 40000, {QStringLiteral("40Q BM"), QStringLiteral("40R BM")});
|
||||||
|
|
||||||
checkArea(QStringLiteral("32U LA 0000000000"), 10000, 10000, 5000, 5000,
|
checkArea(QStringLiteral("32U LA 0000000000"),
|
||||||
{
|
10000,
|
||||||
QStringLiteral("32U LA"),
|
10000,
|
||||||
});
|
5000,
|
||||||
|
5000,
|
||||||
|
{
|
||||||
|
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()));
|
|
||||||
|
|
||||||
const auto squares = LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), false, false);
|
const auto squares = LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), false, false);
|
||||||
|
|
||||||
QStringList src;
|
QStringList src;
|
||||||
src.reserve(squares.size());
|
src.reserve(squares.size());
|
||||||
for (const auto& utm : squares)
|
for (const auto &utm : squares)
|
||||||
src += utm.mgrs(0);
|
src += utm.mgrs(0);
|
||||||
src.sort();
|
src.sort();
|
||||||
|
|
||||||
return squares;
|
return squares;
|
||||||
}
|
}
|
||||||
|
|
||||||
void coordtrans_test::testMgrsSquaresWithSurrounding()
|
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");
|
||||||
|
|
||||||
QStringList string1;
|
QStringList string1;
|
||||||
string1.reserve(squares1.size());
|
string1.reserve(squares1.size());
|
||||||
for (const LtsCoordTrans::UtmCoordinate& item : std::as_const(squares1))
|
for (const LtsCoordTrans::UtmCoordinate &item : std::as_const(squares1))
|
||||||
string1.append(item.mgrs(0));
|
string1.append(item.mgrs(0));
|
||||||
|
|
||||||
QStringList string9;
|
QStringList string9;
|
||||||
string9.reserve(squares9.size());
|
string9.reserve(squares9.size());
|
||||||
for (const LtsCoordTrans::UtmCoordinate& item : std::as_const(squares9))
|
for (const LtsCoordTrans::UtmCoordinate &item : std::as_const(squares9))
|
||||||
string9.append(item.mgrs(0));
|
string9.append(item.mgrs(0));
|
||||||
|
|
||||||
QStringList string33;
|
QStringList string33;
|
||||||
string33.reserve(square33.size());
|
string33.reserve(square33.size());
|
||||||
for (const LtsCoordTrans::UtmCoordinate& item : std::as_const(square33))
|
for (const LtsCoordTrans::UtmCoordinate &item : std::as_const(square33))
|
||||||
string33.append(item.mgrs(0));
|
string33.append(item.mgrs(0));
|
||||||
|
|
||||||
{
|
{
|
||||||
QStringList surroundingStrings;
|
QStringList surroundingStrings;
|
||||||
surroundingStrings.reserve(squares9.size());
|
surroundingStrings.reserve(squares9.size());
|
||||||
for (const QString& str : std::as_const(string9))
|
for (const QString &str : std::as_const(string9))
|
||||||
if (!string1.contains(str))
|
if (!string1.contains(str))
|
||||||
surroundingStrings.append(str);
|
surroundingStrings.append(str);
|
||||||
|
|
||||||
QVERIFY2(surroundingStrings.size() == 8, "checkAreaGetMgrsSquares squaresDiff failed");
|
QVERIFY2(surroundingStrings.size() == 8, "checkAreaGetMgrsSquares squaresDiff failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
QStringList surroundingStrings;
|
QStringList surroundingStrings;
|
||||||
surroundingStrings.reserve(string33.size());
|
surroundingStrings.reserve(string33.size());
|
||||||
for (const QString& str : std::as_const(string33))
|
for (const QString &str : std::as_const(string33))
|
||||||
if (!string1.contains(str))
|
if (!string1.contains(str))
|
||||||
surroundingStrings.append(str);
|
surroundingStrings.append(str);
|
||||||
|
|
||||||
QVERIFY2(surroundingStrings.size() == 32, "checkAreaGetMgrsSquares squaresDiff failed");
|
QVERIFY2(surroundingStrings.size() == 32, "checkAreaGetMgrsSquares squaresDiff failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
qDebug() << "BottomRight: " << bottomRight * LtsCoordTrans::rad2deg();
|
||||||
qDebug() << "BottomRight: " << bottomRight * LtsCoordTrans::rad2deg();
|
|
||||||
|
|
||||||
const auto squares = LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), false, false);
|
const auto squares = LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), false, false);
|
||||||
|
|
||||||
QStringList src;
|
QStringList src;
|
||||||
src.reserve(squares.size());
|
src.reserve(squares.size());
|
||||||
for (const auto& utm : squares)
|
for (const auto &utm : squares)
|
||||||
src += utm.mgrs(0);
|
src += utm.mgrs(0);
|
||||||
src.sort();
|
src.sort();
|
||||||
qDebug() << "src: '" << src << "' expected: '" << coords << "'";
|
qDebug() << "src: '" << src << "' expected: '" << coords << "'";
|
||||||
QCOMPARE(src, coords);
|
QCOMPARE(src, coords);
|
||||||
}
|
}
|
||||||
+16
-16
@@ -7,25 +7,25 @@
|
|||||||
|
|
||||||
class coordtrans_test : public QObject
|
class coordtrans_test : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
void cleanupTestCase();
|
void cleanupTestCase();
|
||||||
void testFromGeographic();
|
void testFromGeographic();
|
||||||
void testMgrsFromGeographic();
|
void testMgrsFromGeographic();
|
||||||
|
|
||||||
void testRelativeMetricalOffet_data();
|
void testRelativeMetricalOffet_data();
|
||||||
void testRelativeMetricalOffet();
|
void testRelativeMetricalOffet();
|
||||||
|
|
||||||
void testAddMarginToArea();
|
void testAddMarginToArea();
|
||||||
void testIncreaseRect();
|
void testIncreaseRect();
|
||||||
void testIncreaseRect2();
|
void testIncreaseRect2();
|
||||||
|
|
||||||
void testGeographicFromMgrs();
|
void testGeographicFromMgrs();
|
||||||
void testMgrsSquares();
|
void testMgrsSquares();
|
||||||
|
|
||||||
void testMgrsSquaresWithSurrounding();
|
void testMgrsSquaresWithSurrounding();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkArea(const QString& base, int xCenter, int yCenter, int width, int height, const QStringList& coords);
|
void checkArea(const QString &base, int xCenter, int yCenter, int width, int height, const QStringList &coords);
|
||||||
};
|
};
|
||||||
@@ -10,178 +10,177 @@
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setCoordinate(const QPointF& geoCoord, bool bUseAsDefaultValue)
|
void LtsCoordWidget::setCoordinate(const QPointF &geoCoord, bool bUseAsDefaultValue)
|
||||||
{
|
{
|
||||||
if (m_coordinate != geoCoord)
|
if (m_coordinate != geoCoord)
|
||||||
emit coordinateChanged(geoCoord);
|
emit coordinateChanged(geoCoord);
|
||||||
if (bUseAsDefaultValue)
|
if (bUseAsDefaultValue)
|
||||||
m_defaultCoordinate = geoCoord;
|
m_defaultCoordinate = geoCoord;
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
m_inputWidgetHandler->setCoordinate(geoCoord);
|
m_inputWidgetHandler->setCoordinate(geoCoord);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::clear()
|
void LtsCoordWidget::clear()
|
||||||
{
|
{
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
m_inputWidgetHandler->clear();
|
m_inputWidgetHandler->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setCoordinate(double lon, double lat, bool bUseAsDefaultValue)
|
void LtsCoordWidget::setCoordinate(double lon, double lat, bool bUseAsDefaultValue)
|
||||||
{
|
{
|
||||||
setCoordinate(QPointF(lon, lat), bUseAsDefaultValue);
|
setCoordinate(QPointF(lon, lat), bUseAsDefaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF LtsCoordWidget::coordinate() const
|
QPointF LtsCoordWidget::coordinate() const
|
||||||
{
|
{
|
||||||
if (!m_inputWidgetHandler)
|
if (!m_inputWidgetHandler)
|
||||||
return QPointF();
|
return QPointF();
|
||||||
return m_inputWidgetHandler->coordinate();
|
return m_inputWidgetHandler->coordinate();
|
||||||
}
|
}
|
||||||
|
|
||||||
LtsCoordWidget::DisplayType LtsCoordWidget::displayType() const
|
LtsCoordWidget::DisplayType LtsCoordWidget::displayType() const
|
||||||
{
|
{
|
||||||
return m_displayType;
|
return m_displayType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setDisplayType(LtsCoordWidget::DisplayType dt)
|
void LtsCoordWidget::setDisplayType(LtsCoordWidget::DisplayType dt)
|
||||||
{
|
{
|
||||||
if (m_displayType == dt)
|
if (m_displayType == dt)
|
||||||
return;
|
return;
|
||||||
m_displayType = dt;
|
m_displayType = dt;
|
||||||
rebuildUi();
|
rebuildUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCoordWidget::withResetButton() const
|
bool LtsCoordWidget::withResetButton() const
|
||||||
{
|
{
|
||||||
return m_bWithResetButton;
|
return m_bWithResetButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setWithResetButton(bool bWith)
|
void LtsCoordWidget::setWithResetButton(bool bWith)
|
||||||
{
|
{
|
||||||
if (m_bWithResetButton == bWith)
|
if (m_bWithResetButton == bWith)
|
||||||
return;
|
return;
|
||||||
m_bWithResetButton = bWith;
|
m_bWithResetButton = bWith;
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
m_inputWidgetHandler->resetButton()->setVisible(m_bWithResetButton);
|
m_inputWidgetHandler->resetButton()->setVisible(m_bWithResetButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCoordWidget::showToolTip() const
|
bool LtsCoordWidget::showToolTip() const
|
||||||
{
|
{
|
||||||
return m_bShowToolTip;
|
return m_bShowToolTip;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setShowToolTip(bool bShow)
|
void LtsCoordWidget::setShowToolTip(bool bShow)
|
||||||
{
|
{
|
||||||
if (m_bShowToolTip == bShow)
|
if (m_bShowToolTip == bShow)
|
||||||
return;
|
return;
|
||||||
m_bShowToolTip = bShow;
|
m_bShowToolTip = bShow;
|
||||||
|
|
||||||
updateToolTip();
|
updateToolTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCoordWidget::mgrsSquareEditable() const
|
bool LtsCoordWidget::mgrsSquareEditable() const
|
||||||
{
|
{
|
||||||
return m_bMgrsSquareEditable;
|
return m_bMgrsSquareEditable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setMgrsSquareEditable(bool bEditable)
|
void LtsCoordWidget::setMgrsSquareEditable(bool bEditable)
|
||||||
{
|
{
|
||||||
if (m_bMgrsSquareEditable == bEditable)
|
if (m_bMgrsSquareEditable == bEditable)
|
||||||
return;
|
return;
|
||||||
m_bMgrsSquareEditable = bEditable;
|
m_bMgrsSquareEditable = bEditable;
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
m_inputWidgetHandler->setSquaresEditable(bEditable);
|
m_inputWidgetHandler->setSquaresEditable(bEditable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setWithSurroundingMgrsSquares(bool bEnable)
|
void LtsCoordWidget::setWithSurroundingMgrsSquares(bool bEnable)
|
||||||
{
|
{
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
m_inputWidgetHandler->setWithSurroundingSquare(bEnable);
|
m_inputWidgetHandler->setWithSurroundingSquare(bEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords)
|
void LtsCoordWidget::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords)
|
||||||
{
|
{
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
m_inputWidgetHandler->setMgrsSquares(geoCoords);
|
m_inputWidgetHandler->setMgrsSquares(geoCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LtsCoordWidget::event(QEvent* event)
|
bool LtsCoordWidget::event(QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::ToolTip)
|
if (event->type() == QEvent::ToolTip)
|
||||||
updateToolTip();
|
updateToolTip();
|
||||||
return QWidget::event(event);
|
return QWidget::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::rebuildUi()
|
void LtsCoordWidget::rebuildUi()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_inputWidgetHandler)
|
if (m_inputWidgetHandler)
|
||||||
{
|
{
|
||||||
m_inputWidgetHandler->cleanup();
|
m_inputWidgetHandler->cleanup();
|
||||||
delete m_inputWidgetHandler;
|
delete m_inputWidgetHandler;
|
||||||
delete layout();
|
delete layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_displayType)
|
switch (m_displayType)
|
||||||
{
|
{
|
||||||
case DisplayType::MGRS5:
|
case DisplayType::MGRS5:
|
||||||
m_inputWidgetHandler = new MgrsEdit(5, this);
|
m_inputWidgetHandler = new MgrsEdit(5, this);
|
||||||
break;
|
break;
|
||||||
case DisplayType::MGRS7:
|
case DisplayType::MGRS7:
|
||||||
m_inputWidgetHandler = new MgrsEdit(7, this);
|
m_inputWidgetHandler = new MgrsEdit(7, this);
|
||||||
break;
|
break;
|
||||||
case DisplayType::UTM:
|
case DisplayType::UTM:
|
||||||
|
|
||||||
qt_assert("DisplayType::UTM not yet implemented", __FILE__, __LINE__);
|
qt_assert("DisplayType::UTM not yet implemented", __FILE__, __LINE__);
|
||||||
break;
|
break;
|
||||||
case DisplayType::WGS84:
|
case DisplayType::WGS84:
|
||||||
m_inputWidgetHandler = new Wgs84Edit(this);
|
m_inputWidgetHandler = new Wgs84Edit(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!m_inputWidgetHandler)
|
if (!m_inputWidgetHandler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::updateToolTip()
|
void LtsCoordWidget::updateToolTip()
|
||||||
{
|
{
|
||||||
QString tt;
|
QString tt;
|
||||||
if (m_bShowToolTip)
|
if (m_bShowToolTip)
|
||||||
{
|
{
|
||||||
const QPointF p(coordinate());
|
const QPointF p(coordinate());
|
||||||
if (!p.isNull())
|
if (!p.isNull())
|
||||||
{
|
{
|
||||||
const QString mgrs = LtsCoordTrans::mgrsFromGeographic(p.x(), p.y());
|
const QString mgrs = LtsCoordTrans::mgrsFromGeographic(p.x(), p.y());
|
||||||
const QPointF p2(p * LtsCoordTrans::rad2deg());
|
const QPointF p2(p * LtsCoordTrans::rad2deg());
|
||||||
tt = tr("MGRS: %1\nlat/lon: %2/%3").arg(mgrs).arg(p2.y(), 0, 'f', 10).arg(p2.x(), 0, 'f', 10);
|
tt = tr("MGRS: %1\nlat/lon: %2/%3").arg(mgrs).arg(p2.y(), 0, 'f', 10).arg(p2.x(), 0, 'f', 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setToolTip(tt);
|
setToolTip(tt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsCoordWidget::onResetToDefaultCoordinate()
|
void LtsCoordWidget::onResetToDefaultCoordinate()
|
||||||
{
|
{
|
||||||
if (!m_inputWidgetHandler)
|
if (!m_inputWidgetHandler)
|
||||||
return;
|
return;
|
||||||
if (m_defaultCoordinate.isNull())
|
if (m_defaultCoordinate.isNull())
|
||||||
m_inputWidgetHandler->clear();
|
m_inputWidgetHandler->clear();
|
||||||
m_inputWidgetHandler->setCoordinate(m_defaultCoordinate);
|
m_inputWidgetHandler->setCoordinate(m_defaultCoordinate);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsCoordWidget
|
} // namespace LtsCoordWidget
|
||||||
@@ -10,43 +10,53 @@ class QToolButton;
|
|||||||
|
|
||||||
namespace LtsCoordWidget
|
namespace LtsCoordWidget
|
||||||
{
|
{
|
||||||
class LtsCoordInputWidgetHandler;
|
class LtsCoordInputWidgetHandler;
|
||||||
|
|
||||||
class LTSCOORDWIDGET_EXPORT LtsCoordWidget : public QWidget
|
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);
|
||||||
|
|
||||||
QPointF coordinate() const;
|
QPointF coordinate() const;
|
||||||
DisplayType displayType() const;
|
DisplayType displayType() const;
|
||||||
bool withResetButton() const;
|
bool withResetButton() const;
|
||||||
bool showToolTip() const;
|
bool showToolTip() const;
|
||||||
bool mgrsSquareEditable() const;
|
bool mgrsSquareEditable() const;
|
||||||
bool event(QEvent* event) override;
|
bool event(QEvent *event) override;
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
|
||||||
void setCoordinate(const QPointF& geoCoord, bool bUseAsDefaultValue = true);
|
void setCoordinate(const QPointF &geoCoord, bool bUseAsDefaultValue = true);
|
||||||
void setCoordinate(double lon, double lat, bool bUseAsDefaultValue = true);
|
void setCoordinate(double lon, double lat, bool bUseAsDefaultValue = true);
|
||||||
void setDisplayType(LtsCoordWidget::DisplayType dt);
|
void setDisplayType(LtsCoordWidget::DisplayType dt);
|
||||||
void setWithResetButton(bool bWith);
|
void setWithResetButton(bool bWith);
|
||||||
void setShowToolTip(bool bShow);
|
void setShowToolTip(bool bShow);
|
||||||
void setMgrsSquareEditable(bool bEditable);
|
void setMgrsSquareEditable(bool bEditable);
|
||||||
void setWithSurroundingMgrsSquares(bool bEnable);
|
void setWithSurroundingMgrsSquares(bool bEnable);
|
||||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords);
|
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void coordinateChanged(const QPointF& newGeoCoord);
|
void coordinateChanged(const QPointF &newGeoCoord);
|
||||||
void invalidCoordinate();
|
void invalidCoordinate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -60,8 +70,8 @@ class LTSCOORDWIDGET_EXPORT LtsCoordWidget : public QWidget
|
|||||||
bool m_bShowToolTip = true;
|
bool m_bShowToolTip = true;
|
||||||
bool m_bMgrsSquareEditable = false;
|
bool m_bMgrsSquareEditable = false;
|
||||||
LtsCoordWidget::DisplayType m_displayType = LtsCoordWidget::DisplayType::MGRS;
|
LtsCoordWidget::DisplayType m_displayType = LtsCoordWidget::DisplayType::MGRS;
|
||||||
LtsCoordInputWidgetHandler* m_inputWidgetHandler = nullptr;
|
LtsCoordInputWidgetHandler *m_inputWidgetHandler = nullptr;
|
||||||
QPointF m_coordinate;
|
QPointF m_coordinate;
|
||||||
QPointF m_defaultCoordinate;
|
QPointF m_defaultCoordinate;
|
||||||
};
|
};
|
||||||
} // namespace LtsCoordWidget
|
} // namespace LtsCoordWidget
|
||||||
@@ -7,70 +7,71 @@
|
|||||||
namespace LtsCoordWidget
|
namespace LtsCoordWidget
|
||||||
{
|
{
|
||||||
|
|
||||||
void LtsCoordInputWidgetHandler::onCoordinateDataChanged()
|
void LtsCoordInputWidgetHandler::onCoordinateDataChanged()
|
||||||
{
|
{
|
||||||
const QPointF coord(coordinate());
|
const QPointF coord(coordinate());
|
||||||
if (coord.isNull())
|
if (coord.isNull())
|
||||||
{
|
{
|
||||||
emit invalidCoordinate();
|
emit invalidCoordinate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
emit coordinateChanged(coord);
|
emit coordinateChanged(coord);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if (m_precision < 0)
|
if (m_precision < 0)
|
||||||
m_precision = 0;
|
m_precision = 0;
|
||||||
if (m_precision > 11)
|
if (m_precision > 11)
|
||||||
m_precision = 11;
|
m_precision = 11;
|
||||||
const int upperLimit = pow(10, m_precision) - 1;
|
const int upperLimit = pow(10, m_precision) - 1;
|
||||||
m_ui->leEast->setValidator(new QIntValidator(0, upperLimit, m_ui->leEast));
|
m_ui->leEast->setValidator(new QIntValidator(0, upperLimit, m_ui->leEast));
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
MgrsEdit::~MgrsEdit()
|
MgrsEdit::~MgrsEdit()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MgrsEdit::isValid()
|
bool MgrsEdit::isValid()
|
||||||
{
|
{
|
||||||
|
|
||||||
const QString& east = m_ui->leEast->text();
|
const QString &east = m_ui->leEast->text();
|
||||||
if (east.size() != m_precision)
|
if (east.size() != m_precision)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const QString& north = m_ui->leNorth->text();
|
const QString &north = m_ui->leNorth->text();
|
||||||
if (north.size() != m_precision)
|
if (north.size() != m_precision)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_ui->cbxZone->currentIndex() < 0)
|
if (m_ui->cbxZone->currentIndex() < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_ui->cbxZone->currentText().isEmpty())
|
if (m_ui->cbxZone->currentText().isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::setCoordinate(const QPointF& geoCoord)
|
void MgrsEdit::setCoordinate(const QPointF &geoCoord)
|
||||||
{
|
{
|
||||||
const QString mgrsString = LtsCoordTrans::mgrsFromGeographic(geoCoord.x(), geoCoord.y(), m_precision, false);
|
const QString mgrsString = LtsCoordTrans::mgrsFromGeographic(geoCoord.x(), geoCoord.y(), m_precision, false);
|
||||||
if (mgrsString.isEmpty())
|
if (mgrsString.isEmpty())
|
||||||
{
|
{
|
||||||
m_ui->leEast->clear();
|
m_ui->leEast->clear();
|
||||||
m_ui->leNorth->clear();
|
m_ui->leNorth->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->leEast->setText(QString());
|
m_ui->leEast->setText(QString());
|
||||||
@@ -82,135 +83,137 @@ void MgrsEdit::setCoordinate(const QPointF& geoCoord)
|
|||||||
int idx = m_ui->cbxZone->findText(mgrsSquare);
|
int idx = m_ui->cbxZone->findText(mgrsSquare);
|
||||||
if (idx < 0)
|
if (idx < 0)
|
||||||
{
|
{
|
||||||
addMgrsSquare(mgrsSquare);
|
addMgrsSquare(mgrsSquare);
|
||||||
idx = m_ui->cbxZone->findText(mgrsSquare);
|
idx = m_ui->cbxZone->findText(mgrsSquare);
|
||||||
}
|
}
|
||||||
m_ui->cbxZone->setCurrentIndex(idx);
|
m_ui->cbxZone->setCurrentIndex(idx);
|
||||||
m_ui->leEast->setText(east);
|
m_ui->leEast->setText(east);
|
||||||
m_ui->leNorth->setText(north);
|
m_ui->leNorth->setText(north);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString getMgrsCoord(QLineEdit* le, int prec)
|
static inline QString getMgrsCoord(QLineEdit *le, int prec)
|
||||||
{
|
{
|
||||||
QString ret = le->text();
|
QString ret = le->text();
|
||||||
if (ret.isEmpty())
|
if (ret.isEmpty())
|
||||||
return ret;
|
return ret;
|
||||||
while (ret.size() < prec)
|
while (ret.size() < prec)
|
||||||
ret += QLatin1Char('0');
|
ret += QLatin1Char('0');
|
||||||
le->setText(ret);
|
le->setText(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF MgrsEdit::coordinate() const
|
QPointF MgrsEdit::coordinate() const
|
||||||
{
|
{
|
||||||
const QString east = getMgrsCoord(m_ui->leEast, m_precision);
|
const QString east = getMgrsCoord(m_ui->leEast, m_precision);
|
||||||
const QString north = getMgrsCoord(m_ui->leNorth, m_precision);
|
const QString north = getMgrsCoord(m_ui->leNorth, m_precision);
|
||||||
if (east.isEmpty() || north.isEmpty() || m_ui->cbxZone->currentIndex() < 0)
|
if (east.isEmpty() || north.isEmpty() || m_ui->cbxZone->currentIndex() < 0)
|
||||||
return QPointF();
|
return QPointF();
|
||||||
|
|
||||||
const QString mgrsString(m_ui->cbxZone->currentText() + east + north);
|
const QString mgrsString(m_ui->cbxZone->currentText() + east + north);
|
||||||
return LtsCoordTrans::geographicFromMgrs(mgrsString);
|
return LtsCoordTrans::geographicFromMgrs(mgrsString);
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolButton* MgrsEdit::resetButton()
|
QToolButton *MgrsEdit::resetButton()
|
||||||
{
|
{
|
||||||
return m_ui->tbReset;
|
return m_ui->tbReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::cleanup()
|
void MgrsEdit::cleanup()
|
||||||
{
|
{
|
||||||
|
|
||||||
delete m_ui->horizontalLayout;
|
delete m_ui->horizontalLayout;
|
||||||
delete m_ui->cbxZone;
|
delete m_ui->cbxZone;
|
||||||
delete m_ui->leEast;
|
delete m_ui->leEast;
|
||||||
delete m_ui->leNorth;
|
delete m_ui->leNorth;
|
||||||
delete m_ui->tbReset;
|
delete m_ui->tbReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::clear()
|
void MgrsEdit::clear()
|
||||||
{
|
{
|
||||||
m_ui->cbxZone->clear();
|
m_ui->cbxZone->clear();
|
||||||
m_ui->leEast->clear();
|
m_ui->leEast->clear();
|
||||||
m_ui->leNorth->clear();
|
m_ui->leNorth->clear();
|
||||||
setDefaultMgrsSquares();
|
setDefaultMgrsSquares();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::setSquaresEditable(bool bEditable)
|
void MgrsEdit::setSquaresEditable(bool bEditable)
|
||||||
{
|
{
|
||||||
m_ui->cbxZone->setEditable(bEditable);
|
m_ui->cbxZone->setEditable(bEditable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::setWithSurroundingSquare(bool bEnabled)
|
void MgrsEdit::setWithSurroundingSquare(bool bEnabled)
|
||||||
{
|
{
|
||||||
m_withMgrsSquareOffset = bEnabled;
|
m_withMgrsSquareOffset = bEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStringList defaultMgrsSquares()
|
static QStringList defaultMgrsSquares()
|
||||||
{
|
{
|
||||||
const QVector<LtsCoordTrans::UtmCoordinate> squares(LtsCoordTrans::defaultMgrsSquares());
|
const QVector<LtsCoordTrans::UtmCoordinate> squares(LtsCoordTrans::defaultMgrsSquares());
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
sl.reserve(squares.size());
|
sl.reserve(squares.size());
|
||||||
for (const LtsCoordTrans::UtmCoordinate& c : squares)
|
for (const LtsCoordTrans::UtmCoordinate &c : squares)
|
||||||
sl += c.mgrs(0);
|
sl += c.mgrs(0);
|
||||||
std::sort(sl.begin(), sl.end());
|
std::sort(sl.begin(), sl.end());
|
||||||
return sl;
|
return sl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString preferedMgrsSquare()
|
static QString preferedMgrsSquare()
|
||||||
{
|
{
|
||||||
const LtsCoordTrans::UtmCoordinate c(LtsCoordTrans::preferedMgrsSquare());
|
const LtsCoordTrans::UtmCoordinate c(LtsCoordTrans::preferedMgrsSquare());
|
||||||
return c.mgrs(0);
|
return c.mgrs(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::setDefaultMgrsSquares()
|
void MgrsEdit::setDefaultMgrsSquares()
|
||||||
{
|
{
|
||||||
m_ui->cbxZone->addItems(defaultMgrsSquares());
|
m_ui->cbxZone->addItems(defaultMgrsSquares());
|
||||||
m_ui->cbxZone->setCurrentIndex(m_ui->cbxZone->findText(preferedMgrsSquare()));
|
m_ui->cbxZone->setCurrentIndex(m_ui->cbxZone->findText(preferedMgrsSquare()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::addMgrsSquare(const QString& newMgrsSquare)
|
void MgrsEdit::addMgrsSquare(const QString &newMgrsSquare)
|
||||||
{
|
{
|
||||||
QStringList sl = defaultMgrsSquares();
|
QStringList sl = defaultMgrsSquares();
|
||||||
sl += newMgrsSquare;
|
sl += newMgrsSquare;
|
||||||
if (m_withMgrsSquareOffset)
|
if (m_withMgrsSquareOffset)
|
||||||
{
|
{
|
||||||
QStringList squares = utmCoordsToList(LtsCoordTrans::defaultMgrsSquareWithOffsets());
|
QStringList squares = utmCoordsToList(LtsCoordTrans::defaultMgrsSquareWithOffsets());
|
||||||
|
|
||||||
for (const auto& sq : std::as_const(squares))
|
for (const auto &sq : std::as_const(squares))
|
||||||
if (!sl.contains(sq))
|
if (!sl.contains(sq))
|
||||||
sl.append(sq);
|
sl.append(sq);
|
||||||
}
|
}
|
||||||
std::sort(sl.begin(), sl.end());
|
std::sort(sl.begin(), sl.end());
|
||||||
m_ui->cbxZone->clear();
|
m_ui->cbxZone->clear();
|
||||||
m_ui->cbxZone->addItems(sl);
|
m_ui->cbxZone->addItems(sl);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList MgrsEdit::utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate>& coords)
|
QStringList MgrsEdit::utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate> &coords)
|
||||||
{
|
{
|
||||||
QStringList list;
|
QStringList list;
|
||||||
list.reserve(coords.count());
|
list.reserve(coords.count());
|
||||||
for (const auto& utm : coords)
|
for (const auto &utm : coords)
|
||||||
list.append(utm.mgrs(0));
|
list.append(utm.mgrs(0));
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MgrsEdit::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords)
|
void MgrsEdit::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords)
|
||||||
{
|
{
|
||||||
QStringList sl = utmCoordsToList(geoCoords);
|
QStringList sl = utmCoordsToList(geoCoords);
|
||||||
if (sl.isEmpty())
|
if (sl.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::sort(sl.begin(), sl.end());
|
std::sort(sl.begin(), sl.end());
|
||||||
m_ui->cbxZone->clear();
|
m_ui->cbxZone->clear();
|
||||||
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);
|
||||||
|
|
||||||
DoubleValidator* v = new DoubleValidator(-180, 180, 9, m_ui->leLon);
|
DoubleValidator *v = new DoubleValidator(-180, 180, 9, m_ui->leLon);
|
||||||
v->setNotation(QDoubleValidator::StandardNotation);
|
v->setNotation(QDoubleValidator::StandardNotation);
|
||||||
m_ui->leLon->setValidator(v);
|
m_ui->leLon->setValidator(v);
|
||||||
|
|
||||||
@@ -220,50 +223,50 @@ Wgs84Edit::Wgs84Edit(QWidget* widget) : LtsCoordInputWidgetHandler(widget), m_ui
|
|||||||
|
|
||||||
connect(m_ui->leLon, &QLineEdit::editingFinished, this, &Wgs84Edit::onCoordinateDataChanged);
|
connect(m_ui->leLon, &QLineEdit::editingFinished, this, &Wgs84Edit::onCoordinateDataChanged);
|
||||||
connect(m_ui->leLat, &QLineEdit::editingFinished, this, &Wgs84Edit::onCoordinateDataChanged);
|
connect(m_ui->leLat, &QLineEdit::editingFinished, this, &Wgs84Edit::onCoordinateDataChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
Wgs84Edit::~Wgs84Edit()
|
Wgs84Edit::~Wgs84Edit()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Wgs84Edit::isValid()
|
bool Wgs84Edit::isValid()
|
||||||
{
|
{
|
||||||
|
|
||||||
return (!m_ui->leLon->text().isEmpty()) && (!m_ui->leLat->text().isEmpty());
|
return (!m_ui->leLon->text().isEmpty()) && (!m_ui->leLat->text().isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wgs84Edit::setCoordinate(const QPointF& geoCoord)
|
void Wgs84Edit::setCoordinate(const QPointF &geoCoord)
|
||||||
{
|
{
|
||||||
const QPointF coord(geoCoord * LtsCoordTrans::rad2deg());
|
const QPointF coord(geoCoord * LtsCoordTrans::rad2deg());
|
||||||
const QLocale l;
|
const QLocale l;
|
||||||
m_ui->leLon->setText(l.toString(coord.x(), 'f', 9));
|
m_ui->leLon->setText(l.toString(coord.x(), 'f', 9));
|
||||||
m_ui->leLat->setText(l.toString(coord.y(), 'f', 9));
|
m_ui->leLat->setText(l.toString(coord.y(), 'f', 9));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF Wgs84Edit::coordinate() const
|
QPointF Wgs84Edit::coordinate() const
|
||||||
{
|
{
|
||||||
QPointF ret;
|
QPointF ret;
|
||||||
const QLocale l;
|
const QLocale l;
|
||||||
|
|
||||||
const QString lonStr = m_ui->leLon->text().remove(l.groupSeparator());
|
const QString lonStr = m_ui->leLon->text().remove(l.groupSeparator());
|
||||||
const QString latStr = m_ui->leLat->text().remove(l.groupSeparator());
|
const QString latStr = m_ui->leLat->text().remove(l.groupSeparator());
|
||||||
if (lonStr.isEmpty() || latStr.isEmpty())
|
if (lonStr.isEmpty() || latStr.isEmpty())
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret.rx() = l.toDouble(lonStr);
|
ret.rx() = l.toDouble(lonStr);
|
||||||
ret.ry() = l.toDouble(latStr);
|
ret.ry() = l.toDouble(latStr);
|
||||||
|
|
||||||
return ret * LtsCoordTrans::deg2rad();
|
return ret * LtsCoordTrans::deg2rad();
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolButton* Wgs84Edit::resetButton()
|
QToolButton *Wgs84Edit::resetButton()
|
||||||
{
|
{
|
||||||
return m_ui->tbReset;
|
return m_ui->tbReset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wgs84Edit::cleanup()
|
void Wgs84Edit::cleanup()
|
||||||
{
|
{
|
||||||
|
|
||||||
delete m_ui->horizontalLayout;
|
delete m_ui->horizontalLayout;
|
||||||
delete m_ui->leLon;
|
delete m_ui->leLon;
|
||||||
@@ -271,31 +274,31 @@ void Wgs84Edit::cleanup()
|
|||||||
delete m_ui->tbReset;
|
delete m_ui->tbReset;
|
||||||
delete m_ui->lblLon;
|
delete m_ui->lblLon;
|
||||||
delete m_ui->lblLat;
|
delete m_ui->lblLat;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wgs84Edit::clear()
|
void Wgs84Edit::clear()
|
||||||
{
|
{
|
||||||
m_ui->leLon->clear();
|
m_ui->leLon->clear();
|
||||||
m_ui->leLat->clear();
|
m_ui->leLat->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
DoubleValidator::DoubleValidator(double bottom, double top, int decimals, QObject* parent)
|
DoubleValidator::DoubleValidator(double bottom, double top, int decimals, QObject *parent)
|
||||||
: QDoubleValidator(bottom, top, decimals, parent)
|
: QDoubleValidator(bottom, top, decimals, parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QValidator::State DoubleValidator::validate(QString& input, int& pos) const
|
QValidator::State DoubleValidator::validate(QString &input, int &pos) const
|
||||||
{
|
{
|
||||||
const QValidator::State ret = QDoubleValidator::validate(input, pos);
|
const QValidator::State ret = QDoubleValidator::validate(input, pos);
|
||||||
if (ret != QValidator::Acceptable)
|
if (ret != QValidator::Acceptable)
|
||||||
return ret;
|
return ret;
|
||||||
QLocale l;
|
QLocale l;
|
||||||
const QChar gs = l.groupSeparator().at(0);
|
const QChar gs = l.groupSeparator().at(0);
|
||||||
if (gs.isNull())
|
if (gs.isNull())
|
||||||
return ret;
|
return ret;
|
||||||
if (input.contains(gs))
|
if (input.contains(gs))
|
||||||
return QValidator::Invalid;
|
return QValidator::Invalid;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsCoordWidget
|
} // namespace LtsCoordWidget
|
||||||
@@ -13,95 +13,89 @@
|
|||||||
|
|
||||||
namespace LtsCoordWidget
|
namespace LtsCoordWidget
|
||||||
{
|
{
|
||||||
class LtsCoordInputWidgetHandler : public QObject
|
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;
|
||||||
virtual QPointF coordinate() const = 0;
|
virtual QPointF coordinate() const = 0;
|
||||||
virtual QToolButton* resetButton() = 0;
|
virtual QToolButton *resetButton() = 0;
|
||||||
virtual void cleanup() = 0;
|
virtual void cleanup() = 0;
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
virtual void setSquaresEditable(bool bEditable) = 0;
|
virtual void setSquaresEditable(bool bEditable) = 0;
|
||||||
virtual void setWithSurroundingSquare(bool bEnabled) = 0;
|
virtual void setWithSurroundingSquare(bool bEnabled) = 0;
|
||||||
virtual void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords) = 0;
|
virtual void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords) = 0;
|
||||||
protected Q_SLOTS:
|
protected Q_SLOTS:
|
||||||
void onCoordinateDataChanged();
|
void onCoordinateDataChanged();
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void coordinateChanged(const QPointF& newGeoCoord);
|
void coordinateChanged(const QPointF &newGeoCoord);
|
||||||
void invalidCoordinate();
|
void invalidCoordinate();
|
||||||
};
|
};
|
||||||
|
|
||||||
class MgrsEdit final : public LtsCoordInputWidgetHandler
|
class MgrsEdit final : public LtsCoordInputWidgetHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit MgrsEdit(int precision, QWidget* widget);
|
explicit MgrsEdit(int precision, QWidget *widget);
|
||||||
~MgrsEdit();
|
~MgrsEdit();
|
||||||
|
|
||||||
bool isValid() override;
|
bool isValid() override;
|
||||||
void setCoordinate(const QPointF& geoCoord) override;
|
void setCoordinate(const QPointF &geoCoord) override;
|
||||||
QPointF coordinate() const override;
|
QPointF coordinate() const override;
|
||||||
QToolButton* resetButton() override;
|
QToolButton *resetButton() override;
|
||||||
void cleanup() override;
|
void cleanup() override;
|
||||||
void clear() override;
|
void clear() override;
|
||||||
void setSquaresEditable(bool bEditable) override;
|
void setSquaresEditable(bool bEditable) override;
|
||||||
void setWithSurroundingSquare(bool bEnabled) override;
|
void setWithSurroundingSquare(bool bEnabled) override;
|
||||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate>& geoCoords) override;
|
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setDefaultMgrsSquares();
|
void setDefaultMgrsSquares();
|
||||||
void addMgrsSquare(const QString& newMgrsSquare);
|
void addMgrsSquare(const QString &newMgrsSquare);
|
||||||
QStringList utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate>& coords);
|
QStringList utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate> &coords);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_precision;
|
int m_precision;
|
||||||
bool m_withMgrsSquareOffset = false;
|
bool m_withMgrsSquareOffset = false;
|
||||||
Ui::Mgrs* m_ui;
|
Ui::Mgrs *m_ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Wgs84Edit final : public LtsCoordInputWidgetHandler
|
class Wgs84Edit final : public LtsCoordInputWidgetHandler
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit Wgs84Edit(QWidget* widget);
|
explicit Wgs84Edit(QWidget *widget);
|
||||||
~Wgs84Edit();
|
~Wgs84Edit();
|
||||||
|
|
||||||
bool isValid() override;
|
bool isValid() override;
|
||||||
void setCoordinate(const QPointF& geoCoord) override;
|
void setCoordinate(const QPointF &geoCoord) override;
|
||||||
QPointF coordinate() const override;
|
QPointF coordinate() const override;
|
||||||
QToolButton* resetButton() override;
|
QToolButton *resetButton() override;
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DoubleValidator final : public QDoubleValidator
|
class DoubleValidator final : public QDoubleValidator
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DoubleValidator(double bottom, double top, int decimals, QObject* parent = nullptr);
|
DoubleValidator(double bottom, double top, int decimals, QObject *parent = nullptr);
|
||||||
|
|
||||||
QValidator::State validate(QString& input, int& pos) const override;
|
QValidator::State validate(QString &input, int &pos) const override;
|
||||||
};
|
};
|
||||||
} // namespace LtsCoordWidget
|
} // namespace LtsCoordWidget
|
||||||
@@ -9,98 +9,92 @@
|
|||||||
#include <QtWidgets/QPushButton>
|
#include <QtWidgets/QPushButton>
|
||||||
#include <QtWidgets/QVBoxLayout>
|
#include <QtWidgets/QVBoxLayout>
|
||||||
|
|
||||||
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)
|
lbl->setText(str);
|
||||||
.arg(coord.y() * LtsCoordTrans::rad2deg(), 0, 'f', 10);
|
|
||||||
lbl->setText(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate base(LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32UMD00")));
|
LtsCoordTrans::UtmCoordinate base(LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32UMD00")));
|
||||||
QPointF topLeft(base.geographic(+50000, -50000));
|
QPointF topLeft(base.geographic(+50000, -50000));
|
||||||
QPointF bottomRight(base.geographic(-50000, 50000));
|
QPointF bottomRight(base.geographic(-50000, 50000));
|
||||||
LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), true, true);
|
LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), true, true);
|
||||||
|
|
||||||
QDialog* dialog(new QDialog);
|
QDialog *dialog(new QDialog);
|
||||||
QVBoxLayout* lay(new QVBoxLayout(dialog));
|
QVBoxLayout *lay(new QVBoxLayout(dialog));
|
||||||
|
|
||||||
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, [lbl5](const QPointF &coord) { updateLabel(coord, lbl5, 5); });
|
||||||
QObject::connect(wMgrs5, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, lbl5,
|
|
||||||
[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, [lbl7](const QPointF &coord) { updateLabel(coord, lbl7, 7); });
|
||||||
QObject::connect(wMgrs7, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, wMgrs7,
|
|
||||||
[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, [lbl84](const QPointF &coord) { updateLabel(coord, lbl84, 11); });
|
||||||
QObject::connect(w84, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, w84,
|
|
||||||
[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, [wChange]() { wChange->setWithResetButton(!wChange->withResetButton()); });
|
||||||
QObject::connect(pbReset, &QPushButton::clicked, wChange,
|
QPushButton *pbNext(new QPushButton(QStringLiteral("Next Type"), dialog));
|
||||||
[wChange]() { wChange->setWithResetButton(!wChange->withResetButton()); });
|
hLay->addWidget(pbNext);
|
||||||
QPushButton* pbNext(new QPushButton(QStringLiteral("Next Type"), dialog));
|
QObject::connect(pbNext,
|
||||||
hLay->addWidget(pbNext);
|
&QPushButton::clicked,
|
||||||
QObject::connect(pbNext, &QPushButton::clicked, wChange, [wChange]() {
|
wChange,
|
||||||
LtsCoordWidget::LtsCoordWidget::DisplayType dt = wChange->displayType();
|
[wChange]()
|
||||||
switch (dt)
|
{
|
||||||
{
|
LtsCoordWidget::LtsCoordWidget::DisplayType dt = wChange->displayType();
|
||||||
case LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS5:
|
switch (dt)
|
||||||
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7;
|
{
|
||||||
break;
|
case LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS5:
|
||||||
case LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7:
|
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7;
|
||||||
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84;
|
break;
|
||||||
break;
|
case LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7:
|
||||||
case LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84:
|
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84;
|
||||||
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS5;
|
break;
|
||||||
break;
|
case LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84:
|
||||||
default:
|
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS5;
|
||||||
break;
|
break;
|
||||||
}
|
default:
|
||||||
wChange->setDisplayType(dt);
|
break;
|
||||||
});
|
}
|
||||||
|
wChange->setDisplayType(dt);
|
||||||
|
});
|
||||||
|
|
||||||
QPushButton* pb(new QPushButton(QStringLiteral("Quit"), dialog));
|
QPushButton *pb(new QPushButton(QStringLiteral("Quit"), dialog));
|
||||||
lay->addWidget(pb);
|
lay->addWidget(pb);
|
||||||
QObject::connect(pb, &QPushButton::clicked, qApp, QCoreApplication::quit);
|
QObject::connect(pb, &QPushButton::clicked, qApp, QCoreApplication::quit);
|
||||||
|
|
||||||
dialog->show();
|
dialog->show();
|
||||||
int ret = app.exec();
|
int ret = app.exec();
|
||||||
delete dialog;
|
delete dialog;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -4,41 +4,49 @@
|
|||||||
#include <GeographicLib/UTMUPS.hpp>
|
#include <GeographicLib/UTMUPS.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s <mgrs>\n", argv[0]);
|
fprintf(stderr, "Usage: %s <mgrs>\n", argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mgrs = argv[1];
|
std::string mgrs = argv[1];
|
||||||
mgrs.erase(remove_if(mgrs.begin(), mgrs.end(), isspace), mgrs.end());
|
mgrs.erase(remove_if(mgrs.begin(), mgrs.end(), isspace), mgrs.end());
|
||||||
|
|
||||||
int prec;
|
int prec;
|
||||||
double lonDeg, latDeg;
|
double lonDeg, latDeg;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int zone;
|
int zone;
|
||||||
bool northp;
|
bool northp;
|
||||||
double x, y;
|
double x, y;
|
||||||
GeographicLib::MGRS::Reverse(mgrs, zone, northp, x, y, prec, true);
|
GeographicLib::MGRS::Reverse(mgrs, zone, northp, x, y, prec, true);
|
||||||
GeographicLib::UTMUPS::Reverse(zone, northp, x, y, latDeg, lonDeg);
|
GeographicLib::UTMUPS::Reverse(zone, northp, x, y, latDeg, lonDeg);
|
||||||
|
|
||||||
GeographicLib::UTMUPS::Forward(latDeg, lonDeg, zone, northp, x, y);
|
GeographicLib::UTMUPS::Forward(latDeg, lonDeg, zone, northp, x, y);
|
||||||
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error converting %s to Lon/Lat coords\n", mgrs.c_str());
|
fprintf(stderr, "Error converting %s to Lon/Lat coords\n", mgrs.c_str());
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
std::string part1, part2, part3, part4;
|
std::string part1, part2, part3, part4;
|
||||||
part1 = mgrs.substr(0, 3);
|
part1 = mgrs.substr(0, 3);
|
||||||
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",
|
||||||
return 0;
|
part1.c_str(),
|
||||||
|
part2.c_str(),
|
||||||
|
part3.c_str(),
|
||||||
|
part4.c_str(),
|
||||||
|
lonDeg,
|
||||||
|
latDeg,
|
||||||
|
lonDeg / 180. * M_PI,
|
||||||
|
latDeg / 180. * M_PI);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -10,43 +10,43 @@
|
|||||||
|
|
||||||
namespace LtsLicence
|
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();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
~AesCryptPrivate()
|
~AesCryptPrivate()
|
||||||
{
|
{
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
|
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
|
||||||
ERR_free_strings();
|
ERR_free_strings();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QString passPhrase;
|
QString passPhrase;
|
||||||
NGL::INGLLogger& logger;
|
NGL::INGLLogger &logger;
|
||||||
};
|
};
|
||||||
Q_GLOBAL_STATIC(AesCryptPrivate, s_Private)
|
Q_GLOBAL_STATIC(AesCryptPrivate, s_Private)
|
||||||
|
|
||||||
void setPassPhrase(const QString& passPhrase)
|
void setPassPhrase(const QString &passPhrase)
|
||||||
{
|
{
|
||||||
s_Private->passPhrase = passPhrase;
|
s_Private->passPhrase = passPhrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString passPhrase()
|
QString passPhrase()
|
||||||
{
|
{
|
||||||
return s_Private->passPhrase;
|
return s_Private->passPhrase;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray decryptData(const QByteArray& dataToDecrypt, const QString& pw, bool* bOk)
|
QByteArray decryptData(const QByteArray &dataToDecrypt, const QString &pw, bool *bOk)
|
||||||
{
|
{
|
||||||
if (bOk)
|
if (bOk)
|
||||||
*bOk = false;
|
*bOk = false;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
int outSize1 = 0;
|
int outSize1 = 0;
|
||||||
@@ -54,53 +54,53 @@ QByteArray decryptData(const QByteArray& dataToDecrypt, const QString& pw, bool*
|
|||||||
unsigned char key[32];
|
unsigned char key[32];
|
||||||
|
|
||||||
const QByteArray baPassword = pw.toUtf8();
|
const QByteArray baPassword = pw.toUtf8();
|
||||||
const unsigned char* dataPw = reinterpret_cast<const unsigned char*>(baPassword.data());
|
const unsigned char *dataPw = reinterpret_cast<const unsigned char *>(baPassword.data());
|
||||||
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), nullptr, dataPw, baPassword.size(), 5, key, nullptr);
|
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), nullptr, dataPw, baPassword.size(), 5, key, nullptr);
|
||||||
if (i != 32)
|
if (i != 32)
|
||||||
{
|
{
|
||||||
ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits";
|
ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
const QByteArray baSalt = dataToDecrypt.left(EVP_MAX_IV_LENGTH);
|
const QByteArray baSalt = dataToDecrypt.left(EVP_MAX_IV_LENGTH);
|
||||||
const unsigned char* salt = reinterpret_cast<const unsigned char*>(baSalt.data());
|
const unsigned char *salt = reinterpret_cast<const unsigned char *>(baSalt.data());
|
||||||
|
|
||||||
const QByteArray bufEncrypted = dataToDecrypt.mid(EVP_MAX_IV_LENGTH);
|
const QByteArray bufEncrypted = dataToDecrypt.mid(EVP_MAX_IV_LENGTH);
|
||||||
|
|
||||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||||
ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt);
|
ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_DecryptInit_ex failed";
|
ERROR_LOG(s_Private->logger) << "EVP_DecryptInit_ex failed";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray bufDecrypted;
|
QByteArray bufDecrypted;
|
||||||
bufDecrypted.resize(bufEncrypted.size() + EVP_CIPHER_CTX_block_size(ctx));
|
bufDecrypted.resize(bufEncrypted.size() + EVP_CIPHER_CTX_block_size(ctx));
|
||||||
const unsigned char* dataIn = reinterpret_cast<const unsigned char*>(bufEncrypted.data());
|
const unsigned char *dataIn = reinterpret_cast<const unsigned char *>(bufEncrypted.data());
|
||||||
unsigned char* dataOut = reinterpret_cast<unsigned char*>(bufDecrypted.data());
|
unsigned char *dataOut = reinterpret_cast<unsigned char *>(bufDecrypted.data());
|
||||||
|
|
||||||
ret = EVP_DecryptUpdate(ctx, dataOut, &outSize1, dataIn, bufEncrypted.size());
|
ret = EVP_DecryptUpdate(ctx, dataOut, &outSize1, dataIn, bufEncrypted.size());
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_DecryptUpdate failed";
|
ERROR_LOG(s_Private->logger) << "EVP_DecryptUpdate failed";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = EVP_DecryptFinal_ex(ctx, dataOut + outSize1, &outSize2);
|
ret = EVP_DecryptFinal_ex(ctx, dataOut + outSize1, &outSize2);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_DecryptFinal_ex failed";
|
ERROR_LOG(s_Private->logger) << "EVP_DecryptFinal_ex failed";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
@@ -108,14 +108,14 @@ QByteArray decryptData(const QByteArray& dataToDecrypt, const QString& pw, bool*
|
|||||||
bufDecrypted.resize(outSize1 + outSize2);
|
bufDecrypted.resize(outSize1 + outSize2);
|
||||||
|
|
||||||
if (bOk)
|
if (bOk)
|
||||||
*bOk = true;
|
*bOk = true;
|
||||||
return bufDecrypted;
|
return bufDecrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray encryptData(const QByteArray& dataToEncrypt, const QString& pw, bool* bOk)
|
QByteArray encryptData(const QByteArray &dataToEncrypt, const QString &pw, bool *bOk)
|
||||||
{
|
{
|
||||||
if (bOk)
|
if (bOk)
|
||||||
*bOk = false;
|
*bOk = false;
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
int outSize1 = 0;
|
int outSize1 = 0;
|
||||||
@@ -124,53 +124,53 @@ QByteArray encryptData(const QByteArray& dataToEncrypt, const QString& pw, bool*
|
|||||||
QByteArray bufEncrypted;
|
QByteArray bufEncrypted;
|
||||||
|
|
||||||
const QByteArray baPassword = pw.toUtf8();
|
const QByteArray baPassword = pw.toUtf8();
|
||||||
const unsigned char* dataPw = reinterpret_cast<const unsigned char*>(baPassword.data());
|
const unsigned char *dataPw = reinterpret_cast<const unsigned char *>(baPassword.data());
|
||||||
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), nullptr, dataPw, baPassword.size(), 5, key, nullptr);
|
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), nullptr, dataPw, baPassword.size(), 5, key, nullptr);
|
||||||
if (i != 32)
|
if (i != 32)
|
||||||
{
|
{
|
||||||
ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits";
|
ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray baSalt(EVP_MAX_IV_LENGTH, 0);
|
QByteArray baSalt(EVP_MAX_IV_LENGTH, 0);
|
||||||
for (int i = 0; i < EVP_MAX_IV_LENGTH; ++i)
|
for (int i = 0; i < EVP_MAX_IV_LENGTH; ++i)
|
||||||
baSalt[i] = static_cast<char>(QRandomGenerator::global()->bounded(256));
|
baSalt[i] = static_cast<char>(QRandomGenerator::global()->bounded(256));
|
||||||
const unsigned char* salt = reinterpret_cast<const unsigned char*>(baSalt.data());
|
const unsigned char *salt = reinterpret_cast<const unsigned char *>(baSalt.data());
|
||||||
|
|
||||||
EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
|
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
||||||
ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt);
|
ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_EncryptInit_ex failed";
|
ERROR_LOG(s_Private->logger) << "EVP_EncryptInit_ex failed";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
bufEncrypted = QByteArray::fromRawData(reinterpret_cast<const char*>(salt), EVP_MAX_IV_LENGTH);
|
bufEncrypted = QByteArray::fromRawData(reinterpret_cast<const char *>(salt), EVP_MAX_IV_LENGTH);
|
||||||
bufEncrypted.resize(bufEncrypted.size() + dataToEncrypt.size() + EVP_CIPHER_CTX_block_size(ctx));
|
bufEncrypted.resize(bufEncrypted.size() + dataToEncrypt.size() + EVP_CIPHER_CTX_block_size(ctx));
|
||||||
const unsigned char* dataIn = reinterpret_cast<const unsigned char*>(dataToEncrypt.data());
|
const unsigned char *dataIn = reinterpret_cast<const unsigned char *>(dataToEncrypt.data());
|
||||||
unsigned char* dataOut = reinterpret_cast<unsigned char*>(bufEncrypted.data());
|
unsigned char *dataOut = reinterpret_cast<unsigned char *>(bufEncrypted.data());
|
||||||
dataOut += baSalt.size();
|
dataOut += baSalt.size();
|
||||||
ret = EVP_EncryptUpdate(ctx, dataOut, &outSize1, dataIn, dataToEncrypt.size());
|
ret = EVP_EncryptUpdate(ctx, dataOut, &outSize1, dataIn, dataToEncrypt.size());
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_EncryptUpdate failed";
|
ERROR_LOG(s_Private->logger) << "EVP_EncryptUpdate failed";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = EVP_EncryptFinal_ex(ctx, dataOut + outSize1, &outSize2);
|
ret = EVP_EncryptFinal_ex(ctx, dataOut + outSize1, &outSize2);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
char errbuf[256];
|
char errbuf[256];
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_EncryptFinal_ex failed";
|
ERROR_LOG(s_Private->logger) << "EVP_EncryptFinal_ex failed";
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
EVP_CIPHER_CTX_free(ctx);
|
||||||
@@ -178,8 +178,8 @@ QByteArray encryptData(const QByteArray& dataToEncrypt, const QString& pw, bool*
|
|||||||
bufEncrypted.resize(outSize1 + outSize2 + baSalt.size());
|
bufEncrypted.resize(outSize1 + outSize2 + baSalt.size());
|
||||||
|
|
||||||
if (bOk)
|
if (bOk)
|
||||||
*bOk = true;
|
*bOk = true;
|
||||||
return bufEncrypted;
|
return bufEncrypted;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsLicence
|
} // namespace LtsLicence
|
||||||
@@ -9,12 +9,10 @@
|
|||||||
namespace LtsLicence
|
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
|
||||||
@@ -13,41 +13,41 @@ QTEST_MAIN(aes_crypt_test)
|
|||||||
|
|
||||||
void aes_crypt_test::initTestCase()
|
void aes_crypt_test::initTestCase()
|
||||||
{
|
{
|
||||||
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false);
|
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes_crypt_test::truePassTest()
|
void aes_crypt_test::truePassTest()
|
||||||
{
|
{
|
||||||
qDebug("Simple TestCase");
|
qDebug("Simple TestCase");
|
||||||
bool bOk;
|
bool bOk;
|
||||||
const QByteArray content("30.06.2013");
|
const QByteArray content("30.06.2013");
|
||||||
const QString pw(QStringLiteral("aes_crypt_test"));
|
const QString pw(QStringLiteral("aes_crypt_test"));
|
||||||
const QByteArray enc = LtsLicence::encryptData(content, pw, &bOk);
|
const QByteArray enc = LtsLicence::encryptData(content, pw, &bOk);
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
QVERIFY2(bOk, "Error encrypting data...");
|
||||||
|
|
||||||
QCOMPARE(((content.size() + 15 + EVP_MAX_IV_LENGTH) / 18) * 16, enc.size());
|
QCOMPARE(((content.size() + 15 + EVP_MAX_IV_LENGTH) / 18) * 16, enc.size());
|
||||||
const QByteArray dec = LtsLicence::decryptData(enc, pw, &bOk);
|
const QByteArray dec = LtsLicence::decryptData(enc, pw, &bOk);
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
QVERIFY2(bOk, "Error encrypting data...");
|
||||||
QCOMPARE(dec, content);
|
QCOMPARE(dec, content);
|
||||||
|
|
||||||
const QByteArray bigContent(12345, '1');
|
const QByteArray bigContent(12345, '1');
|
||||||
const QByteArray bigEnc = LtsLicence::encryptData(bigContent, pw, &bOk);
|
const QByteArray bigEnc = LtsLicence::encryptData(bigContent, pw, &bOk);
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
QVERIFY2(bOk, "Error encrypting data...");
|
||||||
|
|
||||||
QCOMPARE(((bigContent.size() + 15 + EVP_MAX_IV_LENGTH) / 16) * 16, bigEnc.size());
|
QCOMPARE(((bigContent.size() + 15 + EVP_MAX_IV_LENGTH) / 16) * 16, bigEnc.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes_crypt_test::falsePassTest()
|
void aes_crypt_test::falsePassTest()
|
||||||
{
|
{
|
||||||
qDebug("False Password TestCase");
|
qDebug("False Password TestCase");
|
||||||
bool bOk;
|
bool bOk;
|
||||||
const QByteArray content("30.06.2013");
|
const QByteArray content("30.06.2013");
|
||||||
const QString pw(QStringLiteral("aes_crypt_test"));
|
const QString pw(QStringLiteral("aes_crypt_test"));
|
||||||
const QString pw2(QStringLiteral("aes_crypt_test2"));
|
const QString pw2(QStringLiteral("aes_crypt_test2"));
|
||||||
const QByteArray enc = LtsLicence::encryptData(content, pw, &bOk);
|
const QByteArray enc = LtsLicence::encryptData(content, pw, &bOk);
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
QVERIFY2(bOk, "Error encrypting data...");
|
||||||
QVERIFY2(enc.size() != 20, "Error encrypting data...");
|
QVERIFY2(enc.size() != 20, "Error encrypting data...");
|
||||||
const QByteArray dec = LtsLicence::decryptData(enc, pw2, &bOk);
|
const QByteArray dec = LtsLicence::decryptData(enc, pw2, &bOk);
|
||||||
QVERIFY2(!bOk, "Error encrypting data...");
|
QVERIFY2(!bOk, "Error encrypting data...");
|
||||||
QVERIFY2(dec.isEmpty(), "decrypted data is not empty...");
|
QVERIFY2(dec.isEmpty(), "decrypted data is not empty...");
|
||||||
}
|
}
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
class aes_crypt_test : public QObject
|
class aes_crypt_test : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
void truePassTest();
|
void truePassTest();
|
||||||
void falsePassTest();
|
void falsePassTest();
|
||||||
};
|
};
|
||||||
@@ -8,15 +8,15 @@
|
|||||||
|
|
||||||
namespace LtsLicence
|
namespace LtsLicence
|
||||||
{
|
{
|
||||||
static bool extractLicence(const QDomElement& licenceElement, QVector<Licence>& licenceVec);
|
static bool extractLicence(const QDomElement &licenceElement, QVector<Licence> &licenceVec);
|
||||||
|
|
||||||
static NGL::INGLLogger& getLogger()
|
static NGL::INGLLogger &getLogger()
|
||||||
{
|
{
|
||||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicence");
|
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicence");
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<Licence> readLicences(const QByteArray& unencryptedXmlData)
|
QVector<Licence> readLicences(const QByteArray &unencryptedXmlData)
|
||||||
{
|
{
|
||||||
QVector<Licence> licenceVec;
|
QVector<Licence> licenceVec;
|
||||||
|
|
||||||
QDomDocument xmlDoc;
|
QDomDocument xmlDoc;
|
||||||
@@ -24,10 +24,10 @@ QVector<Licence> readLicences(const QByteArray& unencryptedXmlData)
|
|||||||
const auto parseResult = xmlDoc.setContent(unencryptedXmlData);
|
const auto parseResult = xmlDoc.setContent(unencryptedXmlData);
|
||||||
if (!parseResult)
|
if (!parseResult)
|
||||||
{
|
{
|
||||||
ERROR_LOG(getLogger()) << "Error reading xml data, "
|
ERROR_LOG(getLogger()) << "Error reading xml data, "
|
||||||
<< "error in line " << int(parseResult.errorLine) << ", column " << int(parseResult.errorColumn)
|
<< "error in line " << int(parseResult.errorLine) << ", column " << int(parseResult.errorColumn)
|
||||||
<< ", message: " << parseResult.errorMessage;
|
<< ", message: " << parseResult.errorMessage;
|
||||||
return licenceVec;
|
return licenceVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(getLogger()) << "Try to extract licences";
|
INFO_LOG(getLogger()) << "Try to extract licences";
|
||||||
@@ -36,23 +36,22 @@ QVector<Licence> readLicences(const QByteArray& unencryptedXmlData)
|
|||||||
|
|
||||||
while (!licenceElement.isNull())
|
while (!licenceElement.isNull())
|
||||||
{
|
{
|
||||||
if (!extractLicence(licenceElement, licenceVec))
|
if (!extractLicence(licenceElement, licenceVec))
|
||||||
{
|
{
|
||||||
licenceVec.clear();
|
licenceVec.clear();
|
||||||
return licenceVec;
|
return licenceVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
licenceElement = licenceElement.nextSiblingElement(QLatin1String("licence"));
|
licenceElement = licenceElement.nextSiblingElement(QLatin1String("licence"));
|
||||||
}
|
}
|
||||||
return licenceVec;
|
return licenceVec;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray writeUnencryptedLicences(const QVector<Licence>& licences)
|
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"));
|
||||||
@@ -60,43 +59,43 @@ QByteArray writeUnencryptedLicences(const QVector<Licence>& licences)
|
|||||||
|
|
||||||
for (int i = 0; i < licences.size(); ++i)
|
for (int i = 0; i < licences.size(); ++i)
|
||||||
{
|
{
|
||||||
QDomElement lic = xmlDoc.createElement(QLatin1String("licence"));
|
QDomElement lic = xmlDoc.createElement(QLatin1String("licence"));
|
||||||
root.appendChild(lic);
|
root.appendChild(lic);
|
||||||
|
|
||||||
QDomElement element = xmlDoc.createElement(QLatin1String("name"));
|
QDomElement element = xmlDoc.createElement(QLatin1String("name"));
|
||||||
QDomText text = xmlDoc.createTextNode(licences[i].name);
|
QDomText text = xmlDoc.createTextNode(licences[i].name);
|
||||||
element.appendChild(text);
|
element.appendChild(text);
|
||||||
lic.appendChild(element);
|
lic.appendChild(element);
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("ignoreMaxCount"));
|
element = xmlDoc.createElement(QLatin1String("ignoreMaxCount"));
|
||||||
text = xmlDoc.createTextNode(QString::number(licences[i].ignoreMaxCount));
|
text = xmlDoc.createTextNode(QString::number(licences[i].ignoreMaxCount));
|
||||||
element.appendChild(text);
|
element.appendChild(text);
|
||||||
lic.appendChild(element);
|
lic.appendChild(element);
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("ignoreExpiration"));
|
element = xmlDoc.createElement(QLatin1String("ignoreExpiration"));
|
||||||
text = xmlDoc.createTextNode(QString::number(licences[i].ignoreExpiration));
|
text = xmlDoc.createTextNode(QString::number(licences[i].ignoreExpiration));
|
||||||
element.appendChild(text);
|
element.appendChild(text);
|
||||||
lic.appendChild(element);
|
lic.appendChild(element);
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("maxCount"));
|
element = xmlDoc.createElement(QLatin1String("maxCount"));
|
||||||
text = xmlDoc.createTextNode(QString::number(licences[i].maxCount));
|
text = xmlDoc.createTextNode(QString::number(licences[i].maxCount));
|
||||||
element.appendChild(text);
|
element.appendChild(text);
|
||||||
lic.appendChild(element);
|
lic.appendChild(element);
|
||||||
|
|
||||||
const QLatin1String format("dd.MM.yyyy hh:mm:ss");
|
const QLatin1String format("dd.MM.yyyy hh:mm:ss");
|
||||||
const QString qs = licences[i].expiration.toString(format);
|
const QString qs = licences[i].expiration.toString(format);
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("expiration"));
|
element = xmlDoc.createElement(QLatin1String("expiration"));
|
||||||
text = xmlDoc.createTextNode(qs);
|
text = xmlDoc.createTextNode(qs);
|
||||||
element.appendChild(text);
|
element.appendChild(text);
|
||||||
lic.appendChild(element);
|
lic.appendChild(element);
|
||||||
}
|
}
|
||||||
INFO_LOG(getLogger()) << "Generated XML Data...\n" << xmlDoc.toByteArray();
|
INFO_LOG(getLogger()) << "Generated XML Data...\n" << xmlDoc.toByteArray();
|
||||||
return xmlDoc.toByteArray();
|
return xmlDoc.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool extractLicence(const QDomElement& licenceElement, QVector<Licence>& licenceVec)
|
bool extractLicence(const QDomElement &licenceElement, QVector<Licence> &licenceVec)
|
||||||
{
|
{
|
||||||
Licence licence;
|
Licence licence;
|
||||||
|
|
||||||
QDomElement tag = licenceElement.firstChildElement(QLatin1String("name"));
|
QDomElement tag = licenceElement.firstChildElement(QLatin1String("name"));
|
||||||
@@ -120,29 +119,28 @@ bool extractLicence(const QDomElement& licenceElement, QVector<Licence>& licence
|
|||||||
|
|
||||||
if (!qdt.isValid())
|
if (!qdt.isValid())
|
||||||
{
|
{
|
||||||
ERROR_LOG(getLogger()) << "Invalid expiration format! " << qs << " used format: " << format;
|
ERROR_LOG(getLogger()) << "Invalid expiration format! " << qs << " used format: " << format;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Licence::toString() const
|
QString Licence::toString() const
|
||||||
{
|
{
|
||||||
return QObject::tr("Name: %1, Count: %2, ExpireDate: %3, Expires: %4, UseMaxCount: %5")
|
return QObject::tr("Name: %1, Count: %2, ExpireDate: %3, Expires: %4, UseMaxCount: %5")
|
||||||
.arg(name)
|
.arg(name)
|
||||||
.arg(maxCount)
|
.arg(maxCount)
|
||||||
.arg(expiration.toString())
|
.arg(expiration.toString())
|
||||||
.arg(ignoreExpiration)
|
.arg(ignoreExpiration)
|
||||||
.arg(ignoreMaxCount);
|
.arg(ignoreMaxCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsLicence
|
} // namespace LtsLicence
|
||||||
@@ -11,8 +11,8 @@
|
|||||||
namespace LtsLicence
|
namespace LtsLicence
|
||||||
{
|
{
|
||||||
|
|
||||||
struct LTSLICENCE_EXPORT Licence
|
struct LTSLICENCE_EXPORT Licence
|
||||||
{
|
{
|
||||||
QString name;
|
QString name;
|
||||||
bool ignoreMaxCount = false;
|
bool ignoreMaxCount = false;
|
||||||
bool ignoreExpiration = false;
|
bool ignoreExpiration = false;
|
||||||
@@ -21,9 +21,9 @@ struct LTSLICENCE_EXPORT Licence
|
|||||||
int licenceRefCount = 0;
|
int licenceRefCount = 0;
|
||||||
|
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
LTSLICENCE_EXPORT QVector<Licence> readLicences(const QByteArray& unencryptedXmlData);
|
LTSLICENCE_EXPORT QVector<Licence> readLicences(const QByteArray &unencryptedXmlData);
|
||||||
|
|
||||||
LTSLICENCE_EXPORT QByteArray writeUnencryptedLicences(const QVector<Licence>& licences);
|
LTSLICENCE_EXPORT QByteArray writeUnencryptedLicences(const QVector<Licence> &licences);
|
||||||
} // namespace LtsLicence
|
} // namespace LtsLicence
|
||||||
@@ -9,56 +9,58 @@
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
LtsNotification::~LtsNotification()
|
LtsNotification::~LtsNotification()
|
||||||
{
|
{
|
||||||
delete m_controller;
|
delete m_controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::setIcon(const QIcon& icon)
|
void LtsNotification::setIcon(const QIcon &icon)
|
||||||
{
|
{
|
||||||
m_controller->setIcon(icon);
|
m_controller->setIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::setAction(const std::function<void(void)>& action)
|
void LtsNotification::setAction(const std::function<void(void)> &action)
|
||||||
{
|
{
|
||||||
m_controller->setAction(action);
|
m_controller->setAction(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::setToolTip(const QString& toolTip)
|
void LtsNotification::setToolTip(const QString &toolTip)
|
||||||
{
|
{
|
||||||
m_controller->setToolTip(toolTip);
|
m_controller->setToolTip(toolTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString& LtsNotification::tooltip() const
|
const QString &LtsNotification::tooltip() const
|
||||||
{
|
{
|
||||||
return m_controller->tooltip();
|
return m_controller->tooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::setCount(const int count)
|
void LtsNotification::setCount(const int count)
|
||||||
{
|
{
|
||||||
m_controller->setCount(count);
|
m_controller->setCount(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::setEnabled(bool enable)
|
void LtsNotification::setEnabled(bool enable)
|
||||||
{
|
{
|
||||||
m_controller->setEnabled(enable);
|
m_controller->setEnabled(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::setBackground(const int r, const int g, const int b)
|
void LtsNotification::setBackground(const int r, const int g, const int b)
|
||||||
{
|
{
|
||||||
m_controller->setBackground(r, g, b);
|
m_controller->setBackground(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotification::slotCtlDestroyed(QObject* obj)
|
void LtsNotification::slotCtlDestroyed(QObject *obj)
|
||||||
{
|
{
|
||||||
(void)obj;
|
(void)obj;
|
||||||
|
|
||||||
m_controller = nullptr;
|
m_controller = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsNotification
|
} // namespace LtsNotification
|
||||||
@@ -11,35 +11,35 @@
|
|||||||
|
|
||||||
namespace LtsSession
|
namespace LtsSession
|
||||||
{
|
{
|
||||||
class LtsSession;
|
class LtsSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LtsNotification
|
namespace LtsNotification
|
||||||
{
|
{
|
||||||
class LtsNotificationController;
|
class LtsNotificationController;
|
||||||
|
|
||||||
class LTSNOTIFICATION_EXPORT LtsNotification : public QObject
|
class LTSNOTIFICATION_EXPORT LtsNotification : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LtsNotification(LtsNotificationController* ctl);
|
explicit LtsNotification(LtsNotificationController *ctl);
|
||||||
~LtsNotification();
|
~LtsNotification();
|
||||||
|
|
||||||
void setIcon(const QIcon& icon);
|
void setIcon(const QIcon &icon);
|
||||||
void setAction(const std::function<void(void)>& action);
|
void setAction(const std::function<void(void)> &action);
|
||||||
void setToolTip(const QString& toolTip);
|
void setToolTip(const QString &toolTip);
|
||||||
void setCount(const int count);
|
void setCount(const int count);
|
||||||
void setEnabled(bool enable);
|
void setEnabled(bool enable);
|
||||||
void setBackground(const int r, const int g, const int b);
|
void setBackground(const int r, const int g, const int b);
|
||||||
|
|
||||||
const QString& tooltip() const;
|
const QString &tooltip() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LtsNotificationController* m_controller;
|
LtsNotificationController *m_controller;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotCtlDestroyed(QObject* obj);
|
void slotCtlDestroyed(QObject *obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsNotification
|
} // namespace LtsNotification
|
||||||
+67
-62
@@ -13,94 +13,95 @@
|
|||||||
namespace LtsNotification
|
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))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
LtsNotificationController::~LtsNotificationController()
|
LtsNotificationController::~LtsNotificationController()
|
||||||
{
|
{
|
||||||
qDeleteAll(m_notiList);
|
qDeleteAll(m_notiList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setIcon(const QIcon& icon)
|
void LtsNotificationController::setIcon(const QIcon &icon)
|
||||||
{
|
{
|
||||||
m_icon = icon;
|
m_icon = icon;
|
||||||
|
|
||||||
setAllIcons();
|
setAllIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setCount(const int count)
|
void LtsNotificationController::setCount(const int count)
|
||||||
{
|
{
|
||||||
m_count = count;
|
m_count = count;
|
||||||
|
|
||||||
setAllIcons();
|
setAllIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setBackground(const int r, const int g, const int b)
|
void LtsNotificationController::setBackground(const int r, const int g, const int b)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (QToolButton* tb : std::as_const(m_notiList))
|
for (QToolButton *tb : std::as_const(m_notiList))
|
||||||
{
|
{
|
||||||
|
|
||||||
QString stylesheet;
|
QString stylesheet;
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setEnabled(bool enable)
|
void LtsNotificationController::setEnabled(bool enable)
|
||||||
{
|
{
|
||||||
m_enable = enable;
|
m_enable = enable;
|
||||||
|
|
||||||
setAllIcons();
|
setAllIcons();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setAction(const std::function<void(void)>& action)
|
void LtsNotificationController::setAction(const std::function<void(void)> &action)
|
||||||
{
|
{
|
||||||
m_action = action;
|
m_action = action;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setToolTip(const QString& toolTip)
|
void LtsNotificationController::setToolTip(const QString &toolTip)
|
||||||
{
|
{
|
||||||
m_toolTip = toolTip;
|
m_toolTip = toolTip;
|
||||||
|
|
||||||
for (QToolButton* tb : std::as_const(m_notiList))
|
for (QToolButton *tb : std::as_const(m_notiList))
|
||||||
{
|
{
|
||||||
tb->setToolTip(toolTip);
|
tb->setToolTip(toolTip);
|
||||||
tb->setIconSize(QSize(30, 30));
|
tb->setIconSize(QSize(30, 30));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::setAllIcons()
|
void LtsNotificationController::setAllIcons()
|
||||||
{
|
{
|
||||||
if (m_icon.isNull())
|
if (m_icon.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QIcon icon = modifyIcon(m_icon);
|
QIcon icon = modifyIcon(m_icon);
|
||||||
|
|
||||||
for (QToolButton* tb : std::as_const(m_notiList))
|
for (QToolButton *tb : std::as_const(m_notiList))
|
||||||
{
|
{
|
||||||
tb->setIcon(icon);
|
tb->setIcon(icon);
|
||||||
tb->setIconSize(QSize(30, 30));
|
tb->setIconSize(QSize(30, 30));
|
||||||
tb->setEnabled(m_enable);
|
tb->setEnabled(m_enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SIZE 40
|
#define SIZE 40
|
||||||
|
|
||||||
QIcon LtsNotificationController::modifyIcon(const QIcon& icon)
|
QIcon LtsNotificationController::modifyIcon(const QIcon &icon)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_count < 1)
|
if (m_count < 1)
|
||||||
return icon;
|
return icon;
|
||||||
|
|
||||||
QPixmap iconImage(icon.pixmap(SIZE * 8 / 10, SIZE * 8 / 10));
|
QPixmap iconImage(icon.pixmap(SIZE * 8 / 10, SIZE * 8 / 10));
|
||||||
QPainter painter(&iconImage);
|
QPainter painter(&iconImage);
|
||||||
@@ -121,11 +122,11 @@ QIcon LtsNotificationController::modifyIcon(const QIcon& icon)
|
|||||||
painter.restore();
|
painter.restore();
|
||||||
|
|
||||||
return iconImage;
|
return iconImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
QToolButton* LtsNotificationController::createWidget()
|
QToolButton *LtsNotificationController::createWidget()
|
||||||
{
|
{
|
||||||
QToolButton* b = new QToolButton();
|
QToolButton *b = new QToolButton();
|
||||||
b->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
b->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
||||||
b->setObjectName(m_identifier);
|
b->setObjectName(m_identifier);
|
||||||
|
|
||||||
@@ -133,23 +134,27 @@ 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,
|
||||||
if (m_action)
|
&QToolButton::clicked,
|
||||||
m_action();
|
this,
|
||||||
});
|
[this]()
|
||||||
|
{
|
||||||
|
if (m_action)
|
||||||
|
m_action();
|
||||||
|
});
|
||||||
|
|
||||||
if (!m_icon.isNull())
|
if (!m_icon.isNull())
|
||||||
b->setIcon(modifyIcon(m_icon));
|
b->setIcon(modifyIcon(m_icon));
|
||||||
|
|
||||||
b->setToolTip(m_toolTip);
|
b->setToolTip(m_toolTip);
|
||||||
|
|
||||||
m_notiList.append(b);
|
m_notiList.append(b);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsNotificationController::slotNotiWidgetDestroyed(QObject* obj)
|
void LtsNotificationController::slotNotiWidgetDestroyed(QObject *obj)
|
||||||
{
|
{
|
||||||
m_notiList.removeAll(static_cast<QToolButton*>(obj));
|
m_notiList.removeAll(static_cast<QToolButton *>(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsNotification
|
} // namespace LtsNotification
|
||||||
@@ -14,43 +14,37 @@ class QToolButton;
|
|||||||
|
|
||||||
namespace LtsSession
|
namespace LtsSession
|
||||||
{
|
{
|
||||||
class LtsSession;
|
class LtsSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LtsNotification
|
namespace LtsNotification
|
||||||
{
|
{
|
||||||
class LtsNotificationWidget;
|
class LtsNotificationWidget;
|
||||||
|
|
||||||
class LTSNOTIFICATION_EXPORT LtsNotificationController : public QObject
|
class LTSNOTIFICATION_EXPORT LtsNotificationController : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LtsNotificationController(const QString& identifier);
|
explicit LtsNotificationController(const QString &identifier);
|
||||||
~LtsNotificationController();
|
~LtsNotificationController();
|
||||||
|
|
||||||
QToolButton* createWidget();
|
QToolButton *createWidget();
|
||||||
|
|
||||||
void setIcon(const QIcon& icon);
|
void setIcon(const QIcon &icon);
|
||||||
void setAction(const std::function<void(void)>& action);
|
void setAction(const std::function<void(void)> &action);
|
||||||
void setToolTip(const QString& toolTip);
|
void setToolTip(const QString &toolTip);
|
||||||
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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QToolButton*> m_notiList;
|
QList<QToolButton *> m_notiList;
|
||||||
|
|
||||||
QIcon m_icon;
|
QIcon m_icon;
|
||||||
std::function<void(void)> m_action;
|
std::function<void(void)> m_action;
|
||||||
@@ -60,10 +54,10 @@ class LTSNOTIFICATION_EXPORT LtsNotificationController : public QObject
|
|||||||
QString m_identifier;
|
QString m_identifier;
|
||||||
|
|
||||||
void setAllIcons();
|
void setAllIcons();
|
||||||
QIcon modifyIcon(const QIcon& icon);
|
QIcon modifyIcon(const QIcon &icon);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotNotiWidgetDestroyed(QObject* obj);
|
void slotNotiWidgetDestroyed(QObject *obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsNotification
|
} // namespace LtsNotification
|
||||||
@@ -16,157 +16,160 @@
|
|||||||
namespace LtsCommon
|
namespace LtsCommon
|
||||||
{
|
{
|
||||||
|
|
||||||
LtsRestClient::LtsRestClient(const QString &baseUrl, QObject *parent)
|
LtsRestClient::LtsRestClient(const QString &baseUrl, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_baseUrl(baseUrl)
|
, m_baseUrl(baseUrl)
|
||||||
, m_manager(new QNetworkAccessManager(this))
|
, m_manager(new QNetworkAccessManager(this))
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsRestClient::ping(PingSuccessCallback onSuccess, ErrorCallback onError, int timeoutMs)
|
|
||||||
{
|
|
||||||
const QNetworkRequest request((QUrl(m_baseUrl)));
|
|
||||||
QNetworkReply *reply = m_manager->head(request);
|
|
||||||
|
|
||||||
if (!reply)
|
|
||||||
{
|
{
|
||||||
if (onError)
|
|
||||||
onError(QStringLiteral("Failed to initiate ping."));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. Setup the timer (parented to reply for auto-cleanup)
|
void LtsRestClient::ping(PingSuccessCallback onSuccess, ErrorCallback onError, int timeoutMs)
|
||||||
QTimer *timeoutTimer = new QTimer(reply);
|
|
||||||
timeoutTimer->setSingleShot(true);
|
|
||||||
|
|
||||||
// 2. Connect the timeout signal to abort the request
|
|
||||||
connect(timeoutTimer, &QTimer::timeout, this, [reply]()
|
|
||||||
{
|
{
|
||||||
if (reply && reply->isRunning())
|
const QNetworkRequest request((QUrl(m_baseUrl)));
|
||||||
reply->abort(); // Triggers finished() with OperationCanceledError
|
QNetworkReply *reply = m_manager->head(request);
|
||||||
});
|
|
||||||
|
|
||||||
// 3. Connect the finished signal to handle the response
|
if (!reply)
|
||||||
connect(reply,
|
|
||||||
&QNetworkReply::finished,
|
|
||||||
this,
|
|
||||||
[reply, timeoutTimer, onSuccess, onError]()
|
|
||||||
{
|
|
||||||
timeoutTimer->stop();
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
if (reply->error() != QNetworkReply::NoError)
|
|
||||||
{
|
{
|
||||||
if (onError)
|
if (onError)
|
||||||
{
|
onError(QStringLiteral("Failed to initiate ping."));
|
||||||
if (reply->error() == QNetworkReply::OperationCanceledError)
|
|
||||||
onError(QStringLiteral("Ping timed out."));
|
|
||||||
else
|
|
||||||
onError(reply->errorString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
// 1. Setup the timer (parented to reply for auto-cleanup)
|
||||||
|
QTimer *timeoutTimer = new QTimer(reply);
|
||||||
|
timeoutTimer->setSingleShot(true);
|
||||||
|
|
||||||
if (onSuccess)
|
// 2. Connect the timeout signal to abort the request
|
||||||
onSuccess(statusCode);
|
connect(timeoutTimer,
|
||||||
});
|
&QTimer::timeout,
|
||||||
|
this,
|
||||||
|
[reply]()
|
||||||
|
{
|
||||||
|
if (reply && reply->isRunning())
|
||||||
|
reply->abort(); // Triggers finished() with OperationCanceledError
|
||||||
|
});
|
||||||
|
|
||||||
// 4. Start the timer only after all connections are successfully established
|
// 3. Connect the finished signal to handle the response
|
||||||
timeoutTimer->start(timeoutMs);
|
connect(reply,
|
||||||
}
|
&QNetworkReply::finished,
|
||||||
|
this,
|
||||||
|
[reply, timeoutTimer, onSuccess, onError]()
|
||||||
|
{
|
||||||
|
timeoutTimer->stop();
|
||||||
|
reply->deleteLater();
|
||||||
|
|
||||||
void LtsRestClient::get(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
|
if (reply->error() != QNetworkReply::NoError)
|
||||||
{
|
{
|
||||||
sendRequest(QStringLiteral("GET"), endpoint, QByteArray(), onSuccess, onError);
|
if (onError)
|
||||||
}
|
{
|
||||||
|
if (reply->error() == QNetworkReply::OperationCanceledError)
|
||||||
|
onError(QStringLiteral("Ping timed out."));
|
||||||
|
else
|
||||||
|
onError(reply->errorString());
|
||||||
|
}
|
||||||
|
|
||||||
void LtsRestClient::post(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
|
return;
|
||||||
{
|
}
|
||||||
sendRequest(QStringLiteral("POST"), endpoint, json.toJson(), onSuccess, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsRestClient::put(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
|
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
{
|
|
||||||
sendRequest(QStringLiteral("PUT"), endpoint, json.toJson(), onSuccess, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsRestClient::del(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
|
if (onSuccess)
|
||||||
{
|
onSuccess(statusCode);
|
||||||
sendRequest(QStringLiteral("DELETE"), endpoint, QByteArray(), onSuccess, onError);
|
});
|
||||||
}
|
|
||||||
|
|
||||||
void LtsRestClient::sendRequest(const QString &method, const QString &endpoint, const QByteArray &data, SuccessCallback onSuccess, ErrorCallback onError)
|
// 4. Start the timer only after all connections are successfully established
|
||||||
{
|
timeoutTimer->start(timeoutMs);
|
||||||
QUrl url(m_baseUrl);
|
|
||||||
url.setPath(url.path() + endpoint);
|
|
||||||
|
|
||||||
QNetworkRequest request(url);
|
|
||||||
request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
|
|
||||||
|
|
||||||
QNetworkReply *reply = nullptr;
|
|
||||||
|
|
||||||
if (method == QStringLiteral("GET"))
|
|
||||||
reply = m_manager->get(request);
|
|
||||||
else if (method == QStringLiteral("POST"))
|
|
||||||
reply = m_manager->post(request, data);
|
|
||||||
else if (method == QStringLiteral("PUT"))
|
|
||||||
reply = m_manager->put(request, data);
|
|
||||||
else if (method == QStringLiteral("DELETE"))
|
|
||||||
reply = m_manager->deleteResource(request);
|
|
||||||
|
|
||||||
if (!reply)
|
|
||||||
{
|
|
||||||
if (onError)
|
|
||||||
onError(QStringLiteral("Failed to initiate request."));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(reply,
|
void LtsRestClient::get(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
|
||||||
&QNetworkReply::finished,
|
|
||||||
this,
|
|
||||||
[reply, onSuccess, onError]()
|
|
||||||
{
|
{
|
||||||
reply->deleteLater();
|
sendRequest(QStringLiteral("GET"), endpoint, QByteArray(), onSuccess, onError);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle network errors
|
void LtsRestClient::post(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
|
||||||
if (reply->error() != QNetworkReply::NoError)
|
{
|
||||||
|
sendRequest(QStringLiteral("POST"), endpoint, json.toJson(), onSuccess, onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LtsRestClient::put(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
|
||||||
|
{
|
||||||
|
sendRequest(QStringLiteral("PUT"), endpoint, json.toJson(), onSuccess, onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LtsRestClient::del(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
|
||||||
|
{
|
||||||
|
sendRequest(QStringLiteral("DELETE"), endpoint, QByteArray(), onSuccess, onError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LtsRestClient::sendRequest(const QString &method, const QString &endpoint, const QByteArray &data, SuccessCallback onSuccess, ErrorCallback onError)
|
||||||
|
{
|
||||||
|
QUrl url(m_baseUrl);
|
||||||
|
url.setPath(url.path() + endpoint);
|
||||||
|
|
||||||
|
QNetworkRequest request(url);
|
||||||
|
request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json"));
|
||||||
|
|
||||||
|
QNetworkReply *reply = nullptr;
|
||||||
|
|
||||||
|
if (method == QStringLiteral("GET"))
|
||||||
|
reply = m_manager->get(request);
|
||||||
|
else if (method == QStringLiteral("POST"))
|
||||||
|
reply = m_manager->post(request, data);
|
||||||
|
else if (method == QStringLiteral("PUT"))
|
||||||
|
reply = m_manager->put(request, data);
|
||||||
|
else if (method == QStringLiteral("DELETE"))
|
||||||
|
reply = m_manager->deleteResource(request);
|
||||||
|
|
||||||
|
if (!reply)
|
||||||
{
|
{
|
||||||
if (onError)
|
if (onError)
|
||||||
onError(reply->errorString());
|
onError(QStringLiteral("Failed to initiate request."));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle HTTP errors
|
connect(reply,
|
||||||
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
&QNetworkReply::finished,
|
||||||
if (statusCode >= 400)
|
this,
|
||||||
{
|
[reply, onSuccess, onError]()
|
||||||
if (onError)
|
{
|
||||||
onError(QStringLiteral("HTTP Error %1").arg(statusCode));
|
reply->deleteLater();
|
||||||
|
|
||||||
return;
|
// Handle network errors
|
||||||
}
|
if (reply->error() != QNetworkReply::NoError)
|
||||||
|
{
|
||||||
|
if (onError)
|
||||||
|
onError(reply->errorString());
|
||||||
|
|
||||||
// Parse JSON safely
|
return;
|
||||||
QJsonParseError parseError;
|
}
|
||||||
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
|
||||||
|
|
||||||
if (parseError.error != QJsonParseError::NoError)
|
// Handle HTTP errors
|
||||||
{
|
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||||
if (onError)
|
if (statusCode >= 400)
|
||||||
onError(QStringLiteral("JSON Parse Error: ") + parseError.errorString());
|
{
|
||||||
|
if (onError)
|
||||||
|
onError(QStringLiteral("HTTP Error %1").arg(statusCode));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (onSuccess)
|
// Parse JSON safely
|
||||||
onSuccess(doc);
|
QJsonParseError parseError;
|
||||||
});
|
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &parseError);
|
||||||
}
|
|
||||||
|
if (parseError.error != QJsonParseError::NoError)
|
||||||
|
{
|
||||||
|
if (onError)
|
||||||
|
onError(QStringLiteral("JSON Parse Error: ") + parseError.errorString());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onSuccess)
|
||||||
|
onSuccess(doc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace LtsCommon
|
} // namespace LtsCommon
|
||||||
@@ -21,31 +21,31 @@ class QNetworkAccessManager;
|
|||||||
namespace LtsCommon
|
namespace LtsCommon
|
||||||
{
|
{
|
||||||
|
|
||||||
class LTSRESTCLIENT_EXPORT LtsRestClient : public QObject
|
class LTSRESTCLIENT_EXPORT LtsRestClient : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LtsRestClient(const QString &baseUrl, QObject *parent = nullptr);
|
explicit LtsRestClient(const QString &baseUrl, QObject *parent = nullptr);
|
||||||
|
|
||||||
// type aliases
|
// type aliases
|
||||||
using PingSuccessCallback = std::function<void(int statusCode)>;
|
using PingSuccessCallback = std::function<void(int statusCode)>;
|
||||||
using SuccessCallback = std::function<void(const QJsonDocument &)>;
|
using SuccessCallback = std::function<void(const QJsonDocument &)>;
|
||||||
using ErrorCallback = std::function<void(const QString &)>;
|
using ErrorCallback = std::function<void(const QString &)>;
|
||||||
|
|
||||||
// HTTP Header Ping to m_baseUrl to check server availability
|
// HTTP Header Ping to m_baseUrl to check server availability
|
||||||
void ping(PingSuccessCallback onSuccess, ErrorCallback onError = nullptr, int timeoutMs = 3000);
|
void ping(PingSuccessCallback onSuccess, ErrorCallback onError = nullptr, int timeoutMs = 3000);
|
||||||
|
|
||||||
// HTTP Methods
|
// HTTP Methods
|
||||||
void get(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
void get(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
||||||
void post(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
void post(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
||||||
void put(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
void put(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
||||||
void del(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
void del(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void sendRequest(const QString &method, const QString &endpoint, const QByteArray &data, SuccessCallback onSuccess, ErrorCallback onError);
|
void sendRequest(const QString &method, const QString &endpoint, const QByteArray &data, SuccessCallback onSuccess, ErrorCallback onError);
|
||||||
|
|
||||||
QString m_baseUrl;
|
QString m_baseUrl;
|
||||||
QNetworkAccessManager *m_manager;
|
QNetworkAccessManager *m_manager;
|
||||||
}; // class RestClient
|
}; // class RestClient
|
||||||
} // namespace LtsCommon
|
} // namespace LtsCommon
|
||||||
@@ -7,8 +7,8 @@
|
|||||||
namespace LtsSerialPortQuerry
|
namespace LtsSerialPortQuerry
|
||||||
{
|
{
|
||||||
|
|
||||||
LOGGER_T getLogger(const char* name)
|
LOGGER_T getLogger(const char *name)
|
||||||
{
|
{
|
||||||
static const char ns[] = "SPQ.";
|
static const char ns[] = "SPQ.";
|
||||||
std::string loggerName;
|
std::string loggerName;
|
||||||
const size_t len = strlen(name);
|
const size_t len = strlen(name);
|
||||||
@@ -18,13 +18,13 @@ LOGGER_T getLogger(const char* name)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName);
|
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName);
|
||||||
}
|
}
|
||||||
catch (const std::exception& ex)
|
catch (const std::exception &ex)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsSerialPortQuerry
|
} // namespace LtsSerialPortQuerry
|
||||||
@@ -6,12 +6,12 @@
|
|||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
namespace LtsSerialPortQuerry
|
||||||
{
|
{
|
||||||
typedef NGL::INGLLogger& LOGGER_T;
|
typedef NGL::INGLLogger &LOGGER_T;
|
||||||
|
|
||||||
LOGGER_T getLogger(const char* name);
|
LOGGER_T getLogger(const char *name);
|
||||||
|
|
||||||
inline LOGGER_T getLogger(const QString& loggerName)
|
inline LOGGER_T getLogger(const QString &loggerName)
|
||||||
{
|
{
|
||||||
return getLogger(loggerName.toUtf8().constData());
|
return getLogger(loggerName.toUtf8().constData());
|
||||||
}
|
}
|
||||||
} // namespace LtsSerialPortQuerry
|
} // namespace LtsSerialPortQuerry
|
||||||
+13
-10
@@ -9,24 +9,27 @@
|
|||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
namespace LtsSerialPortQuerry
|
||||||
{
|
{
|
||||||
class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
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();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void connectionEstablished();
|
void connectionEstablished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void querrySerialPort(const QSerialPortInfo& info);
|
void querrySerialPort(const QSerialPortInfo &info);
|
||||||
void closeAndDeleteCurrentPort();
|
void closeAndDeleteCurrentPort();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -41,7 +44,7 @@ class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
|||||||
QSerialPort::FlowControl m_flowControll;
|
QSerialPort::FlowControl m_flowControll;
|
||||||
QSerialPort::Parity m_parity;
|
QSerialPort::Parity m_parity;
|
||||||
QSerialPort::StopBits m_stopBits;
|
QSerialPort::StopBits m_stopBits;
|
||||||
QSerialPort* m_currentSerialPort;
|
QSerialPort *m_currentSerialPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsSerialPortQuerry
|
} // namespace LtsSerialPortQuerry
|
||||||
+82
-75
@@ -5,59 +5,65 @@
|
|||||||
namespace LtsSerialPortQuerry
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void LtsSerialPortQuerry::setSerialPortSettings(const QSerialPort::BaudRate& baudRate,
|
void LtsSerialPortQuerry::setSerialPortSettings(const QSerialPort::BaudRate &baudRate,
|
||||||
const QIODevice::OpenModeFlag& openModeFlag,
|
const QIODevice::OpenModeFlag &openModeFlag,
|
||||||
const QSerialPort::DataBits& dataBits,
|
const QSerialPort::DataBits &dataBits,
|
||||||
const QSerialPort::FlowControl& flowControll,
|
const QSerialPort::FlowControl &flowControll,
|
||||||
const QSerialPort::Parity& parity,
|
const QSerialPort::Parity &parity,
|
||||||
const QSerialPort::StopBits& stopBits)
|
const QSerialPort::StopBits &stopBits)
|
||||||
{
|
{
|
||||||
m_baudRate = baudRate;
|
m_baudRate = baudRate;
|
||||||
m_openModeFlag = openModeFlag;
|
m_openModeFlag = openModeFlag;
|
||||||
m_dataBits = dataBits;
|
m_dataBits = dataBits;
|
||||||
m_flowControll = flowControll;
|
m_flowControll = flowControll;
|
||||||
m_parity = parity;
|
m_parity = parity;
|
||||||
m_stopBits = stopBits;
|
m_stopBits = stopBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsSerialPortQuerry::continueQuerry()
|
void LtsSerialPortQuerry::continueQuerry()
|
||||||
{
|
{
|
||||||
m_currentQuerry++;
|
m_currentQuerry++;
|
||||||
if (m_currentQuerry >= m_serialPortInfos.size())
|
if (m_currentQuerry >= m_serialPortInfos.size())
|
||||||
{
|
{
|
||||||
|
|
||||||
restartQuerry();
|
restartQuerry();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
querrySerialPort(m_serialPortInfos.at(m_currentQuerry));
|
querrySerialPort(m_serialPortInfos.at(m_currentQuerry));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsSerialPortQuerry::restartQuerry()
|
void LtsSerialPortQuerry::restartQuerry()
|
||||||
{
|
{
|
||||||
DEBUG_LOG(m_logger) << "restart querry ";
|
DEBUG_LOG(m_logger) << "restart querry ";
|
||||||
m_serialPortInfos = QSerialPortInfo::availablePorts();
|
m_serialPortInfos = QSerialPortInfo::availablePorts();
|
||||||
m_currentQuerry = 0;
|
m_currentQuerry = 0;
|
||||||
if (m_serialPortInfos.size())
|
if (m_serialPortInfos.size())
|
||||||
querrySerialPort(m_serialPortInfos.at(m_currentQuerry));
|
querrySerialPort(m_serialPortInfos.at(m_currentQuerry));
|
||||||
else
|
else
|
||||||
QTimer::singleShot(1000, this, &LtsSerialPortQuerry::restartQuerry);
|
QTimer::singleShot(1000, this, &LtsSerialPortQuerry::restartQuerry);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSerialPort* LtsSerialPortQuerry::currentSerialPort()
|
QSerialPort *LtsSerialPortQuerry::currentSerialPort()
|
||||||
{
|
{
|
||||||
return m_currentSerialPort;
|
return m_currentSerialPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsSerialPortQuerry::querrySerialPort(const QSerialPortInfo& info)
|
void LtsSerialPortQuerry::querrySerialPort(const QSerialPortInfo &info)
|
||||||
{
|
{
|
||||||
closeAndDeleteCurrentPort();
|
closeAndDeleteCurrentPort();
|
||||||
m_currentSerialPort = new QSerialPort(info, this);
|
m_currentSerialPort = new QSerialPort(info, this);
|
||||||
m_currentSerialPort->setBaudRate(m_baudRate);
|
m_currentSerialPort->setBaudRate(m_baudRate);
|
||||||
@@ -66,75 +72,76 @@ 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))
|
||||||
{
|
{
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Oppening failed query next";
|
DEBUG_LOG(m_logger) << "Oppening failed query next";
|
||||||
|
|
||||||
continueQuerry();
|
continueQuerry();
|
||||||
}
|
}
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsSerialPortQuerry::closeAndDeleteCurrentPort()
|
void LtsSerialPortQuerry::closeAndDeleteCurrentPort()
|
||||||
{
|
{
|
||||||
if (m_currentSerialPort)
|
if (m_currentSerialPort)
|
||||||
{
|
{
|
||||||
m_currentSerialPort->disconnect();
|
m_currentSerialPort->disconnect();
|
||||||
if (m_currentSerialPort->isOpen())
|
if (m_currentSerialPort->isOpen())
|
||||||
m_currentSerialPort->close();
|
m_currentSerialPort->close();
|
||||||
m_currentSerialPort->deleteLater();
|
m_currentSerialPort->deleteLater();
|
||||||
|
|
||||||
m_currentSerialPort = nullptr;
|
m_currentSerialPort = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LtsSerialPortQuerry::onSerialPortError(QSerialPort::SerialPortError serialPortError)
|
void LtsSerialPortQuerry::onSerialPortError(QSerialPort::SerialPortError serialPortError)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!m_currentSerialPort)
|
if (!m_currentSerialPort)
|
||||||
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;
|
||||||
}
|
}
|
||||||
case QSerialPort::SerialPortError::DeviceNotFoundError:
|
case QSerialPort::SerialPortError::DeviceNotFoundError:
|
||||||
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();
|
{
|
||||||
continueQuerry();
|
ERROR_LOG(m_logger) << "Closing port and try to reopen it. " << m_currentSerialPort->portName();
|
||||||
|
continueQuerry();
|
||||||
|
|
||||||
Q_FALLTHROUGH();
|
Q_FALLTHROUGH();
|
||||||
}
|
}
|
||||||
case QSerialPort::SerialPortError::UnsupportedOperationError: {
|
case QSerialPort::SerialPortError::UnsupportedOperationError:
|
||||||
ERROR_LOG(m_logger) << errStr;
|
{
|
||||||
break;
|
ERROR_LOG(m_logger) << errStr;
|
||||||
}
|
break;
|
||||||
default: {
|
}
|
||||||
ERROR_LOG(m_logger) << "Got an Error> " << errStr << "restarting";
|
default:
|
||||||
continueQuerry();
|
{
|
||||||
|
ERROR_LOG(m_logger) << "Got an Error> " << errStr << "restarting";
|
||||||
|
continueQuerry();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace LtsSerialPortQuerry
|
} // namespace LtsSerialPortQuerry
|
||||||
+14
-11
@@ -9,18 +9,21 @@
|
|||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
namespace LtsSerialPortQuerry
|
||||||
{
|
{
|
||||||
class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
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();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void continueQuerry();
|
void continueQuerry();
|
||||||
@@ -29,8 +32,8 @@ class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
|||||||
void connectionEstablished();
|
void connectionEstablished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NGL::INGLLogger& m_logger;
|
NGL::INGLLogger &m_logger;
|
||||||
void querrySerialPort(const QSerialPortInfo& info);
|
void querrySerialPort(const QSerialPortInfo &info);
|
||||||
void closeAndDeleteCurrentPort();
|
void closeAndDeleteCurrentPort();
|
||||||
void onSerialPortError(QSerialPort::SerialPortError serialPortError);
|
void onSerialPortError(QSerialPort::SerialPortError serialPortError);
|
||||||
QList<QSerialPortInfo> m_serialPortInfos;
|
QList<QSerialPortInfo> m_serialPortInfos;
|
||||||
@@ -41,7 +44,7 @@ class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
|||||||
QSerialPort::FlowControl m_flowControll;
|
QSerialPort::FlowControl m_flowControll;
|
||||||
QSerialPort::Parity m_parity;
|
QSerialPort::Parity m_parity;
|
||||||
QSerialPort::StopBits m_stopBits;
|
QSerialPort::StopBits m_stopBits;
|
||||||
QSerialPort* m_currentSerialPort;
|
QSerialPort *m_currentSerialPort;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsSerialPortQuerry
|
} // namespace LtsSerialPortQuerry
|
||||||
@@ -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()
|
|
||||||
+757
-770
File diff suppressed because it is too large.
Load diff
+37
-37
@@ -6,50 +6,50 @@
|
|||||||
|
|
||||||
class LtsUtilsTest : public QObject
|
class LtsUtilsTest : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
|
||||||
void test_toIntArray();
|
void test_toIntArray();
|
||||||
void test_fromIntArray();
|
void test_fromIntArray();
|
||||||
void test_toBigintArray();
|
void test_toBigintArray();
|
||||||
void test_fromBigintArray();
|
void test_fromBigintArray();
|
||||||
void test_toIntArray2D();
|
void test_toIntArray2D();
|
||||||
void test_fromIntArray2D();
|
void test_fromIntArray2D();
|
||||||
void test_toBigintArray2D();
|
void test_toBigintArray2D();
|
||||||
void test_fromBigintArray2D();
|
void test_fromBigintArray2D();
|
||||||
|
|
||||||
void test_QPoint3D();
|
void test_QPoint3D();
|
||||||
|
|
||||||
void test_bitArray();
|
void test_bitArray();
|
||||||
|
|
||||||
void test_convert();
|
void test_convert();
|
||||||
|
|
||||||
void test_connection();
|
void test_connection();
|
||||||
void test_queuedConnection();
|
void test_queuedConnection();
|
||||||
void test_signalSignalConnection();
|
void test_signalSignalConnection();
|
||||||
void test_danglingConnection1();
|
void test_danglingConnection1();
|
||||||
void test_danglingConnection2();
|
void test_danglingConnection2();
|
||||||
void test_danglingConnection3();
|
void test_danglingConnection3();
|
||||||
|
|
||||||
void test_jsonObject_fromJson();
|
void test_jsonObject_fromJson();
|
||||||
void test_jsonObject_contains();
|
void test_jsonObject_contains();
|
||||||
void test_jsonObject_value();
|
void test_jsonObject_value();
|
||||||
void test_jsonObject_valueWithError();
|
void test_jsonObject_valueWithError();
|
||||||
void test_jsonObject_valueOr();
|
void test_jsonObject_valueOr();
|
||||||
void test_jsonObject_integers();
|
void test_jsonObject_integers();
|
||||||
void test_jsonObject_nullValues();
|
void test_jsonObject_nullValues();
|
||||||
void test_jsonArray_fromJson();
|
void test_jsonArray_fromJson();
|
||||||
void test_jsonArray();
|
void test_jsonArray();
|
||||||
void test_jsonArray_nullArray();
|
void test_jsonArray_nullArray();
|
||||||
|
|
||||||
void test_byteStreamFromSfmMessage();
|
void test_byteStreamFromSfmMessage();
|
||||||
void test_byteStreamFromSfmMessage2();
|
void test_byteStreamFromSfmMessage2();
|
||||||
void test_byteStreamToSfmMessage();
|
void test_byteStreamToSfmMessage();
|
||||||
|
|
||||||
void test_promise();
|
void test_promise();
|
||||||
void test_promise_example1();
|
void test_promise_example1();
|
||||||
void test_promise_example2();
|
void test_promise_example2();
|
||||||
void test_promise_example3();
|
void test_promise_example3();
|
||||||
|
|
||||||
void byteAccess();
|
void byteAccess();
|
||||||
};
|
};
|
||||||
@@ -7,28 +7,25 @@
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
QObject::connect(sender, signal, &x, [&success]() { success = true; });
|
QObject::connect(sender, signal, &x, [&success]() { success = true; });
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject::connect(sender, signal, &x, &QEventLoop::quit, Qt::QueuedConnection);
|
QObject::connect(sender, signal, &x, &QEventLoop::quit, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
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...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Connect> void await(Connect... connects) noexcept(false)
|
template <typename... Connect> void await(Connect... connects) noexcept(false)
|
||||||
{
|
{
|
||||||
QEventLoop x;
|
QEventLoop x;
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
@@ -39,24 +36,28 @@ template <typename... Connect> void await(Connect... connects) noexcept(false)
|
|||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
|
||||||
throw std::runtime_error("Failed.");
|
throw std::runtime_error("Failed.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Connect> void awaitTimeout(const int timeoutMs, Connect... connects) noexcept(false)
|
template <typename... Connect> void awaitTimeout(const int timeoutMs, Connect... connects) noexcept(false)
|
||||||
{
|
{
|
||||||
std::unique_ptr<QTimer> t(new QTimer);
|
std::unique_ptr<QTimer> t(new QTimer);
|
||||||
bool timeout = false;
|
bool timeout = false;
|
||||||
|
|
||||||
if (timeoutMs > -1)
|
if (timeoutMs > -1)
|
||||||
{
|
{
|
||||||
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(),
|
||||||
fprintf(stderr, "awaitTimeout: timed out!\n");
|
&QTimer::timeout,
|
||||||
timeout = true;
|
t.get(),
|
||||||
});
|
[&timeout]()
|
||||||
t->start();
|
{
|
||||||
|
fprintf(stderr, "awaitTimeout: timed out!\n");
|
||||||
|
timeout = true;
|
||||||
|
});
|
||||||
|
t->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
await(t.get(), &QTimer::timeout, false, connects...);
|
await(t.get(), &QTimer::timeout, false, connects...);
|
||||||
@@ -64,21 +65,23 @@ template <typename... Connect> void awaitTimeout(const int timeoutMs, Connect...
|
|||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
|
|
||||||
throw std::runtime_error("Timeout.");
|
throw std::runtime_error("Timeout.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 int timeoutMs = 0) noexcept(false)
|
const typename QtPrivate::FunctionPointer<Func2>::Object *sender2,
|
||||||
{
|
Func2 signal2,
|
||||||
|
const int timeoutMs = 0) noexcept(false)
|
||||||
|
{
|
||||||
if (timeoutMs > 0)
|
if (timeoutMs > 0)
|
||||||
{
|
{
|
||||||
awaitTimeout(timeoutMs, sender1, signal1, true, sender2, signal2, false);
|
awaitTimeout(timeoutMs, sender1, signal1, true, sender2, signal2, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await(sender1, signal1, true, sender2, signal2, false);
|
await(sender1, signal1, true, sender2, signal2, false);
|
||||||
}
|
}
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -11,36 +11,36 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class IConnection
|
class IConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IConnection() = default;
|
virtual ~IConnection() = default;
|
||||||
virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0;
|
virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0;
|
||||||
virtual void disconnect() = 0;
|
virtual void disconnect() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DummyConnection : public IConnection
|
class DummyConnection : public IConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void connect(Qt::ConnectionType = Qt::AutoConnection) override {}
|
void connect(Qt::ConnectionType = Qt::AutoConnection) override {}
|
||||||
|
|
||||||
void disconnect() override {}
|
void disconnect() override {}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template <class T> struct ExtractClass;
|
template <class T> struct ExtractClass;
|
||||||
|
|
||||||
template <class T, class Member> struct ExtractClass<Member T::*>
|
template <class T, class Member> struct ExtractClass<Member T::*>
|
||||||
{
|
{
|
||||||
using type = T;
|
using type = T;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class Signal, class Slot> class Connection : public IConnection
|
template <class Signal, class Slot> class Connection : public IConnection
|
||||||
{
|
{
|
||||||
static_assert(std::is_member_function_pointer_v<Signal>, "Must be a pointer to method");
|
static_assert(std::is_member_function_pointer_v<Signal>, "Must be a pointer to method");
|
||||||
static_assert(std::is_member_function_pointer_v<Slot>, "Must be a pointer to method");
|
static_assert(std::is_member_function_pointer_v<Slot>, "Must be a pointer to method");
|
||||||
|
|
||||||
@@ -51,36 +51,39 @@ template <class Signal, class Slot> class Connection : public IConnection
|
|||||||
static_assert(std::is_base_of_v<QObject, Target>, "Must be derived from QObject");
|
static_assert(std::is_base_of_v<QObject, Target>, "Must be derived from QObject");
|
||||||
|
|
||||||
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);
|
||||||
Q_ASSERT(target);
|
Q_ASSERT(target);
|
||||||
Q_ASSERT(slot);
|
Q_ASSERT(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override
|
void connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override
|
||||||
{
|
{
|
||||||
Q_ASSERT(!m_connected);
|
Q_ASSERT(!m_connected);
|
||||||
|
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
|
|
||||||
if (!m_emitter || !m_target)
|
if (!m_emitter || !m_target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(), m_slot, connectionType);
|
m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(), m_slot, connectionType);
|
||||||
Q_ASSERT(m_conn);
|
Q_ASSERT(m_conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disconnect() override
|
void disconnect() override
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_connected);
|
Q_ASSERT(m_connected);
|
||||||
|
|
||||||
if (m_conn)
|
if (m_conn)
|
||||||
QObject::disconnect(m_conn);
|
QObject::disconnect(m_conn);
|
||||||
|
|
||||||
m_connected = false;
|
m_connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -90,13 +93,15 @@ template <class Signal, class Slot> class Connection : public IConnection
|
|||||||
QPointer<Target> m_target;
|
QPointer<Target> m_target;
|
||||||
Slot m_slot;
|
Slot m_slot;
|
||||||
QMetaObject::Connection m_conn;
|
QMetaObject::Connection m_conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+21
-16
@@ -4,21 +4,26 @@
|
|||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
enum class DataModification { eAdded, eModified, eRemoved };
|
enum class DataModification
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& str, DataModification mod)
|
|
||||||
{
|
{
|
||||||
switch (mod)
|
eAdded,
|
||||||
{
|
eModified,
|
||||||
case DataModification::eAdded:
|
eRemoved
|
||||||
str << "DataModification::eAdded";
|
};
|
||||||
break;
|
|
||||||
case DataModification::eModified:
|
inline std::ostream &operator<<(std::ostream &str, DataModification mod)
|
||||||
str << "DataModification::eModified";
|
{
|
||||||
break;
|
switch (mod)
|
||||||
case DataModification::eRemoved:
|
{
|
||||||
str << "DataModification::eRemoved";
|
case DataModification::eAdded:
|
||||||
break;
|
str << "DataModification::eAdded";
|
||||||
}
|
break;
|
||||||
return str;
|
case DataModification::eModified:
|
||||||
|
str << "DataModification::eModified";
|
||||||
|
break;
|
||||||
|
case DataModification::eRemoved:
|
||||||
|
str << "DataModification::eRemoved";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
@@ -9,82 +9,82 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace BitArray
|
namespace BitArray
|
||||||
{
|
{
|
||||||
constexpr inline int bitNumber(int position)
|
constexpr inline int bitNumber(int position)
|
||||||
{
|
|
||||||
return 7 - (position % 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline bool testBit(const T& bitField, int position, bool* oob = nullptr)
|
|
||||||
{
|
|
||||||
const size_t byteNum = position / 8;
|
|
||||||
if (byteNum >= bitField.size())
|
|
||||||
{
|
{
|
||||||
if (oob)
|
return 7 - (position % 8);
|
||||||
*oob = true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (oob)
|
|
||||||
|
template <typename T> inline bool testBit(const T &bitField, int position, bool *oob = nullptr)
|
||||||
|
{
|
||||||
|
const size_t byteNum = position / 8;
|
||||||
|
if (byteNum >= bitField.size())
|
||||||
|
{
|
||||||
|
if (oob)
|
||||||
|
*oob = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (oob)
|
||||||
*oob = false;
|
*oob = false;
|
||||||
|
|
||||||
const typename T::value_type mask = 1 << bitNumber(position);
|
const typename T::value_type mask = 1 << bitNumber(position);
|
||||||
return ((bitField.at(byteNum) & mask) == mask);
|
return ((bitField.at(byteNum) & mask) == mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline bool setBit(T& bitField, int position, bool set = true)
|
template <typename T> inline bool setBit(T &bitField, int position, bool set = true)
|
||||||
{
|
{
|
||||||
const size_t byteNum = position / 8;
|
const size_t byteNum = position / 8;
|
||||||
if (byteNum >= bitField.size())
|
if (byteNum >= bitField.size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const typename T::value_type mask = 1 << bitNumber(position);
|
const typename T::value_type mask = 1 << bitNumber(position);
|
||||||
if (set)
|
if (set)
|
||||||
bitField[byteNum] |= mask;
|
bitField[byteNum] |= mask;
|
||||||
else
|
else
|
||||||
bitField[byteNum] &= ~mask;
|
bitField[byteNum] &= ~mask;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline bool clearBit(T& bitField, int position)
|
template <typename T> inline bool clearBit(T &bitField, int position)
|
||||||
{
|
{
|
||||||
return setBit(bitField, position, false);
|
return setBit(bitField, position, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SUPPORT_QBITARRAY
|
#ifdef SUPPORT_QBITARRAY
|
||||||
template <typename T> inline T convert(const QBitArray& bitArray)
|
template <typename T> inline T convert(const QBitArray &bitArray)
|
||||||
{
|
|
||||||
T ret;
|
|
||||||
ret.resize((bitArray.size() + 7) / 8, 0);
|
|
||||||
|
|
||||||
for (int i = 0; i < bitArray.size(); ++i)
|
|
||||||
{
|
{
|
||||||
|
T ret;
|
||||||
|
ret.resize((bitArray.size() + 7) / 8, 0);
|
||||||
|
|
||||||
|
for (int i = 0; i < bitArray.size(); ++i)
|
||||||
|
{
|
||||||
const size_t byteNum = i / 8;
|
const size_t byteNum = i / 8;
|
||||||
const typename T::value_type mask = (1 << bitNumber(i));
|
const typename T::value_type mask = (1 << bitNumber(i));
|
||||||
if (bitArray[i])
|
if (bitArray[i])
|
||||||
ret[byteNum] |= mask;
|
ret[byteNum] |= mask;
|
||||||
else
|
else
|
||||||
ret[byteNum] &= ~mask;
|
ret[byteNum] &= ~mask;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline QBitArray convert(T& bitField, int realSize)
|
template <typename T> inline QBitArray convert(T &bitField, int realSize)
|
||||||
{
|
|
||||||
QBitArray ba(realSize);
|
|
||||||
for (int32_t i = 0; i < realSize; ++i)
|
|
||||||
{
|
{
|
||||||
|
QBitArray ba(realSize);
|
||||||
|
for (int32_t i = 0; i < realSize; ++i)
|
||||||
|
{
|
||||||
const size_t byteNum = i / 8;
|
const size_t byteNum = i / 8;
|
||||||
const typename T::value_type mask = (1 << bitNumber(i));
|
const typename T::value_type mask = (1 << bitNumber(i));
|
||||||
bool bit = ((bitField[byteNum] & mask) == mask);
|
bool bit = ((bitField[byteNum] & mask) == mask);
|
||||||
ba[i] = bit;
|
ba[i] = bit;
|
||||||
|
}
|
||||||
|
return ba;
|
||||||
}
|
}
|
||||||
return ba;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace BitArray
|
} // namespace BitArray
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -8,30 +8,30 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T, typename S> inline void convert(const S& in, T& out)
|
template <typename T, typename S> inline void convert(const S &in, T &out)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same_v<S, T>, "Try to convert a type to the same type - is useless");
|
static_assert(!std::is_same_v<S, T>, "Try to convert a type to the same type - is useless");
|
||||||
out.reserve(static_cast<int>(in.size()));
|
out.reserve(static_cast<int>(in.size()));
|
||||||
std::copy(in.begin(), in.end(), std::back_inserter(out));
|
std::copy(in.begin(), in.end(), std::back_inserter(out));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename S> inline T convert(const S& in)
|
template <typename T, typename S> inline T convert(const S &in)
|
||||||
{
|
{
|
||||||
static_assert(!std::is_same_v<S, T>, "Try to convert a type to the same type - is useless");
|
static_assert(!std::is_same_v<S, T>, "Try to convert a type to the same type - is useless");
|
||||||
T out;
|
T out;
|
||||||
convert(in, out);
|
convert(in, out);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> inline QByteArray toQByteArray(const T& in)
|
template <typename T> inline QByteArray toQByteArray(const T &in)
|
||||||
{
|
{
|
||||||
return convert<QByteArray>(in);
|
return convert<QByteArray>(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename V = typename T::value_type> bool isInVector(const T& vec, const V& valueToSearch)
|
template <typename T, typename V = typename T::value_type> bool isInVector(const T &vec, const V &valueToSearch)
|
||||||
{
|
{
|
||||||
const auto end = vec.end();
|
const auto end = vec.end();
|
||||||
return std::find(vec.begin(), end, valueToSearch) != end;
|
return std::find(vec.begin(), end, valueToSearch) != end;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+6
-6
@@ -14,11 +14,11 @@ class QImage;
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QPixmap getPixmap(const std::vector<uint8_t>& data);
|
LTSUTILSCORE_EXPORT QPixmap getPixmap(const std::vector<uint8_t> &data);
|
||||||
LTSUTILSCORE_EXPORT QPixmap getPixmap(const QByteArray& data);
|
LTSUTILSCORE_EXPORT QPixmap getPixmap(const QByteArray &data);
|
||||||
LTSUTILSCORE_EXPORT QImage getImage(const std::vector<uint8_t>& data);
|
LTSUTILSCORE_EXPORT QImage getImage(const std::vector<uint8_t> &data);
|
||||||
LTSUTILSCORE_EXPORT QImage getImage(const QByteArray& data);
|
LTSUTILSCORE_EXPORT QImage getImage(const QByteArray &data);
|
||||||
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromPixmap(const QPixmap& pixmap, bool* bIsPng = nullptr);
|
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromPixmap(const QPixmap &pixmap, bool *bIsPng = nullptr);
|
||||||
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromImage(const QImage& image, bool* bIsPng = nullptr);
|
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromImage(const QImage &image, bool *bIsPng = nullptr);
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -3,12 +3,12 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
LtsUtils::LtsPortRange fromQPoint(const QPoint& point)
|
LtsUtils::LtsPortRange fromQPoint(const QPoint &point)
|
||||||
{
|
{
|
||||||
if (point.x() < 1025 || point.y() > 65535 || point.x() > point.y())
|
if (point.x() < 1025 || point.y() > 65535 || point.x() > point.y())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return {static_cast<quint16>(point.x()), static_cast<quint16>(point.y())};
|
return {static_cast<quint16>(point.x()), static_cast<quint16>(point.y())};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
typedef QPair<quint16, quint16> LtsPortRange;
|
typedef QPair<quint16, quint16> LtsPortRange;
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT LtsPortRange fromQPoint(const QPoint& point);
|
LTSUTILSCORE_EXPORT LtsPortRange fromQPoint(const QPoint &point);
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+10
-10
@@ -6,17 +6,17 @@
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString LtsTranslatableIdentifier::translatedText(const char* disambiguation, int n) const
|
const QString LtsTranslatableIdentifier::translatedText(const char *disambiguation, int n) const
|
||||||
{
|
{
|
||||||
if (m_identifier.isEmpty() || m_translationContext == nullptr || m_translatableText == nullptr)
|
if (m_identifier.isEmpty() || m_translationContext == nullptr || m_translatableText == nullptr)
|
||||||
return {};
|
return {};
|
||||||
return QCoreApplication::translate(m_translationContext, m_translatableText, disambiguation, n);
|
return QCoreApplication::translate(m_translationContext, m_translatableText, disambiguation, n);
|
||||||
}
|
}
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+14
-16
@@ -7,29 +7,27 @@
|
|||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
class LTSUTILSCORE_EXPORT LtsTranslatableIdentifier
|
class LTSUTILSCORE_EXPORT LtsTranslatableIdentifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LtsTranslatableIdentifier() : m_translationContext(nullptr), m_translatableText("") {}
|
LtsTranslatableIdentifier()
|
||||||
|
: m_translationContext(nullptr)
|
||||||
LtsTranslatableIdentifier(const QString& identifier, const QObject* context, const char* translatableText);
|
, m_translatableText("")
|
||||||
|
|
||||||
const QString& identifier() const
|
|
||||||
{
|
{
|
||||||
return m_identifier;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString translatedText(const char* disambiguation = nullptr, int n = -1) const;
|
LtsTranslatableIdentifier(const QString &identifier, const QObject *context, const char *translatableText);
|
||||||
|
|
||||||
const QString _context() const
|
const QString &identifier() const { return m_identifier; }
|
||||||
{
|
|
||||||
return QString::fromUtf8(m_translationContext);
|
const QString translatedText(const char *disambiguation = nullptr, int n = -1) const;
|
||||||
}
|
|
||||||
|
const QString _context() const { return QString::fromUtf8(m_translationContext); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_identifier;
|
QString m_identifier;
|
||||||
const char* m_translationContext;
|
const char *m_translationContext;
|
||||||
|
|
||||||
const char* m_translatableText;
|
const char *m_translatableText;
|
||||||
};
|
};
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+1
-1
@@ -18,4 +18,4 @@
|
|||||||
#define LTSUTILSCORE_EXPORT Q_DECL_IMPORT
|
#define LTSUTILSCORE_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
inline bool isPositionTimeOutdated(qint64 curTime, qint64 posTime)
|
inline bool isPositionTimeOutdated(qint64 curTime, qint64 posTime)
|
||||||
{
|
{
|
||||||
|
|
||||||
return curTime > posTime + 11 * 60 * 1000;
|
return curTime > posTime + 11 * 60 * 1000;
|
||||||
}
|
}
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -11,141 +11,135 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T> static inline QString convertToPgString(const std::vector<T>& data)
|
template <typename T> static inline QString convertToPgString(const std::vector<T> &data)
|
||||||
{
|
{
|
||||||
if (data.size() == 0)
|
if (data.size() == 0)
|
||||||
return QLatin1String("{}");
|
return QLatin1String("{}");
|
||||||
QString ret(QLatin1Char('{'));
|
QString ret(QLatin1Char('{'));
|
||||||
for (T i : data)
|
for (T i : data)
|
||||||
ret += QString::number(i) + QLatin1Char(',');
|
ret += QString::number(i) + QLatin1Char(',');
|
||||||
ret.chop(1);
|
ret.chop(1);
|
||||||
ret += QLatin1Char('}');
|
ret += QLatin1Char('}');
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString IntArray::toPgString() const
|
template <> LTSUTILSCORE_EXPORT QString IntArray::toPgString() const
|
||||||
{
|
{
|
||||||
return convertToPgString(m_data);
|
return convertToPgString(m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString BigintArray::toPgString() const
|
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;
|
||||||
|
|
||||||
int idxStart = str.indexOf(QLatin1Char('{'));
|
int idxStart = str.indexOf(QLatin1Char('{'));
|
||||||
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
||||||
if (idxEnd < idxStart)
|
if (idxEnd < idxStart)
|
||||||
return T(result);
|
return T(result);
|
||||||
if (idxStart < 0 && idxEnd < 0)
|
if (idxStart < 0 && idxEnd < 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
idxStart = -1;
|
idxStart = -1;
|
||||||
idxEnd = str.length() + 1;
|
idxEnd = str.length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringView strRef = QStringView(str).mid(idxStart + 1, idxEnd - idxStart - 1);
|
const QStringView strRef = QStringView(str).mid(idxStart + 1, idxEnd - idxStart - 1);
|
||||||
const QVector<QStringView> vec = strRef.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
const QVector<QStringView> vec = strRef.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
||||||
result.reserve(vec.size());
|
result.reserve(vec.size());
|
||||||
for (const QStringView& s : vec)
|
for (const QStringView &s : vec)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
const typename T::Type i = convertFunc(s, &ok);
|
const typename T::Type i = convertFunc(s, &ok);
|
||||||
if (ok)
|
if (ok)
|
||||||
result.push_back(i);
|
result.push_back(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return T(result);
|
return T(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT IntArray IntArray::fromPgString(const QString& str)
|
template <> LTSUTILSCORE_EXPORT IntArray IntArray::fromPgString(const QString &str)
|
||||||
{
|
{
|
||||||
return convertFromPgString<IntArray>(str, [](QStringView val, bool* bOk) { return val.toString().toInt(bOk); });
|
return convertFromPgString<IntArray>(str, [](QStringView val, bool *bOk) { return val.toString().toInt(bOk); });
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
if (data.size() == 0)
|
if (data.size() == 0)
|
||||||
return QLatin1String("{}");
|
return QLatin1String("{}");
|
||||||
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('}');
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString IntArray2D::toPgString() const
|
template <> LTSUTILSCORE_EXPORT QString IntArray2D::toPgString() const
|
||||||
{
|
{
|
||||||
return convertToPgString<IntArray2D::Type>(m_data);
|
return convertToPgString<IntArray2D::Type>(m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString BigintArray2D::toPgString() const
|
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('{'));
|
||||||
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
||||||
if (idxEnd < idxStart)
|
if (idxEnd < idxStart)
|
||||||
return T(ret);
|
return T(ret);
|
||||||
if (idxStart < 0 && idxEnd < 0)
|
if (idxStart < 0 && idxEnd < 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
idxStart = -1;
|
idxStart = -1;
|
||||||
idxEnd = str.length() + 1;
|
idxEnd = str.length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QStringView strRef = QStringView(str).mid(idxStart + 1, idxEnd - idxStart - 1);
|
const QStringView strRef = QStringView(str).mid(idxStart + 1, idxEnd - idxStart - 1);
|
||||||
idxStart = strRef.indexOf(QLatin1Char('{'));
|
idxStart = strRef.indexOf(QLatin1Char('{'));
|
||||||
while (idxStart >= 0)
|
while (idxStart >= 0)
|
||||||
{
|
{
|
||||||
idxEnd = strRef.indexOf(QLatin1Char('}'), idxStart);
|
idxEnd = strRef.indexOf(QLatin1Char('}'), idxStart);
|
||||||
if (idxEnd < 0)
|
if (idxEnd < 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
const QStringView keyValueStr = strRef.mid(idxStart + 1, idxEnd - idxStart - 1);
|
const QStringView keyValueStr = strRef.mid(idxStart + 1, idxEnd - idxStart - 1);
|
||||||
const QVector<QStringView> keyValuePair = keyValueStr.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
const QVector<QStringView> keyValuePair = keyValueStr.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
||||||
if (keyValuePair.size() != 2)
|
if (keyValuePair.size() != 2)
|
||||||
break;
|
break;
|
||||||
const typename T::Type key = convertFunc(keyValuePair.at(0).trimmed());
|
const typename T::Type key = convertFunc(keyValuePair.at(0).trimmed());
|
||||||
const typename T::Type value = convertFunc(keyValuePair.at(1).trimmed());
|
const typename T::Type value = convertFunc(keyValuePair.at(1).trimmed());
|
||||||
ret.insert(std::make_pair(key, value));
|
ret.insert(std::make_pair(key, value));
|
||||||
|
|
||||||
idxStart = strRef.indexOf(QLatin1Char('{'), idxEnd + 1);
|
idxStart = strRef.indexOf(QLatin1Char('{'), idxEnd + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return T(ret);
|
return T(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT IntArray2D IntArray2D::fromPgString(const QString& str)
|
template <> LTSUTILSCORE_EXPORT IntArray2D IntArray2D::fromPgString(const QString &str)
|
||||||
{
|
{
|
||||||
return convertFromPgString2D<IntArray2D>(str, [](QStringView val) { return val.toString().toInt(); });
|
return convertFromPgString2D<IntArray2D>(str, [](QStringView val) { return val.toString().toInt(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT BigintArray2D BigintArray2D::fromPgString(const QString& str)
|
template <> LTSUTILSCORE_EXPORT BigintArray2D BigintArray2D::fromPgString(const QString &str)
|
||||||
{
|
{
|
||||||
return convertFromPgString2D<BigintArray2D>(str, [](QStringView val) { return val.toString().toLongLong(); });
|
return convertFromPgString2D<BigintArray2D>(str, [](QStringView val) { return val.toString().toLongLong(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -9,32 +9,32 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T, typename C> class PgArray
|
template <typename T, typename C> class PgArray
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using Type = T;
|
using Type = T;
|
||||||
using ContainerType = C;
|
using ContainerType = C;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
C m_data;
|
C m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
using IntArray = PgArray<int, std::vector<int>>;
|
using IntArray = PgArray<int, std::vector<int>>;
|
||||||
using BigintArray = PgArray<int64_t, std::vector<int64_t>>;
|
using BigintArray = PgArray<int64_t, std::vector<int64_t>>;
|
||||||
|
|
||||||
using IntArray2D = PgArray<int, std::map<int, int>>;
|
using IntArray2D = PgArray<int, std::map<int, int>>;
|
||||||
using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>;
|
using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>;
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -7,74 +7,76 @@
|
|||||||
namespace LtsUtils
|
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);
|
||||||
setFunction(function);
|
setFunction(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Promise::setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)>& function)
|
void Promise::setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function)
|
||||||
{
|
{
|
||||||
if (!function || m_functionAlreadySet)
|
if (!function || m_functionAlreadySet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_functionAlreadySet = true;
|
m_functionAlreadySet = true;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
m_timeout->stop();
|
m_timeout->stop();
|
||||||
m_timeout->setInterval(interval);
|
m_timeout->setInterval(interval);
|
||||||
m_timeoutSet = (interval != 0);
|
m_timeoutSet = (interval != 0);
|
||||||
|
|
||||||
if (interval != 0 && m_functionAlreadySet)
|
if (interval != 0 && m_functionAlreadySet)
|
||||||
m_timeout->start();
|
m_timeout->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Promise::slotTimeout()
|
void Promise::slotTimeout()
|
||||||
{
|
{
|
||||||
reject(QStringLiteral("timeout"));
|
reject(QStringLiteral("timeout"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Promise::resolve(const QVariant& value)
|
void Promise::resolve(const QVariant &value)
|
||||||
{
|
{
|
||||||
if (m_resultSet)
|
if (m_resultSet)
|
||||||
return;
|
return;
|
||||||
m_resultSet = true;
|
m_resultSet = true;
|
||||||
|
|
||||||
m_timeout->stop();
|
m_timeout->stop();
|
||||||
m_resolveFn(value);
|
m_resolveFn(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Promise::reject(const QVariant& value)
|
void Promise::reject(const QVariant &value)
|
||||||
{
|
{
|
||||||
if (m_resultSet)
|
if (m_resultSet)
|
||||||
return;
|
return;
|
||||||
m_resultSet = true;
|
m_resultSet = true;
|
||||||
|
|
||||||
m_timeout->stop();
|
m_timeout->stop();
|
||||||
m_rejectFn(value);
|
m_rejectFn(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise& Promise::resolved(ResultFunction resolveFn)
|
Promise &Promise::resolved(ResultFunction resolveFn)
|
||||||
{
|
{
|
||||||
m_resolveFn = resolveFn;
|
m_resolveFn = resolveFn;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise& Promise::rejected(ResultFunction rejectFn)
|
Promise &Promise::rejected(ResultFunction rejectFn)
|
||||||
{
|
{
|
||||||
m_rejectFn = rejectFn;
|
m_rejectFn = rejectFn;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -10,39 +10,38 @@ class QTimer;
|
|||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
typedef std::function<void(const QVariant& value)> RawResultFunction;
|
typedef std::function<void(const QVariant &value)> RawResultFunction;
|
||||||
typedef const RawResultFunction& ResultFunction;
|
typedef const RawResultFunction &ResultFunction;
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT Promise : public QObject
|
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);
|
||||||
|
|
||||||
void resolve(const QVariant& value = QVariant());
|
void resolve(const QVariant &value = QVariant());
|
||||||
|
|
||||||
void reject(const QVariant& value = QVariant());
|
void reject(const QVariant &value = QVariant());
|
||||||
|
|
||||||
void setTimeout(int interval);
|
void setTimeout(int interval);
|
||||||
|
|
||||||
Promise& resolved(ResultFunction resolveFn);
|
Promise &resolved(ResultFunction resolveFn);
|
||||||
|
|
||||||
Promise& rejected(ResultFunction rejectFn);
|
Promise &rejected(ResultFunction rejectFn);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RawResultFunction m_resolveFn;
|
RawResultFunction m_resolveFn;
|
||||||
RawResultFunction m_rejectFn;
|
RawResultFunction m_rejectFn;
|
||||||
bool m_functionAlreadySet;
|
bool m_functionAlreadySet;
|
||||||
QTimer* m_timeout;
|
QTimer *m_timeout;
|
||||||
bool m_resultSet;
|
bool m_resultSet;
|
||||||
bool m_timeoutSet;
|
bool m_timeoutSet;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotTimeout();
|
void slotTimeout();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+76
-54
@@ -9,57 +9,72 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
void PromiseExample1_Class::doSomethingAsync1()
|
void PromiseExample1_Class::doSomethingAsync1()
|
||||||
{
|
{
|
||||||
QTimer::singleShot(200, this, [this]() { emit signalDone1(true); });
|
QTimer::singleShot(200, this, [this]() { emit signalDone1(true); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void PromiseExample1_Class::doSomethingAsync2()
|
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,
|
||||||
if (!didThisWork)
|
&PromiseExample1_Class::signalDone1,
|
||||||
{
|
this,
|
||||||
|
[this, c, resolve, reject](bool didThisWork)
|
||||||
|
{
|
||||||
|
if (!didThisWork)
|
||||||
|
{
|
||||||
|
|
||||||
reject(QStringLiteral("First Action did not succeed"));
|
reject(QStringLiteral("First Action did not succeed"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
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
|
||||||
reject(QStringLiteral("Second Action did not succeed"));
|
reject(QStringLiteral("Second Action did not succeed"));
|
||||||
});
|
});
|
||||||
|
|
||||||
c->doSomethingAsync2();
|
c->doSomethingAsync2();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
c->doSomethingAsync1();
|
c->doSomethingAsync1();
|
||||||
};
|
};
|
||||||
Promise* p = new Promise(func, this);
|
Promise *p = new Promise(func, this);
|
||||||
|
|
||||||
p->resolved([this](const QVariant& value) {
|
p->resolved(
|
||||||
qDebug() << "example1 promise succeeded! 'someNumberThatReturns' was" << value;
|
[this](const QVariant &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(
|
||||||
[](ResultFunction, ResultFunction) {
|
[](ResultFunction, ResultFunction) {
|
||||||
@@ -69,32 +84,39 @@ PromiseExample2::PromiseExample2(QObject* parent) : QObject(parent), m_success(f
|
|||||||
|
|
||||||
p->setTimeout(1000);
|
p->setTimeout(1000);
|
||||||
|
|
||||||
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(
|
||||||
QVERIFY2(val == QStringLiteral("timeout"), "Promise didn't reject with string \"timeout\"");
|
[this](const QVariant &val)
|
||||||
qDebug() << "Promise rejected as expected";
|
{
|
||||||
m_success = true;
|
QVERIFY2(val == QStringLiteral("timeout"), "Promise didn't reject with string \"timeout\"");
|
||||||
});
|
qDebug() << "Promise rejected as expected";
|
||||||
}
|
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);
|
||||||
|
|
||||||
p->setTimeout(1000);
|
p->setTimeout(1000);
|
||||||
|
|
||||||
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(
|
||||||
qDebug() << "rejected with val" << val;
|
[this](const QVariant &val)
|
||||||
QVERIFY2(val == QString(), "Promise didn't reject with an expected empty string.");
|
{
|
||||||
QVERIFY2(!m_alreadyRejected, "Promise rejected more than once");
|
qDebug() << "rejected with val" << val;
|
||||||
|
QVERIFY2(val == QString(), "Promise didn't reject with an expected empty string.");
|
||||||
|
QVERIFY2(!m_alreadyRejected, "Promise rejected more than once");
|
||||||
|
|
||||||
m_alreadyRejected = true;
|
m_alreadyRejected = true;
|
||||||
qDebug() << "Promise rejected as expected";
|
qDebug() << "Promise rejected as expected";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+18
-27
@@ -5,8 +5,8 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class PromiseExample1_Class : public QObject
|
class PromiseExample1_Class : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
using QObject::QObject;
|
using QObject::QObject;
|
||||||
@@ -17,52 +17,43 @@ class PromiseExample1_Class : public QObject
|
|||||||
signals:
|
signals:
|
||||||
void signalDone1(bool didThisWork);
|
void signalDone1(bool didThisWork);
|
||||||
void signalDone2(bool didThisWork, int someNumberThatReturns);
|
void signalDone2(bool didThisWork, int someNumberThatReturns);
|
||||||
};
|
};
|
||||||
|
|
||||||
class PromiseExample1 : public QObject
|
class PromiseExample1 : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PromiseExample2 : public QObject
|
class PromiseExample2 : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PromiseExample3 : public QObject
|
class PromiseExample3 : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
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;
|
||||||
bool m_alreadyRejected;
|
bool m_alreadyRejected;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+86
-84
@@ -8,8 +8,8 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename T> void inline set8Byte(const T in, QByteArray& out)
|
template <typename T> void inline set8Byte(const T in, QByteArray &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
out += (in & 0xFF00000000000000UL) >> 56;
|
out += (in & 0xFF00000000000000UL) >> 56;
|
||||||
out += (in & 0x00FF000000000000UL) >> 48;
|
out += (in & 0x00FF000000000000UL) >> 48;
|
||||||
@@ -19,34 +19,35 @@ template <typename T> void inline set8Byte(const T in, QByteArray& out)
|
|||||||
out += (in & 0x0000000000FF0000UL) >> 16;
|
out += (in & 0x0000000000FF0000UL) >> 16;
|
||||||
out += (in & 0x000000000000FF00UL) >> 8;
|
out += (in & 0x000000000000FF00UL) >> 8;
|
||||||
out += (in & 0x00000000000000FFUL);
|
out += (in & 0x00000000000000FFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> void inline set8Byte(const double in, QByteArray& out)
|
template <> void inline set8Byte(const double in, QByteArray &out)
|
||||||
{
|
{
|
||||||
union hack {
|
union hack
|
||||||
double d;
|
{
|
||||||
int64_t i;
|
double d;
|
||||||
|
int64_t i;
|
||||||
} h;
|
} h;
|
||||||
|
|
||||||
h.d = in;
|
h.d = in;
|
||||||
set8Byte(h.i, out);
|
set8Byte(h.i, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get8Byte(const QByteArray& baData, size_t& pos, T& out)
|
template <typename T> bool inline get8Byte(const QByteArray &baData, size_t &pos, T &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
static_assert(sizeof(T) >= 8, "sizeof(out) is smaller than 8 bytes - will not fit");
|
static_assert(sizeof(T) >= 8, "sizeof(out) is smaller than 8 bytes - will not fit");
|
||||||
out = T();
|
out = T();
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 8)
|
if (size_t(baData.size()) < pos + 8)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char* data = baData.data() + pos;
|
const char *data = baData.data() + pos;
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
if (std::numeric_limits<T>::is_signed)
|
||||||
out |= static_cast<signed long long>(data[0]) << 56;
|
out |= static_cast<signed long long>(data[0]) << 56;
|
||||||
else
|
else
|
||||||
out |= (data[0] & 0xFFULL) << 56;
|
out |= (data[0] & 0xFFULL) << 56;
|
||||||
out |= (data[1] & 0xFFULL) << 48;
|
out |= (data[1] & 0xFFULL) << 48;
|
||||||
out |= (data[2] & 0xFFULL) << 40;
|
out |= (data[2] & 0xFFULL) << 40;
|
||||||
out |= (data[3] & 0xFFULL) << 32;
|
out |= (data[3] & 0xFFULL) << 32;
|
||||||
@@ -58,59 +59,60 @@ template <typename T> bool inline get8Byte(const QByteArray& baData, size_t& pos
|
|||||||
pos += 8;
|
pos += 8;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> bool inline get8Byte(const QByteArray& baData, size_t& pos, double& out)
|
template <> bool inline get8Byte(const QByteArray &baData, size_t &pos, double &out)
|
||||||
{
|
{
|
||||||
out = 0.;
|
out = 0.;
|
||||||
|
|
||||||
union hack {
|
union hack
|
||||||
double d;
|
{
|
||||||
int64_t i;
|
double d;
|
||||||
|
int64_t i;
|
||||||
} h;
|
} h;
|
||||||
|
|
||||||
if (!get8Byte(baData, pos, h.i))
|
if (!get8Byte(baData, pos, h.i))
|
||||||
return false;
|
return false;
|
||||||
out = h.d;
|
out = h.d;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get8Byte(const QByteArray& data, T& out)
|
template <typename T> bool inline get8Byte(const QByteArray &data, T &out)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
return get8Byte(data, pos, out);
|
return get8Byte(data, pos, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void inline set4Byte(const T in, QByteArray& out)
|
template <typename T> void inline set4Byte(const T in, QByteArray &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
out += (in & 0xFF000000) >> 24;
|
out += (in & 0xFF000000) >> 24;
|
||||||
out += (in & 0x00FF0000) >> 16;
|
out += (in & 0x00FF0000) >> 16;
|
||||||
out += (in & 0x0000FF00) >> 8;
|
out += (in & 0x0000FF00) >> 8;
|
||||||
out += (in & 0x000000FF);
|
out += (in & 0x000000FF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> void inline set4Byte(const double in, QByteArray& out)
|
template <> void inline set4Byte(const double in, QByteArray &out)
|
||||||
{
|
{
|
||||||
int tmp = qRound(in);
|
int tmp = qRound(in);
|
||||||
return set4Byte(tmp, out);
|
return set4Byte(tmp, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get4Byte(const QByteArray& baData, size_t& pos, T& out)
|
template <typename T> bool inline get4Byte(const QByteArray &baData, size_t &pos, T &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
static_assert(sizeof(T) >= 4, "sizeof(out) is smaller than 4 bytes - will not fit");
|
static_assert(sizeof(T) >= 4, "sizeof(out) is smaller than 4 bytes - will not fit");
|
||||||
out = T();
|
out = T();
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 4)
|
if (size_t(baData.size()) < pos + 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char* data = baData.data() + pos;
|
const char *data = baData.data() + pos;
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
if (std::numeric_limits<T>::is_signed)
|
||||||
out |= data[0] << 24;
|
out |= data[0] << 24;
|
||||||
else
|
else
|
||||||
out |= (data[0] & 0xFFU) << 24;
|
out |= (data[0] & 0xFFU) << 24;
|
||||||
out |= (data[1] & 0xFFU) << 16;
|
out |= (data[1] & 0xFFU) << 16;
|
||||||
out |= (data[2] & 0xFFU) << 8;
|
out |= (data[2] & 0xFFU) << 8;
|
||||||
out |= (data[3] & 0xFFU);
|
out |= (data[3] & 0xFFU);
|
||||||
@@ -118,124 +120,124 @@ template <typename T> bool inline get4Byte(const QByteArray& baData, size_t& pos
|
|||||||
pos += 4;
|
pos += 4;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> bool inline get4Byte(const QByteArray& baData, size_t& pos, double& out)
|
template <> bool inline get4Byte(const QByteArray &baData, size_t &pos, double &out)
|
||||||
{
|
{
|
||||||
out = 0.;
|
out = 0.;
|
||||||
int tmp;
|
int tmp;
|
||||||
if (!get4Byte(baData, pos, tmp))
|
if (!get4Byte(baData, pos, tmp))
|
||||||
return false;
|
return false;
|
||||||
out = tmp;
|
out = tmp;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get4Byte(const QByteArray& data, T& out)
|
template <typename T> bool inline get4Byte(const QByteArray &data, T &out)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
return get4Byte(data, pos, out);
|
return get4Byte(data, pos, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void inline set3Byte(const T in, QByteArray& out)
|
template <typename T> void inline set3Byte(const T in, QByteArray &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
out += (in & 0x00FF0000) >> 16;
|
out += (in & 0x00FF0000) >> 16;
|
||||||
out += (in & 0x0000FF00) >> 8;
|
out += (in & 0x0000FF00) >> 8;
|
||||||
out += (in & 0x000000FF);
|
out += (in & 0x000000FF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get3Byte(const QByteArray& baData, size_t& pos, T& out)
|
template <typename T> bool inline get3Byte(const QByteArray &baData, size_t &pos, T &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
static_assert(sizeof(T) >= 3, "sizeof(out) is smaller than 3 bytes - will not fit");
|
static_assert(sizeof(T) >= 3, "sizeof(out) is smaller than 3 bytes - will not fit");
|
||||||
out = T();
|
out = T();
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 3)
|
if (size_t(baData.size()) < pos + 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char* data = baData.data() + pos;
|
const char *data = baData.data() + pos;
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
if (std::numeric_limits<T>::is_signed)
|
||||||
out |= data[0] << 16;
|
out |= data[0] << 16;
|
||||||
else
|
else
|
||||||
out |= (data[0] & 0xFFU) << 16;
|
out |= (data[0] & 0xFFU) << 16;
|
||||||
out |= (data[1] & 0xFFU) << 8;
|
out |= (data[1] & 0xFFU) << 8;
|
||||||
out |= (data[2] & 0xFFU);
|
out |= (data[2] & 0xFFU);
|
||||||
|
|
||||||
pos += 3;
|
pos += 3;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get3Byte(const QByteArray& data, T& out)
|
template <typename T> bool inline get3Byte(const QByteArray &data, T &out)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
return get3Byte(data, pos, out);
|
return get3Byte(data, pos, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void inline set2Byte(const T in, QByteArray& out)
|
template <typename T> void inline set2Byte(const T in, QByteArray &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
out += (in & 0x0000FF00) >> 8;
|
out += (in & 0x0000FF00) >> 8;
|
||||||
out += (in & 0x000000FF);
|
out += (in & 0x000000FF);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get2Byte(const QByteArray& baData, size_t& pos, T& out)
|
template <typename T> bool inline get2Byte(const QByteArray &baData, size_t &pos, T &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
static_assert(sizeof(T) >= 2, "sizeof(out) is smaller than 2 bytes - will not fit");
|
static_assert(sizeof(T) >= 2, "sizeof(out) is smaller than 2 bytes - will not fit");
|
||||||
out = T();
|
out = T();
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 2)
|
if (size_t(baData.size()) < pos + 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const char* data = baData.data() + pos;
|
const char *data = baData.data() + pos;
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
if (std::numeric_limits<T>::is_signed)
|
||||||
out |= data[0] << 8;
|
out |= data[0] << 8;
|
||||||
else
|
else
|
||||||
out |= (data[0] & 0xFFU) << 8;
|
out |= (data[0] & 0xFFU) << 8;
|
||||||
out |= data[1] & 0xFFU;
|
out |= data[1] & 0xFFU;
|
||||||
|
|
||||||
pos += 2;
|
pos += 2;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get2Byte(const QByteArray& data, T& out)
|
template <typename T> bool inline get2Byte(const QByteArray &data, T &out)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
return get2Byte(data, pos, out);
|
return get2Byte(data, pos, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void inline set1Byte(const T in, QByteArray& out)
|
template <typename T> void inline set1Byte(const T in, QByteArray &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
unsigned char c = static_cast<unsigned char>(in);
|
unsigned char c = static_cast<unsigned char>(in);
|
||||||
out += c;
|
out += c;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get1Byte(const QByteArray& baData, size_t& pos, T& out)
|
template <typename T> bool inline get1Byte(const QByteArray &baData, size_t &pos, T &out)
|
||||||
{
|
{
|
||||||
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
static_assert(std::is_integral_v<T> || std::is_enum_v<T>, "Only integrals allowed for raw byte accessd");
|
||||||
out = T();
|
out = T();
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 1)
|
if (size_t(baData.size()) < pos + 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
if (std::numeric_limits<T>::is_signed)
|
||||||
out = (T)(baData.at(pos));
|
out = (T)(baData.at(pos));
|
||||||
else
|
else
|
||||||
out = (T)(baData.at(pos) & 0xFF);
|
out = (T)(baData.at(pos) & 0xFF);
|
||||||
|
|
||||||
pos += 1;
|
pos += 1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool inline get1Byte(const QByteArray& data, T& out)
|
template <typename T> bool inline get1Byte(const QByteArray &data, T &out)
|
||||||
{
|
{
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
return get1Byte(data, pos, out);
|
return get1Byte(data, pos, out);
|
||||||
}
|
}
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -5,69 +5,72 @@
|
|||||||
namespace LtsUtils
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint3D QPlane3D::intersection(const QPoint3D& point, const QPoint3D& direction) const
|
QPoint3D QPlane3D::intersection(const QPoint3D &point, const QPoint3D &direction) const
|
||||||
{
|
{
|
||||||
const double dotProduct = QPoint3D::dotProduct(direction, m_normal);
|
const double dotProduct = QPoint3D::dotProduct(direction, m_normal);
|
||||||
if (qFuzzyIsNull(dotProduct))
|
if (qFuzzyIsNull(dotProduct))
|
||||||
return inPlane(point) ? point : QPoint3D();
|
return inPlane(point) ? point : QPoint3D();
|
||||||
const double distance = distanceTo(point) / std::abs(dotProduct);
|
const double distance = distanceTo(point) / std::abs(dotProduct);
|
||||||
return point + distance * direction;
|
return point + distance * direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QPlane3D::intersects(const QPoint3D& direction) const
|
bool QPlane3D::intersects(const QPoint3D &direction) const
|
||||||
{
|
{
|
||||||
return !isParallel(direction);
|
return !isParallel(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QPlane3D::isParallel(const QPoint3D& direction) const
|
bool QPlane3D::isParallel(const QPoint3D &direction) const
|
||||||
{
|
{
|
||||||
return qFuzzyIsNull(QPoint3D::dotProduct(m_normal, direction));
|
return qFuzzyIsNull(QPoint3D::dotProduct(m_normal, direction));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QPlane3D::inPlane(const QPoint3D& point) const
|
bool QPlane3D::inPlane(const QPoint3D &point) const
|
||||||
{
|
{
|
||||||
if (point == m_pos)
|
if (point == m_pos)
|
||||||
return true;
|
return true;
|
||||||
return qFuzzyIsNull(QPoint3D::dotProduct(m_normal, point - m_pos));
|
return qFuzzyIsNull(QPoint3D::dotProduct(m_normal, point - m_pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
double QPlane3D::distanceTo(const QPoint3D& point) const
|
double QPlane3D::distanceTo(const QPoint3D &point) const
|
||||||
{
|
{
|
||||||
return QPoint3D::dotProduct(point - m_pos, m_normal);
|
return QPoint3D::dotProduct(point - m_pos, m_normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool QPolygon3D::containsPoint(const QPoint3D& point) const
|
bool QPolygon3D::containsPoint(const QPoint3D &point) const
|
||||||
{
|
{
|
||||||
if (!inPlane(point))
|
if (!inPlane(point))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (contains(point))
|
if (contains(point))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
double angleSum = 0.;
|
double angleSum = 0.;
|
||||||
double cosTheta = 0.;
|
double cosTheta = 0.;
|
||||||
const int numberOfVertices = m_vertices.size();
|
const int numberOfVertices = m_vertices.size();
|
||||||
for (int i = 0; i < m_vertices.size(); ++i)
|
for (int i = 0; i < m_vertices.size(); ++i)
|
||||||
{
|
{
|
||||||
const QPoint3D& first = m_vertices[i % numberOfVertices] - point;
|
const QPoint3D &first = m_vertices[i % numberOfVertices] - point;
|
||||||
const QPoint3D& second = m_vertices[(i + 1) % numberOfVertices] - point;
|
const QPoint3D &second = m_vertices[(i + 1) % numberOfVertices] - point;
|
||||||
|
|
||||||
cosTheta = QPoint3D::dotProduct(first, second) / (first.length() * second.length());
|
cosTheta = QPoint3D::dotProduct(first, second) / (first.length() * second.length());
|
||||||
angleSum += acos(cosTheta);
|
angleSum += acos(cosTheta);
|
||||||
}
|
}
|
||||||
return qFuzzyIsNull(M_2_PI - angleSum);
|
return qFuzzyIsNull(M_2_PI - angleSum);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -11,42 +11,27 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT QPlane3D
|
class LTSUTILSCORE_EXPORT QPlane3D
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QPlane3D(const QPoint3D& pos, const QPoint3D& vec1, const QPoint3D& vec2);
|
QPlane3D(const QPoint3D &pos, const QPoint3D &vec1, const QPoint3D &vec2);
|
||||||
|
|
||||||
QPoint3D intersection(const QPoint3D& point, const QPoint3D& direction) const;
|
QPoint3D intersection(const QPoint3D &point, const QPoint3D &direction) const;
|
||||||
bool intersects(const QPoint3D& direction) const;
|
bool intersects(const QPoint3D &direction) const;
|
||||||
bool isParallel(const QPoint3D& direction) const;
|
bool isParallel(const QPoint3D &direction) const;
|
||||||
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;
|
||||||
@@ -54,23 +39,20 @@ class LTSUTILSCORE_EXPORT QPlane3D
|
|||||||
QPoint3D m_vec2;
|
QPoint3D m_vec2;
|
||||||
QPoint3D m_normal;
|
QPoint3D m_normal;
|
||||||
double m_planeC;
|
double m_planeC;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT QPolygon3D : public QPlane3D
|
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;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<QPoint3D> m_vertices;
|
QVector<QPoint3D> m_vertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -7,14 +7,14 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
QDataStream& operator<<(QDataStream& s, const QPoint3D& p)
|
QDataStream &operator<<(QDataStream &s, const QPoint3D &p)
|
||||||
{
|
{
|
||||||
s << p.x() << p.y() << p.z();
|
s << p.x() << p.y() << p.z();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream& operator>>(QDataStream& s, QPoint3D& p)
|
QDataStream &operator>>(QDataStream &s, QPoint3D &p)
|
||||||
{
|
{
|
||||||
double x, y, z;
|
double x, y, z;
|
||||||
s >> x;
|
s >> x;
|
||||||
p.rx() = x;
|
p.rx() = x;
|
||||||
@@ -23,6 +23,6 @@ QDataStream& operator>>(QDataStream& s, QPoint3D& p)
|
|||||||
s >> z;
|
s >> z;
|
||||||
p.rz() = z;
|
p.rz() = z;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -13,15 +13,24 @@
|
|||||||
namespace LtsUtils
|
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())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,275 +43,244 @@ class QPoint3D
|
|||||||
constexpr inline void setY(double ypos);
|
constexpr inline void setY(double ypos);
|
||||||
constexpr inline void setZ(double zpos);
|
constexpr inline void setZ(double zpos);
|
||||||
|
|
||||||
constexpr inline double& rx();
|
constexpr inline double &rx();
|
||||||
constexpr inline double& ry();
|
constexpr inline double &ry();
|
||||||
constexpr inline double& rz();
|
constexpr inline double &rz();
|
||||||
|
|
||||||
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()
|
||||||
{
|
{
|
||||||
double len = xp * xp + yp * yp + zp * zp;
|
double len = xp * xp + yp * yp + zp * zp;
|
||||||
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
|
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
len = std::sqrt(len);
|
len = std::sqrt(len);
|
||||||
|
|
||||||
xp /= len;
|
xp /= len;
|
||||||
yp /= len;
|
yp /= len;
|
||||||
zp /= len;
|
zp /= len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QPoint3D normalized() const
|
inline QPoint3D normalized() const
|
||||||
{
|
{
|
||||||
double len = xp * xp + yp * yp + zp * zp;
|
double len = xp * xp + yp * yp + zp * zp;
|
||||||
if (qFuzzyIsNull(len - 1.0f))
|
if (qFuzzyIsNull(len - 1.0f))
|
||||||
return *this;
|
return *this;
|
||||||
else if (!qFuzzyIsNull(len))
|
else if (!qFuzzyIsNull(len))
|
||||||
return *this / std::sqrt(len);
|
return *this / std::sqrt(len);
|
||||||
else
|
else
|
||||||
return QPoint3D(*this);
|
return QPoint3D(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void rotate(const double& phi, const Axis& axis)
|
inline void rotate(const double &phi, const Axis &axis)
|
||||||
{
|
{
|
||||||
const double sin = std::sin(phi);
|
const double sin = std::sin(phi);
|
||||||
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: {
|
|
||||||
const double _xp = (cos * xp) + (sin * zp);
|
|
||||||
const double _zp = (-sin * xp) + (cos * zp);
|
|
||||||
xp = _xp;
|
|
||||||
zp = _zp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Axis::Z: {
|
|
||||||
const double _xp = (cos * xp) - (sin * yp);
|
|
||||||
const double _yp = (sin * xp) + (cos * yp);
|
|
||||||
xp = _xp;
|
|
||||||
yp = _yp;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
case Axis::Y:
|
||||||
|
{
|
||||||
|
const double _xp = (cos * xp) + (sin * zp);
|
||||||
|
const double _zp = (-sin * xp) + (cos * zp);
|
||||||
|
xp = _xp;
|
||||||
|
zp = _zp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Axis::Z:
|
||||||
|
{
|
||||||
|
const double _xp = (cos * xp) - (sin * yp);
|
||||||
|
const double _yp = (sin * xp) + (cos * yp);
|
||||||
|
xp = _xp;
|
||||||
|
yp = _yp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline QPoint3D rotated(const double& phi, const Axis& axis) const
|
inline QPoint3D rotated(const double &phi, const Axis &axis) const
|
||||||
{
|
{
|
||||||
QPoint3D p(*this);
|
QPoint3D p(*this);
|
||||||
p.rotate(phi, axis);
|
p.rotate(phi, axis);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline double distanceToLine(const QPoint3D& point, const QPoint3D& direction) const
|
inline double distanceToLine(const QPoint3D &point, const QPoint3D &direction) const
|
||||||
{
|
|
||||||
if (direction.isNull())
|
|
||||||
return (*this - point).length();
|
|
||||||
QPoint3D p = point + dotProduct(*this - point, direction) * direction;
|
|
||||||
return (*this - p).length();
|
|
||||||
}
|
|
||||||
inline double distanceToPlane(const QPoint3D& plane, const QPoint3D& normal) const
|
|
||||||
{
|
|
||||||
return dotProduct(*this - plane, normal);
|
|
||||||
}
|
|
||||||
inline double distanceToPlane(const QPoint3D& plane1, const QPoint3D& plane2, const QPoint3D& plane3) const
|
|
||||||
{
|
|
||||||
QPoint3D n = normal(plane2 - plane1, plane3 - plane1);
|
|
||||||
return dotProduct(*this - plane1, n);
|
|
||||||
}
|
|
||||||
inline double distanceToPoint(const QPoint3D& point) const
|
|
||||||
{
|
{
|
||||||
|
if (direction.isNull())
|
||||||
return (*this - point).length();
|
return (*this - point).length();
|
||||||
|
QPoint3D p = point + dotProduct(*this - point, direction) * direction;
|
||||||
|
return (*this - p).length();
|
||||||
|
}
|
||||||
|
inline double distanceToPlane(const QPoint3D &plane, const QPoint3D &normal) const { return dotProduct(*this - plane, normal); }
|
||||||
|
inline double distanceToPlane(const QPoint3D &plane1, const QPoint3D &plane2, const QPoint3D &plane3) const
|
||||||
|
{
|
||||||
|
QPoint3D n = normal(plane2 - plane1, plane3 - plane1);
|
||||||
|
return dotProduct(*this - plane1, n);
|
||||||
|
}
|
||||||
|
inline double distanceToPoint(const QPoint3D &point) const { 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 QPoint3D operator+(const QPoint3D &p1, const QPoint3D &p2) { 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) { return QPoint3D(p1.xp - p2.xp, p1.yp - p2.yp, p1.zp - p2.zp); }
|
||||||
|
|
||||||
|
friend constexpr inline QPoint3D operator*(const QPoint3D &p1, double factor) { return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor); }
|
||||||
|
|
||||||
|
friend constexpr inline QPoint3D operator*(double factor, const QPoint3D &p1) { return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor); }
|
||||||
|
|
||||||
|
friend constexpr inline QPoint3D operator/(const QPoint3D &p1, double factor) { return QPoint3D(p1.xp / factor, p1.yp / factor, p1.zp / factor); }
|
||||||
|
|
||||||
|
constexpr inline QPoint3D &operator+=(const QPoint3D &o)
|
||||||
|
{
|
||||||
|
xp += o.xp;
|
||||||
|
yp += o.yp;
|
||||||
|
zp += o.zp;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr inline bool operator==(const QPoint3D& p1, const QPoint3D& p2);
|
constexpr inline QPoint3D &operator-=(const QPoint3D &o)
|
||||||
friend constexpr inline bool 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);
|
xp -= o.xp;
|
||||||
|
yp -= o.yp;
|
||||||
|
zp -= o.zp;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr inline QPoint3D operator-(const QPoint3D& p1, const QPoint3D& p2)
|
constexpr inline QPoint3D &operator*=(double factor)
|
||||||
{
|
{
|
||||||
return QPoint3D(p1.xp - p2.xp, p1.yp - p2.yp, p1.zp - p2.zp);
|
xp *= factor;
|
||||||
|
yp *= factor;
|
||||||
|
zp *= factor;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr inline QPoint3D operator*(const QPoint3D& p1, double factor)
|
constexpr inline QPoint3D &operator/=(double divisor)
|
||||||
{
|
{
|
||||||
return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor);
|
xp /= divisor;
|
||||||
|
yp /= divisor;
|
||||||
|
zp /= divisor;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr inline QPoint3D operator*(double factor, const QPoint3D& p1)
|
constexpr static inline double dotProduct(const QPoint3D &v1, const QPoint3D &v2) { return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; }
|
||||||
|
|
||||||
|
constexpr static inline QPoint3D crossProduct(const QPoint3D &v1, const QPoint3D &v2)
|
||||||
{
|
{
|
||||||
return QPoint3D(p1.xp * factor, p1.yp * factor, p1.zp * factor);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend constexpr inline QPoint3D operator/(const QPoint3D& p1, double factor)
|
static inline QPoint3D normal(const QPoint3D &v1, const QPoint3D &v2) { return crossProduct(v1, v2).normalized(); }
|
||||||
{
|
|
||||||
return QPoint3D(p1.xp / factor, p1.yp / factor, p1.zp / factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline QPoint3D& operator+=(const QPoint3D& o)
|
static inline QPoint3D normal(const QPoint3D &v1, const QPoint3D &v2, const QPoint3D &v3) { return crossProduct((v2 - v1), (v3 - v1)).normalized(); }
|
||||||
{
|
|
||||||
xp += o.xp;
|
|
||||||
yp += o.yp;
|
|
||||||
zp += o.zp;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline QPoint3D& operator-=(const QPoint3D& o)
|
friend inline bool qFuzzyCompare(const QPoint3D &v1, const QPoint3D &v2)
|
||||||
{
|
{
|
||||||
xp -= o.xp;
|
return ::qFuzzyCompare(v1.xp, v2.xp) && ::qFuzzyCompare(v1.yp, v2.yp) && ::qFuzzyCompare(v1.zp, v2.zp);
|
||||||
yp -= o.yp;
|
|
||||||
zp -= o.zp;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline QPoint3D& operator*=(double factor)
|
|
||||||
{
|
|
||||||
xp *= factor;
|
|
||||||
yp *= factor;
|
|
||||||
zp *= factor;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline QPoint3D& operator/=(double divisor)
|
|
||||||
{
|
|
||||||
xp /= divisor;
|
|
||||||
yp /= divisor;
|
|
||||||
zp /= divisor;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr static inline double dotProduct(const QPoint3D& v1, const QPoint3D& v2)
|
|
||||||
{
|
|
||||||
return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline QPoint3D normal(const QPoint3D& v1, const QPoint3D& v2)
|
|
||||||
{
|
|
||||||
return crossProduct(v1, v2).normalized();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline QPoint3D normal(const QPoint3D& v1, const QPoint3D& v2, const QPoint3D& v3)
|
|
||||||
{
|
|
||||||
return crossProduct((v2 - v1), (v3 - v1)).normalized();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend inline bool qFuzzyCompare(const QPoint3D& v1, const QPoint3D& v2)
|
|
||||||
{
|
|
||||||
return ::qFuzzyCompare(v1.xp, v2.xp) && ::qFuzzyCompare(v1.yp, v2.yp) && ::qFuzzyCompare(v1.zp, v2.zp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double xp = 0;
|
double xp = 0;
|
||||||
double yp = 0;
|
double yp = 0;
|
||||||
double zp = 0;
|
double zp = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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
|
||||||
{
|
{
|
||||||
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
|
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline double QPoint3D::x() const
|
constexpr inline double QPoint3D::x() const
|
||||||
{
|
{
|
||||||
return xp;
|
return xp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline double QPoint3D::y() const
|
constexpr inline double QPoint3D::y() const
|
||||||
{
|
{
|
||||||
return yp;
|
return yp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline double QPoint3D::z() const
|
constexpr inline double QPoint3D::z() const
|
||||||
{
|
{
|
||||||
return zp;
|
return zp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline void QPoint3D::setX(double xpos)
|
constexpr inline void QPoint3D::setX(double xpos)
|
||||||
{
|
{
|
||||||
xp = xpos;
|
xp = xpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline void QPoint3D::setY(double ypos)
|
constexpr inline void QPoint3D::setY(double ypos)
|
||||||
{
|
{
|
||||||
yp = ypos;
|
yp = ypos;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline void QPoint3D::setZ(double zpos)
|
constexpr inline void QPoint3D::setZ(double zpos)
|
||||||
{
|
{
|
||||||
zp = zpos;
|
zp = zpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline double& QPoint3D::rx()
|
constexpr inline double &QPoint3D::rx()
|
||||||
{
|
{
|
||||||
return xp;
|
return xp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline double& QPoint3D::ry()
|
constexpr inline double &QPoint3D::ry()
|
||||||
{
|
{
|
||||||
return yp;
|
return yp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline double& QPoint3D::rz()
|
constexpr inline double &QPoint3D::rz()
|
||||||
{
|
{
|
||||||
return zp;
|
return zp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline QPointF QPoint3D::toPointF() const
|
constexpr inline QPointF QPoint3D::toPointF() const
|
||||||
{
|
{
|
||||||
return QPointF(xp, yp);
|
return QPointF(xp, yp);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool operator==(const QPoint3D& p1, const QPoint3D& p2)
|
constexpr inline bool operator==(const QPoint3D &p1, const QPoint3D &p2)
|
||||||
{
|
{
|
||||||
return p1.xp == p2.xp && p1.yp == p2.yp && p1.zp == p2.zp;
|
return p1.xp == p2.xp && p1.yp == p2.yp && p1.zp == p2.zp;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr inline bool operator!=(const QPoint3D& p1, const QPoint3D& p2)
|
constexpr inline bool operator!=(const QPoint3D &p1, const QPoint3D &p2)
|
||||||
{
|
{
|
||||||
return p1.xp != p2.xp || p1.yp != p2.yp || p1.zp != p2.zp;
|
return p1.xp != p2.xp || p1.yp != p2.yp || p1.zp != p2.zp;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& stream, const QPoint3D& pos)
|
inline std::ostream &operator<<(std::ostream &stream, const QPoint3D &pos)
|
||||||
{
|
{
|
||||||
stream << "(" << pos.x() << "," << pos.y() << "," << pos.z() << ")";
|
stream << "(" << pos.x() << "," << pos.y() << "," << pos.z() << ")";
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
|
|
||||||
|
|||||||
+7
-6
@@ -7,15 +7,16 @@
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedConnection::~ScopedConnection()
|
ScopedConnection::~ScopedConnection()
|
||||||
{
|
{
|
||||||
m_conn->disconnect();
|
m_conn->disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -9,16 +9,16 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class IConnection;
|
class IConnection;
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT ScopedConnection
|
class LTSUTILSCORE_EXPORT ScopedConnection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ScopedConnection(IConnection* connection, Qt::ConnectionType = Qt::AutoConnection);
|
explicit ScopedConnection(IConnection *connection, Qt::ConnectionType = Qt::AutoConnection);
|
||||||
~ScopedConnection();
|
~ScopedConnection();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IConnection* m_conn;
|
IConnection *m_conn;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+137
-137
@@ -5,24 +5,24 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
static constexpr unsigned char XON = 0x11;
|
static constexpr unsigned char XON = 0x11;
|
||||||
static constexpr unsigned char XOFF = 0x13;
|
static constexpr unsigned char XOFF = 0x13;
|
||||||
static constexpr unsigned char STX = 0x02;
|
static constexpr unsigned char STX = 0x02;
|
||||||
static constexpr unsigned char ETX = 0x03;
|
static constexpr unsigned char ETX = 0x03;
|
||||||
static constexpr unsigned char SUBST = 0x80;
|
static constexpr unsigned char SUBST = 0x80;
|
||||||
|
|
||||||
static constexpr unsigned char SUB_XON = 0x91;
|
static constexpr unsigned char SUB_XON = 0x91;
|
||||||
static constexpr unsigned char SUB_XOFF = 0x93;
|
static constexpr unsigned char SUB_XOFF = 0x93;
|
||||||
static constexpr unsigned char SUB_STX = 0x82;
|
static constexpr unsigned char SUB_STX = 0x82;
|
||||||
static constexpr unsigned char SUB_ETX = 0x83;
|
static constexpr unsigned char SUB_ETX = 0x83;
|
||||||
static constexpr unsigned char SUB_SUBST = 0x00;
|
static constexpr unsigned char SUB_SUBST = 0x00;
|
||||||
|
|
||||||
static constexpr int HEADER_SIZE = 3;
|
static constexpr int HEADER_SIZE = 3;
|
||||||
static constexpr int CHECKSUM_SIZE = 1;
|
static constexpr int CHECKSUM_SIZE = 1;
|
||||||
static constexpr int MINIMUM_BYTE_SIZE = 1 + HEADER_SIZE + CHECKSUM_SIZE + 1;
|
static constexpr int MINIMUM_BYTE_SIZE = 1 + HEADER_SIZE + CHECKSUM_SIZE + 1;
|
||||||
|
|
||||||
static SfmMessage getSfmMessage(const QByteArray& p_data)
|
static SfmMessage getSfmMessage(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
|
|
||||||
unsigned short id = 0;
|
unsigned short id = 0;
|
||||||
id |= (((unsigned short)p_data[0]) & 0x7F) << 8;
|
id |= (((unsigned short)p_data[0]) & 0x7F) << 8;
|
||||||
@@ -34,10 +34,10 @@ static SfmMessage getSfmMessage(const QByteArray& p_data)
|
|||||||
msg.setPayload(p_data.right(p_data.size() - HEADER_SIZE));
|
msg.setPayload(p_data.right(p_data.size() - HEADER_SIZE));
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray getHeader(const SfmMessage& p_msg)
|
static QByteArray getHeader(const SfmMessage &p_msg)
|
||||||
{
|
{
|
||||||
QByteArray header(2, Qt::Uninitialized);
|
QByteArray header(2, Qt::Uninitialized);
|
||||||
|
|
||||||
header[0] = ((p_msg.id() >> 8) & 0x7f) | (p_msg.rtr() << 7);
|
header[0] = ((p_msg.id() >> 8) & 0x7f) | (p_msg.rtr() << 7);
|
||||||
@@ -45,184 +45,184 @@ static QByteArray getHeader(const SfmMessage& p_msg)
|
|||||||
header[1] = (p_msg.id() >> 0) & 0xff;
|
header[1] = (p_msg.id() >> 0) & 0xff;
|
||||||
|
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline char getChecksum(const QByteArray& p_data)
|
static inline char getChecksum(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
char sum = 0;
|
char sum = 0;
|
||||||
|
|
||||||
for (const char c : p_data)
|
for (const char c : p_data)
|
||||||
sum += c;
|
sum += c;
|
||||||
|
|
||||||
return sum ^ 0xff;
|
return sum ^ 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray removeChecksum(const QByteArray& p_data)
|
static QByteArray removeChecksum(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
QByteArray withoutChecksum(p_data);
|
QByteArray withoutChecksum(p_data);
|
||||||
ConversionError error("Checksum error");
|
ConversionError error("Checksum error");
|
||||||
|
|
||||||
if (p_data.size() >= CHECKSUM_SIZE)
|
if (p_data.size() >= CHECKSUM_SIZE)
|
||||||
{
|
{
|
||||||
withoutChecksum.chop(1);
|
withoutChecksum.chop(1);
|
||||||
|
|
||||||
if (p_data.at(p_data.size() - 1) != getChecksum(withoutChecksum))
|
if (p_data.at(p_data.size() - 1) != getChecksum(withoutChecksum))
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw error;
|
throw error;
|
||||||
|
|
||||||
return withoutChecksum;
|
return withoutChecksum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray maskData(const QByteArray& p_data)
|
static QByteArray maskData(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
QByteArray maskData;
|
QByteArray maskData;
|
||||||
maskData.reserve(p_data.size() * 8 / 6);
|
maskData.reserve(p_data.size() * 8 / 6);
|
||||||
|
|
||||||
for (const unsigned char byte : p_data)
|
for (const unsigned char byte : p_data)
|
||||||
{
|
{
|
||||||
switch (byte)
|
switch (byte)
|
||||||
{
|
{
|
||||||
case XON:
|
case XON:
|
||||||
maskData.append(SUBST);
|
maskData.append(SUBST);
|
||||||
maskData.append(SUB_XON);
|
maskData.append(SUB_XON);
|
||||||
break;
|
break;
|
||||||
case XOFF:
|
case XOFF:
|
||||||
maskData.append(SUBST);
|
maskData.append(SUBST);
|
||||||
maskData.append(SUB_XOFF);
|
maskData.append(SUB_XOFF);
|
||||||
break;
|
break;
|
||||||
case STX:
|
case STX:
|
||||||
maskData.append(SUBST);
|
maskData.append(SUBST);
|
||||||
maskData.append(SUB_STX);
|
maskData.append(SUB_STX);
|
||||||
break;
|
break;
|
||||||
case ETX:
|
case ETX:
|
||||||
maskData.append(SUBST);
|
maskData.append(SUBST);
|
||||||
maskData.append(SUB_ETX);
|
maskData.append(SUB_ETX);
|
||||||
break;
|
break;
|
||||||
case SUBST:
|
case SUBST:
|
||||||
maskData.append(SUBST);
|
maskData.append(SUBST);
|
||||||
maskData.append(static_cast<char>(SUB_SUBST));
|
maskData.append(static_cast<char>(SUB_SUBST));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
maskData.append(byte);
|
maskData.append(byte);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return maskData;
|
return maskData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mustBeMasked(const unsigned char byte)
|
static bool mustBeMasked(const unsigned char byte)
|
||||||
{
|
{
|
||||||
switch (byte)
|
switch (byte)
|
||||||
{
|
{
|
||||||
case XON:
|
case XON:
|
||||||
case XOFF:
|
case XOFF:
|
||||||
case STX:
|
case STX:
|
||||||
case ETX:
|
case ETX:
|
||||||
case SUBST:
|
case SUBST:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lenMaskedData(const QByteArray& data)
|
int lenMaskedData(const QByteArray &data)
|
||||||
{
|
{
|
||||||
int ret = data.length();
|
int ret = data.length();
|
||||||
const unsigned char upperLen = ((data.length() & 0xff00) >> 8);
|
const unsigned char upperLen = ((data.length() & 0xff00) >> 8);
|
||||||
const unsigned char lowerLen = ((data.length() & 0x00ff) >> 0);
|
const unsigned char lowerLen = ((data.length() & 0x00ff) >> 0);
|
||||||
if (mustBeMasked(upperLen))
|
if (mustBeMasked(upperLen))
|
||||||
++ret;
|
++ret;
|
||||||
if (mustBeMasked(lowerLen))
|
if (mustBeMasked(lowerLen))
|
||||||
++ret;
|
++ret;
|
||||||
for (const unsigned char byte : data)
|
for (const unsigned char byte : data)
|
||||||
{
|
{
|
||||||
if (mustBeMasked(byte))
|
if (mustBeMasked(byte))
|
||||||
++ret;
|
++ret;
|
||||||
}
|
}
|
||||||
if (mustBeMasked(getChecksum(data)))
|
if (mustBeMasked(getChecksum(data)))
|
||||||
++ret;
|
++ret;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray unmaskData(const QByteArray& p_data)
|
static QByteArray unmaskData(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
QByteArray unmaskData;
|
QByteArray unmaskData;
|
||||||
unmaskData.reserve(p_data.size());
|
unmaskData.reserve(p_data.size());
|
||||||
|
|
||||||
for (int position = 0; position < p_data.size(); ++position)
|
for (int position = 0; position < p_data.size(); ++position)
|
||||||
{
|
{
|
||||||
unsigned char byte = p_data.at(position);
|
unsigned char byte = p_data.at(position);
|
||||||
if (byte == SUBST)
|
if (byte == SUBST)
|
||||||
{
|
{
|
||||||
++position;
|
++position;
|
||||||
byte = p_data.at(position);
|
byte = p_data.at(position);
|
||||||
|
|
||||||
switch (byte)
|
switch (byte)
|
||||||
{
|
{
|
||||||
case SUB_XON:
|
case SUB_XON:
|
||||||
unmaskData.append(XON);
|
unmaskData.append(XON);
|
||||||
break;
|
break;
|
||||||
case SUB_XOFF:
|
case SUB_XOFF:
|
||||||
unmaskData.append(XOFF);
|
unmaskData.append(XOFF);
|
||||||
break;
|
break;
|
||||||
case SUB_STX:
|
case SUB_STX:
|
||||||
unmaskData.append(STX);
|
unmaskData.append(STX);
|
||||||
break;
|
break;
|
||||||
case SUB_ETX:
|
case SUB_ETX:
|
||||||
unmaskData.append(ETX);
|
unmaskData.append(ETX);
|
||||||
break;
|
break;
|
||||||
case SUB_SUBST:
|
case SUB_SUBST:
|
||||||
unmaskData.append(SUBST);
|
unmaskData.append(SUBST);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
unmaskData.append(byte);
|
else
|
||||||
|
unmaskData.append(byte);
|
||||||
}
|
}
|
||||||
return unmaskData;
|
return unmaskData;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray addFrame(const QByteArray& p_data)
|
static QByteArray addFrame(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
QByteArray ret;
|
QByteArray ret;
|
||||||
ret.reserve(2 + p_data.size());
|
ret.reserve(2 + p_data.size());
|
||||||
ret.append(STX);
|
ret.append(STX);
|
||||||
ret.append(p_data);
|
ret.append(p_data);
|
||||||
ret.append(ETX);
|
ret.append(ETX);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QByteArray removeFrame(const QByteArray& p_data)
|
static QByteArray removeFrame(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (p_data[0] == STX && p_data[p_data.size() - 1] == ETX)
|
if (p_data[0] == STX && p_data[p_data.size() - 1] == ETX)
|
||||||
{
|
{
|
||||||
|
|
||||||
return p_data.mid(1, p_data.size() - 2);
|
return p_data.mid(1, p_data.size() - 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw ConversionError("Framing Error");
|
throw ConversionError("Framing Error");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void checkLength(const QByteArray& p_data)
|
static void checkLength(const QByteArray &p_data)
|
||||||
{
|
{
|
||||||
if (p_data.size() < HEADER_SIZE)
|
if (p_data.size() < HEADER_SIZE)
|
||||||
throw ConversionError("Telegram too short");
|
throw ConversionError("Telegram too short");
|
||||||
|
|
||||||
unsigned char length = p_data[HEADER_SIZE - 1];
|
unsigned char length = p_data[HEADER_SIZE - 1];
|
||||||
if (length != p_data.size() - HEADER_SIZE)
|
if (length != p_data.size() - HEADER_SIZE)
|
||||||
throw ConversionError("Telegram length does not match");
|
throw ConversionError("Telegram length does not match");
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray byteStreamFromSfmMessage(const SfmMessage& message)
|
QByteArray byteStreamFromSfmMessage(const SfmMessage &message)
|
||||||
{
|
{
|
||||||
QByteArray byteData(getHeader(message));
|
QByteArray byteData(getHeader(message));
|
||||||
|
|
||||||
byteData.append(message.payload().size());
|
byteData.append(message.payload().size());
|
||||||
@@ -230,12 +230,12 @@ QByteArray byteStreamFromSfmMessage(const SfmMessage& message)
|
|||||||
byteData.append(getChecksum(byteData));
|
byteData.append(getChecksum(byteData));
|
||||||
|
|
||||||
return addFrame(maskData(byteData));
|
return addFrame(maskData(byteData));
|
||||||
}
|
}
|
||||||
|
|
||||||
SfmMessage byteStreamToSfmMessage(const QByteArray& datastream)
|
SfmMessage byteStreamToSfmMessage(const QByteArray &datastream)
|
||||||
{
|
{
|
||||||
if (datastream.size() < MINIMUM_BYTE_SIZE)
|
if (datastream.size() < MINIMUM_BYTE_SIZE)
|
||||||
throw ConversionError("Can't convert an QByteArray that hasn't the minimum size!");
|
throw ConversionError("Can't convert an QByteArray that hasn't the minimum size!");
|
||||||
|
|
||||||
QByteArray checkMsg;
|
QByteArray checkMsg;
|
||||||
|
|
||||||
@@ -247,29 +247,29 @@ SfmMessage byteStreamToSfmMessage(const QByteArray& datastream)
|
|||||||
checkLength(checkMsg);
|
checkLength(checkMsg);
|
||||||
|
|
||||||
return getSfmMessage(checkMsg);
|
return getSfmMessage(checkMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray byteStreamFromEscMessage(const QByteArray& message)
|
QByteArray byteStreamFromEscMessage(const QByteArray &message)
|
||||||
{
|
{
|
||||||
QByteArray byteData = message;
|
QByteArray byteData = message;
|
||||||
if (message.size() == 1)
|
if (message.size() == 1)
|
||||||
{
|
{
|
||||||
|
|
||||||
byteData.append(message);
|
byteData.append(message);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
byteData.append(getChecksum(byteData));
|
byteData.append(getChecksum(byteData));
|
||||||
|
|
||||||
byteData = maskData(byteData);
|
byteData = maskData(byteData);
|
||||||
byteData = addFrame(byteData);
|
byteData = addFrame(byteData);
|
||||||
|
|
||||||
return byteData;
|
return byteData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray byteStreamToEscMessage(const QByteArray& datastream)
|
QByteArray byteStreamToEscMessage(const QByteArray &datastream)
|
||||||
{
|
{
|
||||||
if (datastream.size() < 2)
|
if (datastream.size() < 2)
|
||||||
return QByteArray("ERROR");
|
return QByteArray("ERROR");
|
||||||
|
|
||||||
QByteArray checkMsg;
|
QByteArray checkMsg;
|
||||||
|
|
||||||
@@ -278,6 +278,6 @@ QByteArray byteStreamToEscMessage(const QByteArray& datastream)
|
|||||||
|
|
||||||
checkMsg.chop(1);
|
checkMsg.chop(1);
|
||||||
return checkMsg;
|
return checkMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+18
-39
@@ -9,64 +9,43 @@
|
|||||||
namespace LtsUtils
|
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;
|
||||||
bool m_rtr = false;
|
bool m_rtr = false;
|
||||||
QByteArray m_payload;
|
QByteArray m_payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConversionError : public std::runtime_error
|
class ConversionError : public std::runtime_error
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using std::runtime_error::runtime_error;
|
using std::runtime_error::runtime_error;
|
||||||
};
|
};
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QByteArray byteStreamFromSfmMessage(const SfmMessage& message);
|
LTSUTILSCORE_EXPORT QByteArray byteStreamFromSfmMessage(const SfmMessage &message);
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT SfmMessage byteStreamToSfmMessage(const QByteArray& datastream);
|
LTSUTILSCORE_EXPORT SfmMessage byteStreamToSfmMessage(const QByteArray &datastream);
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QByteArray byteStreamFromEscMessage(const QByteArray& message);
|
LTSUTILSCORE_EXPORT QByteArray byteStreamFromEscMessage(const QByteArray &message);
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QByteArray byteStreamToEscMessage(const QByteArray& datastream);
|
LTSUTILSCORE_EXPORT QByteArray byteStreamToEscMessage(const QByteArray &datastream);
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT int lenMaskedData(const QByteArray& data);
|
LTSUTILSCORE_EXPORT int lenMaskedData(const QByteArray &data);
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+15
-15
@@ -7,31 +7,31 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
inline bool lessThan(const QVariant& var1, const QVariant& var2)
|
inline bool lessThan(const QVariant &var1, const QVariant &var2)
|
||||||
{
|
{
|
||||||
if (var1.canConvert<QString>() && var2.canConvert<QString>())
|
if (var1.canConvert<QString>() && var2.canConvert<QString>())
|
||||||
{
|
{
|
||||||
QString str1(var1.toString());
|
QString str1(var1.toString());
|
||||||
QString str2(var2.toString());
|
QString str2(var2.toString());
|
||||||
|
|
||||||
bool k1 = false;
|
bool k1 = false;
|
||||||
double d1 = str1.toDouble(&k1);
|
double d1 = str1.toDouble(&k1);
|
||||||
|
|
||||||
if (!k1)
|
if (!k1)
|
||||||
return str1 < str2;
|
return str1 < str2;
|
||||||
|
|
||||||
bool k2 = false;
|
bool k2 = false;
|
||||||
double d2 = str2.toDouble(&k2);
|
double d2 = str2.toDouble(&k2);
|
||||||
|
|
||||||
if (!k2)
|
if (!k2)
|
||||||
return str1 < str2;
|
return str1 < str2;
|
||||||
|
|
||||||
return d1 < d2;
|
return d1 < d2;
|
||||||
}
|
}
|
||||||
else if (var1.canConvert<double>() && var2.canConvert<double>())
|
else if (var1.canConvert<double>() && var2.canConvert<double>())
|
||||||
return var1.toDouble() < var2.toDouble();
|
return var1.toDouble() < var2.toDouble();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+36
-30
@@ -8,52 +8,58 @@
|
|||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
int ConnectingDialog::s_waitForHistoricalDataWaitTime = 10000;
|
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()
|
||||||
{
|
{
|
||||||
m_ui = new Ui::ConnectingDialog;
|
m_ui = new Ui::ConnectingDialog;
|
||||||
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,
|
||||||
m_ui->pbRetry->setEnabled(false);
|
&QPushButton::clicked,
|
||||||
m_ui->pbIgnore->setEnabled(false);
|
this,
|
||||||
|
[this]()
|
||||||
|
{
|
||||||
|
m_ui->pbRetry->setEnabled(false);
|
||||||
|
m_ui->pbIgnore->setEnabled(false);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
emit signalStopLoop();
|
emit signalStopLoop();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_ui->pbIgnore, &QPushButton::clicked, this, [this]() {
|
connect(m_ui->pbIgnore,
|
||||||
m_ui->pbIgnore->setEnabled(false);
|
&QPushButton::clicked,
|
||||||
m_ui->pbRetry->setEnabled(false);
|
this,
|
||||||
m_ui->pbIgnore->setText(tr("continuing.."));
|
[this]()
|
||||||
|
{
|
||||||
|
m_ui->pbIgnore->setEnabled(false);
|
||||||
|
m_ui->pbRetry->setEnabled(false);
|
||||||
|
m_ui->pbIgnore->setText(tr("continuing.."));
|
||||||
|
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectingDialog::~ConnectingDialog()
|
ConnectingDialog::~ConnectingDialog()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
raise();
|
raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+33
-28
@@ -11,47 +11,52 @@
|
|||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class ConnectingDialog;
|
class ConnectingDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialog : public LtsWidgets::LtsFramelessDialog
|
class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialog : public LtsWidgets::LtsFramelessDialog
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
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();
|
||||||
show();
|
show();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
{
|
||||||
|
if ((dtc.get()->*waitForHistoricalDataFunction)(s_waitForHistoricalDataWaitTime))
|
||||||
{
|
{
|
||||||
if ((dtc.get()->*waitForHistoricalDataFunction)(s_waitForHistoricalDataWaitTime))
|
deleteLater();
|
||||||
{
|
return;
|
||||||
deleteLater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_waitForHistoricalDataWaitTime >= 999999)
|
|
||||||
{
|
|
||||||
deleteLater();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
failed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s_waitForHistoricalDataWaitTime >= 999999)
|
||||||
|
{
|
||||||
|
deleteLater();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
failed();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~ConnectingDialog();
|
~ConnectingDialog();
|
||||||
@@ -61,13 +66,13 @@ class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialog : public LtsWidgets::LtsF
|
|||||||
private:
|
private:
|
||||||
QString m_serviceName;
|
QString m_serviceName;
|
||||||
QString m_exerciseName;
|
QString m_exerciseName;
|
||||||
Ui::ConnectingDialog* m_ui;
|
Ui::ConnectingDialog *m_ui;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void setup();
|
void setup();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void signalStopLoop();
|
void signalStopLoop();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+63
-54
@@ -12,39 +12,50 @@
|
|||||||
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,
|
||||||
if (m_autoRetryTick < 1)
|
&QTimer::timeout,
|
||||||
{
|
this,
|
||||||
slotRetry();
|
[this]()
|
||||||
return;
|
{
|
||||||
}
|
if (m_autoRetryTick < 1)
|
||||||
|
{
|
||||||
|
slotRetry();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_ui->pbRetry->setText(QStringLiteral("%1 [%2]").arg(tr("Retry")).arg(m_autoRetryTick));
|
m_ui->pbRetry->setText(QStringLiteral("%1 [%2]").arg(tr("Retry")).arg(m_autoRetryTick));
|
||||||
m_autoRetryTick--;
|
m_autoRetryTick--;
|
||||||
});
|
});
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
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,
|
||||||
m_ui->pbIgnore->setEnabled(false);
|
&QPushButton::clicked,
|
||||||
m_ui->pbRetry->setEnabled(false);
|
this,
|
||||||
m_ui->pbIgnore->setText(tr("continuing.."));
|
[this]()
|
||||||
|
{
|
||||||
|
m_ui->pbIgnore->setEnabled(false);
|
||||||
|
m_ui->pbRetry->setEnabled(false);
|
||||||
|
m_ui->pbIgnore->setText(tr("continuing.."));
|
||||||
|
|
||||||
emit signalFailed();
|
emit signalFailed();
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
|
|
||||||
show();
|
show();
|
||||||
|
|
||||||
@@ -52,32 +63,32 @@ ConnectingDialogNT::ConnectingDialogNT(const std::function<bool(int)>& checkFn,
|
|||||||
|
|
||||||
m_go = true;
|
m_go = true;
|
||||||
m_ui->pbRetry->setEnabled(false);
|
m_ui->pbRetry->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ConnectingDialogNT::random(int min, int max)
|
int ConnectingDialogNT::random(int min, int max)
|
||||||
{
|
{
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
||||||
return QRandomGenerator::global()->bounded(min, max);
|
return QRandomGenerator::global()->bounded(min, max);
|
||||||
#else
|
#else
|
||||||
return (qrand() % (((max + 1) - min) + min));
|
return (qrand() % (((max + 1) - min) + min));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectingDialogNT::event(QEvent* event)
|
bool ConnectingDialogNT::event(QEvent *event)
|
||||||
{
|
{
|
||||||
bool result = LtsWidgets::LtsFramelessDialog::event(event);
|
bool result = LtsWidgets::LtsFramelessDialog::event(event);
|
||||||
|
|
||||||
if (event->type() == QEvent::Paint && m_go)
|
if (event->type() == QEvent::Paint && m_go)
|
||||||
{
|
{
|
||||||
m_go = false;
|
m_go = false;
|
||||||
QTimer::singleShot(0, this, &ConnectingDialogNT::signalGo);
|
QTimer::singleShot(0, this, &ConnectingDialogNT::signalGo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectingDialogNT::slotRetry()
|
void ConnectingDialogNT::slotRetry()
|
||||||
{
|
{
|
||||||
m_autoRetryTimer->stop();
|
m_autoRetryTimer->stop();
|
||||||
|
|
||||||
m_ui->pbRetry->setText(tr("Retry"));
|
m_ui->pbRetry->setText(tr("Retry"));
|
||||||
@@ -86,36 +97,34 @@ void ConnectingDialogNT::slotRetry()
|
|||||||
|
|
||||||
reset();
|
reset();
|
||||||
QTimer::singleShot(1, this, &ConnectingDialogNT::slotGo);
|
QTimer::singleShot(1, this, &ConnectingDialogNT::slotGo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectingDialogNT::slotGo()
|
void ConnectingDialogNT::slotGo()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (m_checkFn(ConnectingDialog::s_waitForHistoricalDataWaitTime))
|
if (m_checkFn(ConnectingDialog::s_waitForHistoricalDataWaitTime))
|
||||||
{
|
{
|
||||||
emit signalSuccess();
|
emit signalSuccess();
|
||||||
deleteLater();
|
deleteLater();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
failed();
|
failed();
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
{
|
{
|
||||||
delete m_ui;
|
delete m_ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@@ -124,6 +133,6 @@ void ConnectingDialogNT::failed()
|
|||||||
m_autoRetryTimer->start();
|
m_autoRetryTimer->start();
|
||||||
|
|
||||||
raise();
|
raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+8
-9
@@ -11,19 +11,18 @@ class QTimer;
|
|||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class ConnectingDialog;
|
class ConnectingDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialogNT : public LtsWidgets::LtsFramelessDialog
|
class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialogNT : public LtsWidgets::LtsFramelessDialog
|
||||||
{
|
{
|
||||||
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();
|
||||||
@@ -43,14 +42,14 @@ class LTSUTILSGUICONNECTDIALOG_EXPORT ConnectingDialogNT : public LtsWidgets::Lt
|
|||||||
std::function<bool(int)> m_checkFn;
|
std::function<bool(int)> m_checkFn;
|
||||||
bool m_go;
|
bool m_go;
|
||||||
|
|
||||||
QTimer* m_autoRetryTimer;
|
QTimer *m_autoRetryTimer;
|
||||||
int m_autoRetryTick{0};
|
int m_autoRetryTick{0};
|
||||||
|
|
||||||
Ui::ConnectingDialog* m_ui;
|
Ui::ConnectingDialog *m_ui;
|
||||||
|
|
||||||
int random(int min, int max);
|
int random(int min, int max);
|
||||||
bool event(QEvent* event) override;
|
bool event(QEvent *event) override;
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
-6
@@ -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)
|
|
||||||
+57
-57
@@ -13,8 +13,8 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
QIcon iconFromSvg(const QByteArray& svgData, QSize iconSize)
|
QIcon iconFromSvg(const QByteArray &svgData, QSize iconSize)
|
||||||
{
|
{
|
||||||
QSvgRenderer renderer(svgData);
|
QSvgRenderer renderer(svgData);
|
||||||
QPixmap p(iconSize);
|
QPixmap p(iconSize);
|
||||||
p.fill(Qt::transparent);
|
p.fill(Qt::transparent);
|
||||||
@@ -23,60 +23,60 @@ QIcon iconFromSvg(const QByteArray& svgData, QSize iconSize)
|
|||||||
painter.end();
|
painter.end();
|
||||||
|
|
||||||
return {p};
|
return {p};
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon iconFromSvg(const QString& svgFilename, QSize iconSize)
|
QIcon iconFromSvg(const QString &svgFilename, QSize iconSize)
|
||||||
{
|
{
|
||||||
QFile f(svgFilename);
|
QFile f(svgFilename);
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
if (!f.open(QIODevice::ReadOnly))
|
||||||
return {};
|
return {};
|
||||||
return iconFromSvg(f.readAll(), iconSize);
|
return iconFromSvg(f.readAll(), iconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap pixmapFromIcon(const QIcon& icon, QSize iconSize)
|
QPixmap pixmapFromIcon(const QIcon &icon, QSize iconSize)
|
||||||
{
|
{
|
||||||
return icon.pixmap(iconSize).scaled(100, 100, Qt::AspectRatioMode::IgnoreAspectRatio);
|
return icon.pixmap(iconSize).scaled(100, 100, Qt::AspectRatioMode::IgnoreAspectRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap pixmapFromSvg(const QString& svgFilename, QSize iconSize)
|
QPixmap pixmapFromSvg(const QString &svgFilename, QSize iconSize)
|
||||||
{
|
{
|
||||||
return pixmapFromIcon(iconFromSvg(svgFilename, iconSize), iconSize);
|
return pixmapFromIcon(iconFromSvg(svgFilename, iconSize), iconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap getPixmap(const std::vector<uint8_t>& data)
|
QPixmap getPixmap(const std::vector<uint8_t> &data)
|
||||||
{
|
{
|
||||||
if (data.size() == 0)
|
if (data.size() == 0)
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
|
|
||||||
return getPixmap(QByteArray(reinterpret_cast<const char*>(&data.at(0)), data.size()));
|
return getPixmap(QByteArray(reinterpret_cast<const char *>(&data.at(0)), data.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap getPixmap(const QByteArray& data)
|
QPixmap getPixmap(const QByteArray &data)
|
||||||
{
|
{
|
||||||
return QPixmap::fromImage(QImage::fromData(data));
|
return QPixmap::fromImage(QImage::fromData(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage getImage(const std::vector<uint8_t>& data)
|
QImage getImage(const std::vector<uint8_t> &data)
|
||||||
{
|
{
|
||||||
if (data.size() == 0)
|
if (data.size() == 0)
|
||||||
return QImage();
|
return QImage();
|
||||||
|
|
||||||
return getImage(QByteArray(reinterpret_cast<const char*>(&data.at(0)), data.size()));
|
return getImage(QByteArray(reinterpret_cast<const char *>(&data.at(0)), data.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage getImage(const QByteArray& data)
|
QImage getImage(const QByteArray &data)
|
||||||
{
|
{
|
||||||
return QImage::fromData(data);
|
return QImage::fromData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void setIf(bool* boolPtr, bool val)
|
static inline void setIf(bool *boolPtr, bool val)
|
||||||
{
|
{
|
||||||
if (boolPtr)
|
if (boolPtr)
|
||||||
*boolPtr = val;
|
*boolPtr = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> fromPixmap(const QPixmap& pixmap, bool* bIsPng)
|
std::vector<uint8_t> fromPixmap(const QPixmap &pixmap, bool *bIsPng)
|
||||||
{
|
{
|
||||||
QBuffer buf;
|
QBuffer buf;
|
||||||
buf.open(QIODevice::WriteOnly);
|
buf.open(QIODevice::WriteOnly);
|
||||||
pixmap.save(&buf, "PNG");
|
pixmap.save(&buf, "PNG");
|
||||||
@@ -87,22 +87,22 @@ std::vector<uint8_t> fromPixmap(const QPixmap& pixmap, bool* bIsPng)
|
|||||||
|
|
||||||
if (ba.size() > 10240 && !pixmap.hasAlpha() && !pixmap.hasAlphaChannel())
|
if (ba.size() > 10240 && !pixmap.hasAlpha() && !pixmap.hasAlphaChannel())
|
||||||
{
|
{
|
||||||
QBuffer buf2;
|
QBuffer buf2;
|
||||||
buf2.open(QIODevice::WriteOnly);
|
buf2.open(QIODevice::WriteOnly);
|
||||||
pixmap.save(&buf2, "JPG");
|
pixmap.save(&buf2, "JPG");
|
||||||
buf2.close();
|
buf2.close();
|
||||||
if (buf2.buffer().size() < buf.buffer().size())
|
if (buf2.buffer().size() < buf.buffer().size())
|
||||||
{
|
{
|
||||||
setIf(bIsPng, false);
|
setIf(bIsPng, false);
|
||||||
ba = buf2.buffer();
|
ba = buf2.buffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return convert<std::vector<uint8_t>>(ba);
|
return convert<std::vector<uint8_t>>(ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> fromImage(const QImage& image, bool* bIsPng)
|
std::vector<uint8_t> fromImage(const QImage &image, bool *bIsPng)
|
||||||
{
|
{
|
||||||
QBuffer buf;
|
QBuffer buf;
|
||||||
buf.open(QIODevice::WriteOnly);
|
buf.open(QIODevice::WriteOnly);
|
||||||
image.save(&buf, "PNG");
|
image.save(&buf, "PNG");
|
||||||
@@ -112,18 +112,18 @@ std::vector<uint8_t> fromImage(const QImage& image, bool* bIsPng)
|
|||||||
setIf(bIsPng, true);
|
setIf(bIsPng, true);
|
||||||
if ((ba.size() > 10240 && !image.hasAlphaChannel()) || ba.size() > 1024 * 1024)
|
if ((ba.size() > 10240 && !image.hasAlphaChannel()) || ba.size() > 1024 * 1024)
|
||||||
{
|
{
|
||||||
QBuffer buf2;
|
QBuffer buf2;
|
||||||
buf2.open(QIODevice::WriteOnly);
|
buf2.open(QIODevice::WriteOnly);
|
||||||
image.save(&buf2, "JPG");
|
image.save(&buf2, "JPG");
|
||||||
buf2.close();
|
buf2.close();
|
||||||
if (buf2.buffer().size() < buf.buffer().size())
|
if (buf2.buffer().size() < buf.buffer().size())
|
||||||
{
|
{
|
||||||
setIf(bIsPng, false);
|
setIf(bIsPng, false);
|
||||||
ba = buf2.buffer();
|
ba = buf2.buffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return convert<std::vector<uint8_t>>(ba);
|
return convert<std::vector<uint8_t>>(ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+10
-10
@@ -17,15 +17,15 @@ class QIcon;
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QPixmap getPixmap(const std::vector<uint8_t>& data);
|
LTSUTILSCORE_EXPORT QPixmap getPixmap(const std::vector<uint8_t> &data);
|
||||||
LTSUTILSCORE_EXPORT QPixmap getPixmap(const QByteArray& data);
|
LTSUTILSCORE_EXPORT QPixmap getPixmap(const QByteArray &data);
|
||||||
LTSUTILSCORE_EXPORT QImage getImage(const std::vector<uint8_t>& data);
|
LTSUTILSCORE_EXPORT QImage getImage(const std::vector<uint8_t> &data);
|
||||||
LTSUTILSCORE_EXPORT QImage getImage(const QByteArray& data);
|
LTSUTILSCORE_EXPORT QImage getImage(const QByteArray &data);
|
||||||
LTSUTILSCORE_EXPORT QIcon iconFromSvg(const QByteArray& svgData, QSize iconSize = QSize(100, 100));
|
LTSUTILSCORE_EXPORT QIcon iconFromSvg(const QByteArray &svgData, QSize iconSize = QSize(100, 100));
|
||||||
LTSUTILSCORE_EXPORT QIcon iconFromSvg(const QString& svgFilename, QSize iconSize = QSize(100, 100));
|
LTSUTILSCORE_EXPORT QIcon iconFromSvg(const QString &svgFilename, QSize iconSize = QSize(100, 100));
|
||||||
LTSUTILSCORE_EXPORT QPixmap pixmapFromIcon(const QIcon& icon, QSize iconSize = QSize(100, 100));
|
LTSUTILSCORE_EXPORT QPixmap pixmapFromIcon(const QIcon &icon, QSize iconSize = QSize(100, 100));
|
||||||
LTSUTILSCORE_EXPORT QPixmap pixmapFromSvg(const QString& svgFilename, QSize iconSize = QSize(100, 100));
|
LTSUTILSCORE_EXPORT QPixmap pixmapFromSvg(const QString &svgFilename, QSize iconSize = QSize(100, 100));
|
||||||
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromPixmap(const QPixmap& pixmap, bool* bIsPng = nullptr);
|
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromPixmap(const QPixmap &pixmap, bool *bIsPng = nullptr);
|
||||||
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromImage(const QImage& image, bool* bIsPng = nullptr);
|
LTSUTILSCORE_EXPORT std::vector<uint8_t> fromImage(const QImage &image, bool *bIsPng = nullptr);
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+1
-1
@@ -9,4 +9,4 @@
|
|||||||
#define LTSUTILSGUIDDS_EXPORT
|
#define LTSUTILSGUIDDS_EXPORT
|
||||||
#define LTSUTILSGUIDDS_NO_EXPORT
|
#define LTSUTILSGUIDDS_NO_EXPORT
|
||||||
|
|
||||||
#endif // LTSUTILSDDS_EXPORT_H
|
#endif // LTSUTILSDDS_EXPORT_H
|
||||||
+113
-110
@@ -18,72 +18,76 @@
|
|||||||
|
|
||||||
namespace LtsUtils
|
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);
|
||||||
|
|
||||||
if (s_debug)
|
if (s_debug)
|
||||||
{
|
{
|
||||||
QTimer* t = new QTimer(this);
|
QTimer *t = new QTimer(this);
|
||||||
t->setInterval(2000);
|
t->setInterval(2000);
|
||||||
t->setSingleShot(true);
|
t->setSingleShot(true);
|
||||||
connect(this, &RequestHelper::signalNextRequest, t, static_cast<void (QTimer::*)(void)>(&QTimer::start));
|
connect(this, &RequestHelper::signalNextRequest, t, static_cast<void (QTimer::*)(void)>(&QTimer::start));
|
||||||
connect(t, &QTimer::timeout, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection);
|
connect(t, &QTimer::timeout, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
connect(this, &RequestHelper::signalNextRequest, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection
|
connect(this, &RequestHelper::signalNextRequest, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestHelper::requestReply(const Core::FunctionReply& baseReply)
|
bool RequestHelper::requestReply(const Core::FunctionReply &baseReply)
|
||||||
{
|
{
|
||||||
// rtiddsgen 7.7 generates plain public members (no getters/setters)
|
// rtiddsgen 7.7 generates plain public members (no getters/setters)
|
||||||
const Core::FunctionReplyObject fro(baseReply.id, baseReply.errorString, baseReply.errorParams);
|
const Core::FunctionReplyObject fro(baseReply.id, baseReply.errorString, baseReply.errorParams);
|
||||||
return _requestReply(fro, &baseReply);
|
return _requestReply(fro, &baseReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestHelper::requestReply(const Core::FunctionReplyObject& replyObject)
|
bool RequestHelper::requestReply(const Core::FunctionReplyObject &replyObject)
|
||||||
{
|
{
|
||||||
return _requestReply(replyObject, nullptr);
|
return _requestReply(replyObject, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestHelper::_requestReply(const Core::FunctionReplyObject& fro, const Core::FunctionReply* baseReply)
|
bool RequestHelper::_requestReply(const Core::FunctionReplyObject &fro, const Core::FunctionReply *baseReply)
|
||||||
{
|
{
|
||||||
m_errorString = fro.translated();
|
m_errorString = fro.translated();
|
||||||
|
|
||||||
#ifdef REQUEST_HELPER_WITH_GUI
|
#ifdef REQUEST_HELPER_WITH_GUI
|
||||||
if (fro.error())
|
if (fro.error())
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!m_quiet)
|
if (!m_quiet)
|
||||||
|
{
|
||||||
|
if (m_blockingCall)
|
||||||
{
|
{
|
||||||
if (m_blockingCall)
|
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget *>(parent()), m_errorString, tr("Request failed"));
|
||||||
{
|
|
||||||
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget*>(parent()), m_errorString,
|
|
||||||
tr("Request failed"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget*>(parent()), m_errorString,
|
|
||||||
tr("Request failed"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()), m_errorString, tr("Request failed"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -91,67 +95,65 @@ bool RequestHelper::_requestReply(const Core::FunctionReplyObject& fro, const Co
|
|||||||
|
|
||||||
if (m_singleRequestCustomFunctionReply != nullptr)
|
if (m_singleRequestCustomFunctionReply != nullptr)
|
||||||
{
|
{
|
||||||
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())
|
||||||
{
|
{
|
||||||
failure();
|
failure();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit signalNextRequest();
|
emit signalNextRequest();
|
||||||
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);
|
||||||
return startRequests();
|
return startRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestHelper::failure()
|
void RequestHelper::failure()
|
||||||
{
|
{
|
||||||
m_failed = true;
|
m_failed = true;
|
||||||
emit signalFailed();
|
emit signalFailed();
|
||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestHelper::done()
|
void RequestHelper::done()
|
||||||
{
|
{
|
||||||
#ifdef REQUEST_HELPER_WITH_GUI
|
#ifdef REQUEST_HELPER_WITH_GUI
|
||||||
if (!m_quiet)
|
if (!m_quiet)
|
||||||
LtsWidgets::LtsGlobalWaitDialog::getInstance()->done();
|
LtsWidgets::LtsGlobalWaitDialog::getInstance()->done();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_requestFunctions.clear();
|
m_requestFunctions.clear();
|
||||||
m_singleRequestCustomFunctionReply = nullptr;
|
m_singleRequestCustomFunctionReply = nullptr;
|
||||||
|
|
||||||
if (m_blockingCall)
|
if (m_blockingCall)
|
||||||
emit signalQuitLoop();
|
emit signalQuitLoop();
|
||||||
|
|
||||||
m_blockingCall = true;
|
m_blockingCall = true;
|
||||||
|
|
||||||
if (!m_blockingCall)
|
if (!m_blockingCall)
|
||||||
deleteLater();
|
deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestHelper::slotNextRequest()
|
void RequestHelper::slotNextRequest()
|
||||||
{
|
{
|
||||||
if (m_requestFunctions.isEmpty())
|
if (m_requestFunctions.isEmpty())
|
||||||
{
|
{
|
||||||
if (!m_blockingCall)
|
if (!m_blockingCall)
|
||||||
emit signalSuccess();
|
emit signalSuccess();
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const RequestFunctionContainer rfc = m_requestFunctions.takeFirst();
|
const RequestFunctionContainer rfc = m_requestFunctions.takeFirst();
|
||||||
@@ -162,59 +164,60 @@ void RequestHelper::slotNextRequest()
|
|||||||
if (result == 0)
|
if (result == 0)
|
||||||
{
|
{
|
||||||
#ifdef REQUEST_HELPER_WITH_GUI
|
#ifdef REQUEST_HELPER_WITH_GUI
|
||||||
if (!m_quiet)
|
if (!m_quiet)
|
||||||
|
{
|
||||||
|
if (m_blockingCall)
|
||||||
{
|
{
|
||||||
if (m_blockingCall)
|
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget *>(parent()), tr("Request failed"));
|
||||||
{
|
|
||||||
LtsWidgets::LtsMessageDialog::showMessage(qobject_cast<QWidget*>(parent()), tr("Request failed"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connect(new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget*>(parent()), tr("Request failed")),
|
|
||||||
&LtsWidgets::LtsMessageDialogNew::destroyed, this, [this]() { failure(); });
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
else
|
||||||
failure();
|
{
|
||||||
}
|
connect(new LtsWidgets::LtsMessageDialogNew(qobject_cast<QWidget *>(parent()), tr("Request failed")),
|
||||||
}
|
&LtsWidgets::LtsMessageDialogNew::destroyed,
|
||||||
|
this,
|
||||||
|
[this]() { failure(); });
|
||||||
|
|
||||||
void RequestHelper::startSingleBackgroundRequest(
|
return;
|
||||||
const std::function<int64_t()>& requestFunction,
|
}
|
||||||
const std::function<void(const Core::FunctionReply&)>& baseReplyHandler)
|
}
|
||||||
{
|
#endif
|
||||||
|
failure();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RequestHelper::startSingleBackgroundRequest(const std::function<int64_t()> &requestFunction,
|
||||||
|
const std::function<void(const Core::FunctionReply &)> &baseReplyHandler)
|
||||||
|
{
|
||||||
m_blockingCall = false;
|
m_blockingCall = false;
|
||||||
startSingleRequest(requestFunction, baseReplyHandler);
|
startSingleRequest(requestFunction, baseReplyHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestHelper::startBackgroundRequests()
|
void RequestHelper::startBackgroundRequests()
|
||||||
{
|
{
|
||||||
m_blockingCall = false;
|
m_blockingCall = false;
|
||||||
startRequests();
|
startRequests();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestHelper::setCustomWaitMessage(const QString& customWaitMessage)
|
void RequestHelper::setCustomWaitMessage(const QString &customWaitMessage)
|
||||||
{
|
{
|
||||||
m_customWaitMessage = (customWaitMessage + QStringLiteral(" ..."));
|
m_customWaitMessage = (customWaitMessage + QStringLiteral(" ..."));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RequestHelper::startRequests()
|
bool RequestHelper::startRequests()
|
||||||
{
|
{
|
||||||
if (m_requestFunctions.isEmpty())
|
if (m_requestFunctions.isEmpty())
|
||||||
{
|
{
|
||||||
#ifdef LTS_DEBUG
|
#ifdef LTS_DEBUG
|
||||||
qWarning("RequestHelper: started request helper without requests!");
|
qWarning("RequestHelper: started request helper without requests!");
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_failed = false;
|
m_failed = false;
|
||||||
|
|
||||||
#ifdef REQUEST_HELPER_WITH_GUI
|
#ifdef REQUEST_HELPER_WITH_GUI
|
||||||
if (!m_quiet)
|
if (!m_quiet)
|
||||||
LtsWidgets::LtsGlobalWaitDialog::getInstance()->wait(m_customWaitMessage);
|
LtsWidgets::LtsGlobalWaitDialog::getInstance()->wait(m_customWaitMessage);
|
||||||
m_customWaitMessage.clear();
|
m_customWaitMessage.clear();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -223,25 +226,25 @@ bool RequestHelper::startRequests()
|
|||||||
|
|
||||||
if (s_debug)
|
if (s_debug)
|
||||||
{
|
{
|
||||||
QTimer* t = new QTimer(this);
|
QTimer *t = new QTimer(this);
|
||||||
t->setInterval(2000);
|
t->setInterval(2000);
|
||||||
connect(t, &QTimer::timeout, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection);
|
connect(t, &QTimer::timeout, this, &RequestHelper::slotNextRequest, Qt::QueuedConnection);
|
||||||
connect(t, &QTimer::timeout, t, &QTimer::deleteLater);
|
connect(t, &QTimer::timeout, t, &QTimer::deleteLater);
|
||||||
t->start();
|
t->start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
slotNextRequest();
|
slotNextRequest();
|
||||||
|
|
||||||
if (m_blockingCall)
|
if (m_blockingCall)
|
||||||
{
|
{
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
connect(this, &RequestHelper::signalQuitLoop, &loop, &QEventLoop::quit, Qt::QueuedConnection);
|
connect(this, &RequestHelper::signalQuitLoop, &loop, &QEventLoop::quit, Qt::QueuedConnection);
|
||||||
loop.exec();
|
loop.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (!m_failed);
|
return (!m_failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+69
-70
@@ -27,114 +27,113 @@
|
|||||||
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>();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class LTSUTILSGUIDDS_INTERNAL_EXPORT RequestHelper : public QObject // TODO: DOC !!!
|
class LTSUTILSGUIDDS_INTERNAL_EXPORT RequestHelper : public QObject // TODO: DOC !!!
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static bool s_debug;
|
static bool s_debug;
|
||||||
|
|
||||||
explicit RequestHelper(QObject *parent = nullptr, bool quiet = false,
|
explicit RequestHelper(
|
||||||
// for non-blocking
|
QObject *parent = nullptr,
|
||||||
const std::function<void (void)> &success = [](){},
|
bool quiet = false,
|
||||||
const std::function<void (void)> &failure = [](){});
|
// for non-blocking
|
||||||
~RequestHelper() = default;
|
const std::function<void(void)> &success = []() {},
|
||||||
|
const std::function<void(void)> &failure = []() {});
|
||||||
|
~RequestHelper() = default;
|
||||||
|
|
||||||
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 !
|
||||||
/**
|
/**
|
||||||
* @brief startSingleBackgroundRequest << you cannot reuse this request helper after using background requests! Only use if your REALLY need it.
|
* @brief startSingleBackgroundRequest << you cannot reuse this request helper after using background requests! Only use if your REALLY need it.
|
||||||
* @param requestFunction
|
* @param requestFunction
|
||||||
* @param baseReplyHandler
|
* @param baseReplyHandler
|
||||||
*/
|
*/
|
||||||
void startSingleBackgroundRequest(const std::function<int64_t()> &requestFunction,
|
void startSingleBackgroundRequest(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);
|
||||||
/**
|
/**
|
||||||
* @brief startBackgroundRequests << you cannot reuse this request helper after using background requests! Only use if your REALLY need it.
|
* @brief startBackgroundRequests << you cannot reuse this request helper after using background requests! Only use if your REALLY need it.
|
||||||
*/
|
*/
|
||||||
void startBackgroundRequests(); // non-blocking !
|
void startBackgroundRequests(); // non-blocking !
|
||||||
|
|
||||||
bool requestReply(const Core::FunctionReply &baseReply); // if you have a custom FunctionReply, pass the base ptr
|
bool requestReply(const Core::FunctionReply &baseReply); // if you have a custom FunctionReply, pass the base ptr
|
||||||
bool requestReply(const Core::FunctionReplyObject &replyObject);
|
bool requestReply(const Core::FunctionReplyObject &replyObject);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief hasRequests are requests is added?
|
* @brief hasRequests are requests is added?
|
||||||
* @return True if a request is added, otherwise false
|
* @return True if a request is added, otherwise false
|
||||||
*/
|
*/
|
||||||
bool hasRequests() const { return !m_requestFunctions.isEmpty(); }
|
bool hasRequests() const { return !m_requestFunctions.isEmpty(); }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief getRepliedId returns the Return-ID of the ReplyObject you gave to the method 'requestReply' - which is mostly the ID for the new Table Entry (Unique ID)
|
* @brief getRepliedId returns the Return-ID of the ReplyObject you gave to the method 'requestReply' - which is mostly the ID for the new Table Entry (Unique ID)
|
||||||
* @return the Return-ID or -1 on error (not set)
|
* @return the Return-ID or -1 on error (not set)
|
||||||
*/
|
*/
|
||||||
int getRepliedId() const { return m_repliedId; }
|
int getRepliedId() const { return m_repliedId; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief getErrorString returns the error string set by an ftc reply
|
* @brief getErrorString returns the error string set by an ftc reply
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
QString getErrorString() const { return m_errorString; }
|
QString getErrorString() const { return m_errorString; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief setCustomWaitMessage changes the default 'Waiting for server reply ...' message with a custom one (NOTE: " ..." is automagically added to the custom text)
|
* @brief setCustomWaitMessage changes the default 'Waiting for server reply ...' message with a custom one (NOTE: " ..." is automagically added to the custom text)
|
||||||
* After a request was started, the custom wait message is immediately reset, so that the next call to start a request, shows the default message again
|
* After a request was started, the custom wait message is immediately reset, so that the next call to start a request, shows the default message again
|
||||||
* @param customWaitMessage the wait message to replace the default message with (note that " ..." is added to the text)
|
* @param customWaitMessage the wait message to replace the default message with (note that " ..." is added to the text)
|
||||||
*/
|
*/
|
||||||
void setCustomWaitMessage(const QString &customWaitMessage);
|
void setCustomWaitMessage(const QString &customWaitMessage);
|
||||||
|
|
||||||
bool failed() const { return m_failed; }
|
bool failed() const { return m_failed; }
|
||||||
void failure();
|
void failure();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using RequestFunctionContainer = QPair<std::function<int64_t()>, std::function<void(const Core::FunctionReply &)>>;
|
using RequestFunctionContainer = QPair<std::function<int64_t()>, std::function<void(const Core::FunctionReply &)>>;
|
||||||
|
|
||||||
QVector<RequestFunctionContainer> m_requestFunctions;
|
QVector<RequestFunctionContainer> m_requestFunctions;
|
||||||
bool m_failed;
|
bool m_failed;
|
||||||
int m_repliedId;
|
int m_repliedId;
|
||||||
std::function<void(const Core::FunctionReply &)> m_singleRequestCustomFunctionReply;
|
std::function<void(const Core::FunctionReply &)> m_singleRequestCustomFunctionReply;
|
||||||
bool m_quiet;
|
bool m_quiet;
|
||||||
bool m_blockingCall;
|
bool m_blockingCall;
|
||||||
std::function<void (void)> m_successFn;
|
std::function<void(void)> m_successFn;
|
||||||
std::function<void (void)> m_failureFn;
|
std::function<void(void)> m_failureFn;
|
||||||
QString m_errorString;
|
QString m_errorString;
|
||||||
QString m_customWaitMessage;
|
QString m_customWaitMessage;
|
||||||
|
|
||||||
void done();
|
void done();
|
||||||
bool _requestReply(const Core::FunctionReplyObject &fro, const Core::FunctionReply *baseReply);
|
bool _requestReply(const Core::FunctionReplyObject &fro, const Core::FunctionReply *baseReply);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void signalNextRequest();
|
void signalNextRequest();
|
||||||
void signalQuitLoop();
|
void signalQuitLoop();
|
||||||
void signalSuccess();
|
void signalSuccess();
|
||||||
void signalFailed();
|
void signalFailed();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotNextRequest();
|
void slotNextRequest();
|
||||||
|
};
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+39
-42
@@ -10,82 +10,79 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
struct StyleManagerHandler
|
struct StyleManagerHandler
|
||||||
{
|
{
|
||||||
StyleManager styleManager;
|
StyleManager styleManager;
|
||||||
};
|
};
|
||||||
Q_GLOBAL_STATIC(StyleManagerHandler, s_styleManagerHandler)
|
Q_GLOBAL_STATIC(StyleManagerHandler, s_styleManagerHandler)
|
||||||
|
|
||||||
StyleManager* StyleManager::getInstance()
|
StyleManager *StyleManager::getInstance()
|
||||||
{
|
{
|
||||||
return &s_styleManagerHandler->styleManager;
|
return &s_styleManagerHandler->styleManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StyleManager::loadStyle(const QString& stylePluginName, bool highDpi)
|
bool StyleManager::loadStyle(const QString &stylePluginName, bool highDpi)
|
||||||
{
|
{
|
||||||
if (m_currentStylePluginLoader != nullptr)
|
if (m_currentStylePluginLoader != nullptr)
|
||||||
{
|
{
|
||||||
|
|
||||||
QObject* pluginInstance = m_currentStylePluginLoader->instance();
|
QObject *pluginInstance = m_currentStylePluginLoader->instance();
|
||||||
StylePlugin::Plugin* sp = qobject_cast<StylePlugin::Plugin*>(pluginInstance);
|
StylePlugin::Plugin *sp = qobject_cast<StylePlugin::Plugin *>(pluginInstance);
|
||||||
|
|
||||||
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;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
sp->unloadStyle();
|
sp->unloadStyle();
|
||||||
|
|
||||||
m_currentStylePluginLoader = nullptr;
|
m_currentStylePluginLoader = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LtsPluginManager::LtsPluginLoader* pluginLoader = LtsPluginManager::LtsPluginLoader::getInstance();
|
LtsPluginManager::LtsPluginLoader *pluginLoader = LtsPluginManager::LtsPluginLoader::getInstance();
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!pluginLoader->loadPlugins(LtsPluginManager::PluginType::STYLE, loadPluginFn, QStringList() << stylePluginName))
|
if (!pluginLoader->loadPlugins(LtsPluginManager::PluginType::STYLE, loadPluginFn, QStringList() << stylePluginName))
|
||||||
{
|
{
|
||||||
qWarning() << "StyleManager::loadStyle: Error loading Style Plugin - using default Qt style";
|
qWarning() << "StyleManager::loadStyle: Error loading Style Plugin - using default Qt style";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stylePluginLoader == nullptr)
|
if (stylePluginLoader == nullptr)
|
||||||
{
|
{
|
||||||
qWarning() << "StyleManager::loadStyle: No Style Plugin loader available - using default Qt style";
|
qWarning() << "StyleManager::loadStyle: No Style Plugin loader available - using default Qt style";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
StylePlugin::Plugin* sp = qobject_cast<StylePlugin::Plugin*>(stylePluginLoader->instance());
|
StylePlugin::Plugin *sp = qobject_cast<StylePlugin::Plugin *>(stylePluginLoader->instance());
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp->loadStyle(highDpi);
|
sp->loadStyle(highDpi);
|
||||||
@@ -95,6 +92,6 @@ bool StyleManager::loadStyle(const QString& stylePluginName, bool highDpi)
|
|||||||
emit signalStyleChanged(stylePluginName);
|
emit signalStyleChanged(stylePluginName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+8
-11
@@ -10,29 +10,26 @@ class QPluginLoader;
|
|||||||
|
|
||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
class LTSUTILSGUISTYLEMANAGER_EXPORT StyleManager : public QObject
|
class LTSUTILSGUISTYLEMANAGER_EXPORT StyleManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
using QObject::QObject;
|
using QObject::QObject;
|
||||||
~StyleManager() = default;
|
~StyleManager() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static StyleManager* getInstance();
|
static StyleManager *getInstance();
|
||||||
|
|
||||||
bool loadStyle(const QString& stylePluginName, bool highDpi = false);
|
bool loadStyle(const QString &stylePluginName, bool highDpi = false);
|
||||||
|
|
||||||
const QString& currentStyleName() const
|
const QString ¤tStyleName() const { return m_stylePluginName; }
|
||||||
{
|
|
||||||
return m_stylePluginName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct StyleManagerHandler;
|
friend struct StyleManagerHandler;
|
||||||
|
|
||||||
QPluginLoader* m_currentStylePluginLoader = nullptr;
|
QPluginLoader *m_currentStylePluginLoader = nullptr;
|
||||||
QString m_stylePluginName;
|
QString m_stylePluginName;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void signalStyleChanged(const QString& stylePluginName);
|
void signalStyleChanged(const QString &stylePluginName);
|
||||||
};
|
};
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
+125
-124
@@ -16,233 +16,234 @@
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
enum class SettingType {
|
enum class SettingType
|
||||||
|
{
|
||||||
String = 1,
|
String = 1,
|
||||||
StringList = 2,
|
StringList = 2,
|
||||||
Json = 3,
|
Json = 3,
|
||||||
FunctionKeys = 4,
|
FunctionKeys = 4,
|
||||||
Boolean = 5,
|
Boolean = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
QString typeToString(SettingType t)
|
QString typeToString(SettingType t)
|
||||||
{
|
{
|
||||||
switch (t)
|
switch (t)
|
||||||
{
|
{
|
||||||
case SettingType::String:
|
case SettingType::String:
|
||||||
return QStringLiteral("String");
|
return QStringLiteral("String");
|
||||||
case SettingType::StringList:
|
case SettingType::StringList:
|
||||||
return QStringLiteral("StringList");
|
return QStringLiteral("StringList");
|
||||||
case SettingType::Json:
|
case SettingType::Json:
|
||||||
return QStringLiteral("Json");
|
return QStringLiteral("Json");
|
||||||
case SettingType::FunctionKeys:
|
case SettingType::FunctionKeys:
|
||||||
return QStringLiteral("FunctionKeys");
|
return QStringLiteral("FunctionKeys");
|
||||||
case SettingType::Boolean:
|
case SettingType::Boolean:
|
||||||
return QStringLiteral("Boolean");
|
return QStringLiteral("Boolean");
|
||||||
}
|
}
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
return QStringLiteral("Unknown SettingType (%1)").arg(int(t));
|
return QStringLiteral("Unknown SettingType (%1)").arg(int(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingType stringToType(const QString& s)
|
SettingType stringToType(const QString &s)
|
||||||
{
|
{
|
||||||
if (s == typeToString(SettingType::String))
|
if (s == typeToString(SettingType::String))
|
||||||
return SettingType::String;
|
return SettingType::String;
|
||||||
if (s == typeToString(SettingType::StringList))
|
if (s == typeToString(SettingType::StringList))
|
||||||
return SettingType::StringList;
|
return SettingType::StringList;
|
||||||
if (s == typeToString(SettingType::Json))
|
if (s == typeToString(SettingType::Json))
|
||||||
return SettingType::Json;
|
return SettingType::Json;
|
||||||
if (s == typeToString(SettingType::FunctionKeys))
|
if (s == typeToString(SettingType::FunctionKeys))
|
||||||
return SettingType::FunctionKeys;
|
return SettingType::FunctionKeys;
|
||||||
if (s == typeToString(SettingType::Boolean))
|
if (s == typeToString(SettingType::Boolean))
|
||||||
return SettingType::Boolean;
|
return SettingType::Boolean;
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
return SettingType::String;
|
return SettingType::String;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString craftKey(const QString& group, const QString& identifier)
|
static QString craftKey(const QString &group, const QString &identifier)
|
||||||
{
|
{
|
||||||
return group + QLatin1Char('.') + identifier;
|
return group + QLatin1Char('.') + identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
static OperatorSettings* s_operatorSettings = nullptr;
|
static OperatorSettings *s_operatorSettings = nullptr;
|
||||||
|
|
||||||
static void cleanupOperatorSettings()
|
static void cleanupOperatorSettings()
|
||||||
{
|
{
|
||||||
delete s_operatorSettings;
|
delete s_operatorSettings;
|
||||||
s_operatorSettings = nullptr;
|
s_operatorSettings = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
OperatorSettings* OperatorSettings::getInstance()
|
OperatorSettings *OperatorSettings::getInstance()
|
||||||
{
|
{
|
||||||
if (!s_operatorSettings)
|
if (!s_operatorSettings)
|
||||||
{
|
{
|
||||||
s_operatorSettings = new OperatorSettings;
|
s_operatorSettings = new OperatorSettings;
|
||||||
qAddPostRoutine(&cleanupOperatorSettings);
|
qAddPostRoutine(&cleanupOperatorSettings);
|
||||||
}
|
}
|
||||||
return s_operatorSettings;
|
return s_operatorSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ProjectSettings* s_projectSettings = nullptr;
|
static ProjectSettings *s_projectSettings = nullptr;
|
||||||
|
|
||||||
static void cleanupProjectSettings()
|
static void cleanupProjectSettings()
|
||||||
{
|
{
|
||||||
delete s_projectSettings;
|
delete s_projectSettings;
|
||||||
s_projectSettings = nullptr;
|
s_projectSettings = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectSettings* ProjectSettings::getInstance()
|
ProjectSettings *ProjectSettings::getInstance()
|
||||||
{
|
{
|
||||||
if (!s_projectSettings)
|
if (!s_projectSettings)
|
||||||
{
|
{
|
||||||
s_projectSettings = new ProjectSettings;
|
s_projectSettings = new ProjectSettings;
|
||||||
qAddPostRoutine(&cleanupProjectSettings);
|
qAddPostRoutine(&cleanupProjectSettings);
|
||||||
}
|
}
|
||||||
return s_projectSettings;
|
return s_projectSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProjectSettings::initFromFile(const QString& filename)
|
bool ProjectSettings::initFromFile(const QString &filename)
|
||||||
{
|
{
|
||||||
QFile f(filename);
|
QFile f(filename);
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
if (!f.open(QIODevice::ReadOnly))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QJsonParseError jErr;
|
QJsonParseError jErr;
|
||||||
const QJsonObject settings = QJsonDocument::fromJson(f.readAll(), &jErr).object();
|
const QJsonObject settings = QJsonDocument::fromJson(f.readAll(), &jErr).object();
|
||||||
if (jErr.error != QJsonParseError::NoError)
|
if (jErr.error != QJsonParseError::NoError)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const QJsonObject psObj = settings[QStringLiteral("ProjectSettings")].toObject();
|
const QJsonObject psObj = settings[QStringLiteral("ProjectSettings")].toObject();
|
||||||
if (psObj.isEmpty())
|
if (psObj.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QHash<QString, QVariant> newData;
|
QHash<QString, QVariant> newData;
|
||||||
const QStringList& groupKeys(psObj.keys());
|
const QStringList &groupKeys(psObj.keys());
|
||||||
for (const auto& gKey : groupKeys)
|
for (const auto &gKey : groupKeys)
|
||||||
{
|
{
|
||||||
const QJsonObject objGroup(psObj[gKey].toObject());
|
const QJsonObject objGroup(psObj[gKey].toObject());
|
||||||
const QStringList& itemKeys(objGroup.keys());
|
const QStringList &itemKeys(objGroup.keys());
|
||||||
for (const auto& key : itemKeys)
|
for (const auto &key : itemKeys)
|
||||||
|
{
|
||||||
|
const QJsonObject obj(objGroup[key].toObject());
|
||||||
|
const auto strType(obj[QStringLiteral("Type")].toString());
|
||||||
|
const auto type = stringToType(strType);
|
||||||
|
const QJsonValue jVal(obj[QStringLiteral("Default")]);
|
||||||
|
QVariant val;
|
||||||
|
switch (type)
|
||||||
{
|
{
|
||||||
const QJsonObject obj(objGroup[key].toObject());
|
case SettingType::Json:
|
||||||
const auto strType(obj[QStringLiteral("Type")].toString());
|
val = QJsonDocument(jVal.toObject()).toJson();
|
||||||
const auto type = stringToType(strType);
|
break;
|
||||||
const QJsonValue jVal(obj[QStringLiteral("Default")]);
|
case SettingType::StringList:
|
||||||
QVariant val;
|
{
|
||||||
switch (type)
|
const QJsonArray arr(jVal.toArray());
|
||||||
{
|
QStringList sl;
|
||||||
case SettingType::Json:
|
sl.reserve(arr.size());
|
||||||
val = QJsonDocument(jVal.toObject()).toJson();
|
for (const auto &ele : arr)
|
||||||
break;
|
sl.push_back(ele.toString());
|
||||||
case SettingType::StringList: {
|
val = sl;
|
||||||
const QJsonArray arr(jVal.toArray());
|
break;
|
||||||
QStringList sl;
|
}
|
||||||
sl.reserve(arr.size());
|
case SettingType::FunctionKeys:
|
||||||
for (const auto& ele : arr)
|
val = jVal.toVariant();
|
||||||
sl.push_back(ele.toString());
|
break;
|
||||||
val = sl;
|
case SettingType::String:
|
||||||
break;
|
val = jVal.toString();
|
||||||
}
|
break;
|
||||||
case SettingType::FunctionKeys:
|
case SettingType::Boolean:
|
||||||
val = jVal.toVariant();
|
val = jVal.toBool();
|
||||||
break;
|
break;
|
||||||
case SettingType::String:
|
|
||||||
val = jVal.toString();
|
|
||||||
break;
|
|
||||||
case SettingType::Boolean:
|
|
||||||
val = jVal.toBool();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
newData[craftKey(gKey, key)] = val;
|
|
||||||
}
|
}
|
||||||
|
newData[craftKey(gKey, key)] = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
getInstance()->m_data = newData;
|
getInstance()->m_data = newData;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::init(const QByteArray& settings)
|
void Settings::init(const QByteArray &settings)
|
||||||
{
|
{
|
||||||
QByteArray uncompressed;
|
QByteArray uncompressed;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
uncompressed = qUncompress(settings);
|
uncompressed = qUncompress(settings);
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uncompressed.isEmpty())
|
if (uncompressed.isEmpty())
|
||||||
uncompressed = settings;
|
uncompressed = settings;
|
||||||
|
|
||||||
QDataStream stream(uncompressed);
|
QDataStream stream(uncompressed);
|
||||||
stream >> m_data;
|
stream >> m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray Settings::exportSettings() const
|
QByteArray Settings::exportSettings() const
|
||||||
{
|
{
|
||||||
if (m_data.isEmpty())
|
if (m_data.isEmpty())
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
|
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
QDataStream stream(&ba, QIODevice::WriteOnly);
|
QDataStream stream(&ba, QIODevice::WriteOnly);
|
||||||
stream << m_data;
|
stream << m_data;
|
||||||
return qCompress(ba);
|
return qCompress(ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::clear()
|
void Settings::clear()
|
||||||
{
|
{
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::dump()
|
void Settings::dump()
|
||||||
{
|
{
|
||||||
qWarning() << "Settings::m_data: keys=" << m_data.keys();
|
qWarning() << "Settings::m_data: keys=" << m_data.keys();
|
||||||
QHashIterator<QString, QVariant> it(m_data);
|
QHashIterator<QString, QVariant> it(m_data);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (it.hasNext())
|
while (it.hasNext())
|
||||||
{
|
{
|
||||||
it.next();
|
it.next();
|
||||||
qWarning() << i++ << ":"
|
qWarning() << i++ << ":"
|
||||||
<< " - key='" << it.key() << "' value -> '" << it.value() << "'";
|
<< " - key='" << it.key() << "' value -> '" << it.value() << "'";
|
||||||
}
|
}
|
||||||
qWarning() << "Settings::m_data: ------------------";
|
qWarning() << "Settings::m_data: ------------------";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setValue(const QString& group, const QString& identifier, const QVariant& value)
|
void Settings::setValue(const QString &group, const QString &identifier, const QVariant &value)
|
||||||
{
|
{
|
||||||
|
|
||||||
m_data.insert(craftKey(group, identifier), value);
|
m_data.insert(craftKey(group, identifier), value);
|
||||||
emit valueChanged(group, identifier, value);
|
emit valueChanged(group, identifier, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::removeValue(const QString& group, const QString& identifier)
|
void Settings::removeValue(const QString &group, const QString &identifier)
|
||||||
{
|
{
|
||||||
if (m_data.remove(craftKey(group, identifier)))
|
if (m_data.remove(craftKey(group, identifier)))
|
||||||
emit valueRemoved(group, identifier);
|
emit valueRemoved(group, identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Settings::identifiers(const QString& group) const
|
QStringList Settings::identifiers(const QString &group) const
|
||||||
{
|
{
|
||||||
QStringList result;
|
QStringList result;
|
||||||
for (auto it = m_data.begin(); it != m_data.end(); ++it)
|
for (auto it = m_data.begin(); it != m_data.end(); ++it)
|
||||||
{
|
{
|
||||||
const QStringList decrafted = QString(it.key()).split(QLatin1Char('.'));
|
const QStringList decrafted = QString(it.key()).split(QLatin1Char('.'));
|
||||||
if (decrafted.size() > 1 && QStringView(group).compare(decrafted.at(0)) == 0)
|
if (decrafted.size() > 1 && QStringView(group).compare(decrafted.at(0)) == 0)
|
||||||
result.append(decrafted.at(0).mid(1));
|
result.append(decrafted.at(0).mid(1));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant Settings::value(const QString& group, const QString& identifier, const QVariant& defaultValue) const
|
QVariant Settings::value(const QString &group, const QString &identifier, const QVariant &defaultValue) const
|
||||||
{
|
{
|
||||||
return m_data.value(craftKey(group, identifier), defaultValue);
|
return m_data.value(craftKey(group, identifier), defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -12,22 +12,22 @@ class QJsonObject;
|
|||||||
namespace LtsUtils
|
namespace LtsUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
class LTSUTILSSETTINGS_EXPORT Settings : public QObject
|
class LTSUTILSSETTINGS_EXPORT Settings : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
~Settings() = default;
|
~Settings() = default;
|
||||||
|
|
||||||
void setValue(const QString& group, const QString& identifier, const QVariant& value);
|
void setValue(const QString &group, const QString &identifier, const QVariant &value);
|
||||||
|
|
||||||
void removeValue(const QString& group, const QString& identifier);
|
void removeValue(const QString &group, const QString &identifier);
|
||||||
|
|
||||||
QVariant value(const QString& group, const QString& identifier, const QVariant& defaultValue = QVariant()) const;
|
QVariant value(const QString &group, const QString &identifier, const QVariant &defaultValue = QVariant()) const;
|
||||||
|
|
||||||
QStringList identifiers(const QString& group) const;
|
QStringList identifiers(const QString &group) const;
|
||||||
|
|
||||||
void init(const QByteArray& settings);
|
void init(const QByteArray &settings);
|
||||||
QByteArray exportSettings() const;
|
QByteArray exportSettings() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
@@ -37,28 +37,28 @@ class LTSUTILSSETTINGS_EXPORT Settings : public QObject
|
|||||||
Settings() = default;
|
Settings() = default;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void valueChanged(const QString& group, const QString& identifier, const QVariant& value);
|
void valueChanged(const QString &group, const QString &identifier, const QVariant &value);
|
||||||
void valueRemoved(const QString& group, const QString& identifier);
|
void valueRemoved(const QString &group, const QString &identifier);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<QString, QVariant> m_data;
|
QHash<QString, QVariant> m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LTSUTILSSETTINGS_EXPORT OperatorSettings : public Settings
|
class LTSUTILSSETTINGS_EXPORT OperatorSettings : public Settings
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static OperatorSettings* getInstance();
|
static OperatorSettings *getInstance();
|
||||||
};
|
};
|
||||||
|
|
||||||
class LTSUTILSSETTINGS_EXPORT ProjectSettings : public Settings
|
class LTSUTILSSETTINGS_EXPORT ProjectSettings : public Settings
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
static ProjectSettings* getInstance();
|
static ProjectSettings *getInstance();
|
||||||
|
|
||||||
static bool initFromFile(const QString& filename);
|
static bool initFromFile(const QString &filename);
|
||||||
static bool isFunctionEnabled(const QString& group, const QString& function);
|
static bool isFunctionEnabled(const QString &group, const QString &function);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsUtils
|
} // namespace LtsUtils
|
||||||
@@ -10,80 +10,80 @@
|
|||||||
namespace LtsWebSocket
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
ClientConnection::~ClientConnection()
|
ClientConnection::~ClientConnection()
|
||||||
{
|
{
|
||||||
DEBUG_LOG(m_logger) << "Thread closed" << this;
|
DEBUG_LOG(m_logger) << "Thread closed" << this;
|
||||||
delete m_socket;
|
delete m_socket;
|
||||||
qDeleteAll(m_messageQueue);
|
qDeleteAll(m_messageQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
bool ClientConnection::init()
|
bool ClientConnection::init()
|
||||||
{
|
{
|
||||||
if (m_socket == nullptr)
|
if (m_socket == nullptr)
|
||||||
{
|
{
|
||||||
ERROR_LOG(m_logger) << "Initialisation failed due to an invalid socket";
|
ERROR_LOG(m_logger) << "Initialisation failed due to an invalid socket";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnection::addReply(ReplyMessage* message)
|
void ClientConnection::addReply(ReplyMessage *message)
|
||||||
{
|
{
|
||||||
if (!m_socket || m_socket->state() != QAbstractSocket::ConnectedState)
|
if (!m_socket || m_socket->state() != QAbstractSocket::ConnectedState)
|
||||||
{
|
{
|
||||||
m_messageQueue.enqueue(message);
|
m_messageQueue.enqueue(message);
|
||||||
DEBUG_LOG(m_logger) << "Adding message to queue, size: " << m_messageQueue.size();
|
DEBUG_LOG(m_logger) << "Adding message to queue, size: " << m_messageQueue.size();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QString msg(message->toJsonString());
|
const QString msg(message->toJsonString());
|
||||||
DEBUG_LOG(m_logger) << "Sending message: " << msg;
|
DEBUG_LOG(m_logger) << "Sending message: " << msg;
|
||||||
m_socket->sendTextMessage(msg);
|
m_socket->sendTextMessage(msg);
|
||||||
delete message;
|
delete message;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnection::onNewTextMessageFromSocket(const QString& message)
|
void ClientConnection::onNewTextMessageFromSocket(const QString &message)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(m_logger) << "Recv msg: " << message << this;
|
DEBUG_LOG(m_logger) << "Recv msg: " << message << this;
|
||||||
emit newTextMessage(this, message);
|
emit newTextMessage(this, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientConnection::sendMessagesFromQueue()
|
void ClientConnection::sendMessagesFromQueue()
|
||||||
{
|
{
|
||||||
INFO_LOG(m_logger) << "Client connected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
INFO_LOG(m_logger) << "Client connected ip: " << m_socket->peerAddress().toString() << ":" << m_socket->peerPort();
|
||||||
|
|
||||||
if (m_socket->state() != QAbstractSocket::ConnectedState)
|
if (m_socket->state() != QAbstractSocket::ConnectedState)
|
||||||
return;
|
return;
|
||||||
while (!m_messageQueue.isEmpty())
|
while (!m_messageQueue.isEmpty())
|
||||||
{
|
{
|
||||||
ReplyMessage* message = m_messageQueue.dequeue();
|
ReplyMessage *message = m_messageQueue.dequeue();
|
||||||
const QString msg(message->toJsonString());
|
const QString msg(message->toJsonString());
|
||||||
TRACE_LOG(m_logger) << "Send msg: " << msg;
|
TRACE_LOG(m_logger) << "Send msg: " << msg;
|
||||||
m_socket->sendTextMessage(msg);
|
m_socket->sendTextMessage(msg);
|
||||||
delete message;
|
delete message;
|
||||||
DEBUG_LOG(m_logger) << "Sent message from queue, new size: " << m_messageQueue.size();
|
DEBUG_LOG(m_logger) << "Sent message from queue, new size: " << m_messageQueue.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
@@ -12,68 +12,70 @@
|
|||||||
#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
|
||||||
{
|
{
|
||||||
class QWebSocketStub
|
class QWebSocketStub
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QWebSocketStub(QObject* parent = nullptr) { Q_UNUSED(parent); }
|
QWebSocketStub(QObject *parent = nullptr) { Q_UNUSED(parent); }
|
||||||
virtual ~QWebSocketStub() = default;
|
virtual ~QWebSocketStub() = default;
|
||||||
void sendTextMessage(const QString& /*message*/) {}
|
void sendTextMessage(const QString & /*message*/) {}
|
||||||
void close() {}
|
void close() {}
|
||||||
bool isValid() const { return false; }
|
bool isValid() const { return false; }
|
||||||
QString errorString() const { return QString(); }
|
QString errorString() const { return QString(); }
|
||||||
};
|
};
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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:
|
||||||
explicit ClientConnection(QWebSocket* socket, QObject* parent = nullptr);
|
explicit ClientConnection(QWebSocket *socket, QObject *parent = nullptr);
|
||||||
|
|
||||||
~ClientConnection();
|
~ClientConnection();
|
||||||
|
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
bool init();
|
bool init();
|
||||||
|
|
||||||
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 {}
|
||||||
QWebSocket* webSocket() { return nullptr; }
|
QWebSocket *webSocket() { return nullptr; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void newTextMessage(ClientConnection* client, const QString& message);
|
void newTextMessage(ClientConnection *client, const QString &message);
|
||||||
|
|
||||||
void disconnected(ClientConnection* client);
|
void disconnected(ClientConnection *client);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
void onNewTextMessageFromSocket(const QString& message);
|
void onNewTextMessageFromSocket(const QString &message);
|
||||||
void sendMessagesFromQueue();
|
void sendMessagesFromQueue();
|
||||||
void onSocketDisconnect();
|
void onSocketDisconnect();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NGL::INGLLogger& m_logger;
|
NGL::INGLLogger &m_logger;
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
void sendMessages();
|
void sendMessages();
|
||||||
#endif
|
#endif
|
||||||
QWebSocket* m_socket;
|
QWebSocket *m_socket;
|
||||||
QQueue<ReplyMessage*> m_messageQueue;
|
QQueue<ReplyMessage *> m_messageQueue;
|
||||||
};
|
};
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
@@ -9,13 +9,14 @@
|
|||||||
namespace LtsWebSocket
|
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)
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void InvalidMessage::process()
|
void InvalidMessage::process()
|
||||||
{
|
{
|
||||||
ErrorMessage::ErrorData errorData;
|
ErrorMessage::ErrorData errorData;
|
||||||
|
|
||||||
errorData.errorClass = 1;
|
errorData.errorClass = 1;
|
||||||
@@ -23,12 +24,12 @@ void InvalidMessage::process()
|
|||||||
errorData.uuid = m_uuid;
|
errorData.uuid = m_uuid;
|
||||||
|
|
||||||
m_client->addReply(new ErrorMessage(errorData));
|
m_client->addReply(new ErrorMessage(errorData));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InvalidMessage::hasValidData() const
|
bool InvalidMessage::hasValidData() const
|
||||||
{
|
{
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
@@ -11,12 +11,15 @@
|
|||||||
namespace LtsWebSocket
|
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,29 +29,26 @@ 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;
|
||||||
const int m_typeId;
|
const int m_typeId;
|
||||||
const QString m_uuid;
|
const QString m_uuid;
|
||||||
const QJsonValue m_data;
|
const QJsonValue m_data;
|
||||||
ReplyHandler* m_client;
|
ReplyHandler *m_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LTSWEBSOCKETCOMMON_EXPORT InvalidMessage final : public AbstractClientMessage
|
class LTSWEBSOCKETCOMMON_EXPORT InvalidMessage final : public AbstractClientMessage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit InvalidMessage(ReplyHandler* client, const QString& uuid, const QString& errorText);
|
explicit InvalidMessage(ReplyHandler *client, const QString &uuid, const QString &errorText);
|
||||||
|
|
||||||
void process() override;
|
void process() override;
|
||||||
bool hasValidData() const override;
|
bool hasValidData() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_errorText;
|
QString m_errorText;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
@@ -10,13 +10,13 @@
|
|||||||
namespace LtsWebSocket
|
namespace LtsWebSocket
|
||||||
{
|
{
|
||||||
|
|
||||||
QJsonParseError AbstractClientMessageFactory::parseMessage(const QString& message)
|
QJsonParseError AbstractClientMessageFactory::parseMessage(const QString &message)
|
||||||
{
|
{
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);
|
QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8(), &error);
|
||||||
|
|
||||||
if (error.error != QJsonParseError::NoError)
|
if (error.error != QJsonParseError::NoError)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
QJsonObject obj = doc.object();
|
QJsonObject obj = doc.object();
|
||||||
|
|
||||||
@@ -26,38 +26,37 @@ QJsonParseError AbstractClientMessageFactory::parseMessage(const QString& messag
|
|||||||
m_uuid = obj.value(JsonKeys::UUID_()).toString();
|
m_uuid = obj.value(JsonKeys::UUID_()).toString();
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractClientMessage* AbstractClientMessageFactory::checkAttributes(ReplyHandler* client, const QString& message) const
|
AbstractClientMessage *AbstractClientMessageFactory::checkAttributes(ReplyHandler *client, const QString &message) const
|
||||||
{
|
{
|
||||||
if (!m_uuid.isEmpty() && !m_type.isEmpty())
|
if (!m_uuid.isEmpty() && !m_type.isEmpty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (m_uuid.isEmpty())
|
if (m_uuid.isEmpty())
|
||||||
{
|
{
|
||||||
WARNING_LOG(m_logger) << "Got message without uuid: " << message << "'";
|
WARNING_LOG(m_logger) << "Got message without uuid: " << message << "'";
|
||||||
return new LtsWebSocket::InvalidMessage(client, QString(), QStringLiteral("Got message without uuid"));
|
return new LtsWebSocket::InvalidMessage(client, QString(), QStringLiteral("Got message without uuid"));
|
||||||
}
|
}
|
||||||
WARNING_LOG(m_logger) << "Got message no type: " << message << "'";
|
WARNING_LOG(m_logger) << "Got message no type: " << message << "'";
|
||||||
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)
|
||||||
{
|
{
|
||||||
WARNING_LOG(m_logger) << "Could not parse message: " << message;
|
WARNING_LOG(m_logger) << "Could not parse message: " << message;
|
||||||
result = new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Invalid type"));
|
result = new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Invalid type"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result->hasValidData())
|
if (!result->hasValidData())
|
||||||
{
|
{
|
||||||
WARNING_LOG(m_logger) << "Resulting JSon message has invalid data... " << message;
|
WARNING_LOG(m_logger) << "Resulting JSon message has invalid data... " << message;
|
||||||
delete result;
|
delete result;
|
||||||
result = new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Has invalid data part"));
|
result = new LtsWebSocket::InvalidMessage(client, m_uuid, QStringLiteral("Has invalid data part"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
@@ -11,58 +11,55 @@
|
|||||||
|
|
||||||
namespace NGL
|
namespace NGL
|
||||||
{
|
{
|
||||||
class INGLLogger;
|
class INGLLogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace LtsWebSocket
|
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() {}
|
||||||
|
|
||||||
QJsonParseError parseMessage(const QString& message);
|
QJsonParseError parseMessage(const QString &message);
|
||||||
|
|
||||||
virtual AbstractClientMessage* createMessage(ReplyHandler* client, const QString& message) = 0;
|
virtual AbstractClientMessage *createMessage(ReplyHandler *client, const QString &message) = 0;
|
||||||
|
|
||||||
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;
|
||||||
QString m_type;
|
QString m_type;
|
||||||
int m_typeId;
|
int m_typeId;
|
||||||
QString m_uuid;
|
QString m_uuid;
|
||||||
QJsonValue m_data;
|
QJsonValue m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
@@ -12,84 +12,84 @@
|
|||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionHandler::~ConnectionHandler()
|
ConnectionHandler::~ConnectionHandler()
|
||||||
{
|
{
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
for (auto connection : std::as_const(m_connections))
|
for (auto connection : std::as_const(m_connections))
|
||||||
connection->disconnect(this);
|
connection->disconnect(this);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
bool ConnectionHandler::init(const QString& serviceName, unsigned short port)
|
bool ConnectionHandler::init(const QString &serviceName, unsigned short port)
|
||||||
{
|
{
|
||||||
if (m_server != nullptr)
|
if (m_server != nullptr)
|
||||||
{
|
{
|
||||||
m_server->disconnect();
|
m_server->disconnect();
|
||||||
delete m_server;
|
delete m_server;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_server = new QWebSocketServer(QStringLiteral("RME-") + serviceName, QWebSocketServer::NonSecureMode, this);
|
m_server = new QWebSocketServer(QStringLiteral("RME-") + serviceName, QWebSocketServer::NonSecureMode, this);
|
||||||
|
|
||||||
connect(m_server, &QWebSocketServer::newConnection, this, &ConnectionHandler::onNewConnection);
|
connect(m_server, &QWebSocketServer::newConnection, this, &ConnectionHandler::onNewConnection);
|
||||||
connect(m_server, &QWebSocketServer::serverError, this, &ConnectionHandler::onServerError);
|
connect(m_server, &QWebSocketServer::serverError, this, &ConnectionHandler::onServerError);
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Trying to listen ";
|
DEBUG_LOG(m_logger) << "Trying to listen ";
|
||||||
if (!m_server->listen(QHostAddress::Any, port))
|
if (!m_server->listen(QHostAddress::Any, port))
|
||||||
{
|
{
|
||||||
ERROR_LOG(m_logger) << "Not possible to listen to port " << port;
|
ERROR_LOG(m_logger) << "Not possible to listen to port " << port;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DEBUG_LOG(m_logger) << "... ok, port " << m_server->serverPort();
|
DEBUG_LOG(m_logger) << "... ok, port " << m_server->serverPort();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionHandler::sendToAllClients(ReplyMessage* message)
|
void ConnectionHandler::sendToAllClients(ReplyMessage *message)
|
||||||
{
|
{
|
||||||
for (auto connection : std::as_const(m_connections))
|
for (auto connection : std::as_const(m_connections))
|
||||||
connection->addReply(new ReplyMessage(*message));
|
connection->addReply(new ReplyMessage(*message));
|
||||||
|
|
||||||
delete message;
|
delete message;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionHandler::onServerError(QWebSocketProtocol::CloseCode closeCode)
|
void ConnectionHandler::onServerError(QWebSocketProtocol::CloseCode closeCode)
|
||||||
{
|
{
|
||||||
ERROR_LOG(m_logger) << "Got server error with close code " << closeCode;
|
ERROR_LOG(m_logger) << "Got server error with close code " << closeCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionHandler::onNewConnection()
|
void ConnectionHandler::onNewConnection()
|
||||||
{
|
{
|
||||||
while (m_server->hasPendingConnections())
|
while (m_server->hasPendingConnections())
|
||||||
|
{
|
||||||
|
QWebSocket *socket = m_server->nextPendingConnection();
|
||||||
|
|
||||||
|
ClientConnection *newConnection = new ClientConnection(socket, this);
|
||||||
|
connect(newConnection, &ClientConnection::destroyed, this, [this](QObject *o) { m_connections.remove(static_cast<ClientConnection *>(o)); });
|
||||||
|
|
||||||
|
if (!newConnection->init())
|
||||||
{
|
{
|
||||||
QWebSocket* socket = m_server->nextPendingConnection();
|
ERROR_LOG(m_logger) << "Failed to initialise new client";
|
||||||
|
delete newConnection;
|
||||||
ClientConnection* newConnection = new ClientConnection(socket, this);
|
newConnection = nullptr;
|
||||||
connect(newConnection, &ClientConnection::destroyed, this,
|
continue;
|
||||||
[this](QObject* o) { m_connections.remove(static_cast<ClientConnection*>(o)); });
|
|
||||||
|
|
||||||
if (!newConnection->init())
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Failed to initialise new client";
|
|
||||||
delete newConnection;
|
|
||||||
newConnection = nullptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
newConnection->start();
|
|
||||||
|
|
||||||
connect(newConnection, &ClientConnection::newTextMessage, this, &ConnectionHandler::newTextMessageFromClient);
|
|
||||||
connect(newConnection, &ClientConnection::disconnected, this, &ConnectionHandler::clientDisconnected);
|
|
||||||
connect(newConnection, &ClientConnection::finished, newConnection, &ClientConnection::deleteLater);
|
|
||||||
|
|
||||||
m_connections.insert(newConnection);
|
|
||||||
emit clientConnected(newConnection);
|
|
||||||
INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":"
|
|
||||||
<< socket->localPort();
|
|
||||||
}
|
}
|
||||||
|
newConnection->start();
|
||||||
|
|
||||||
|
connect(newConnection, &ClientConnection::newTextMessage, this, &ConnectionHandler::newTextMessageFromClient);
|
||||||
|
connect(newConnection, &ClientConnection::disconnected, this, &ConnectionHandler::clientDisconnected);
|
||||||
|
connect(newConnection, &ClientConnection::finished, newConnection, &ClientConnection::deleteLater);
|
||||||
|
|
||||||
|
m_connections.insert(newConnection);
|
||||||
|
emit clientConnected(newConnection);
|
||||||
|
INFO_LOG(m_logger) << "New client connected ip: " << socket->localAddress().toString() << ":" << socket->localPort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -11,46 +11,52 @@
|
|||||||
#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
|
||||||
{
|
{
|
||||||
class MessageHandler;
|
class MessageHandler;
|
||||||
class ClientConnection;
|
class ClientConnection;
|
||||||
class ReplyMessage;
|
class ReplyMessage;
|
||||||
|
|
||||||
class ConnectionHandler : public QObject
|
class ConnectionHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit ConnectionHandler(QObject* parent = nullptr);
|
explicit ConnectionHandler(QObject *parent = nullptr);
|
||||||
~ConnectionHandler();
|
~ConnectionHandler();
|
||||||
|
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
bool init(const QString& serviceName, unsigned short port);
|
bool init(const QString &serviceName, unsigned short port);
|
||||||
|
|
||||||
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*/) {}
|
||||||
unsigned short webSocketPort() { return 0; }
|
unsigned short webSocketPort() { return 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void newTextMessageFromClient(ClientConnection* client, const QString& message);
|
void newTextMessageFromClient(ClientConnection *client, const QString &message);
|
||||||
|
|
||||||
void clientDisconnected(ClientConnection* client);
|
void clientDisconnected(ClientConnection *client);
|
||||||
|
|
||||||
void clientConnected(ClientConnection* client);
|
void clientConnected(ClientConnection *client);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
@@ -59,12 +65,12 @@ class ConnectionHandler : public QObject
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NGL::INGLLogger& m_logger;
|
NGL::INGLLogger &m_logger;
|
||||||
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
#ifdef QT6_WEBSOCKETS_AVAILABLE
|
||||||
QWebSocketServer* m_server;
|
QWebSocketServer *m_server;
|
||||||
#else
|
#else
|
||||||
void* m_server;
|
void *m_server;
|
||||||
#endif
|
#endif
|
||||||
QSet<ClientConnection*> m_connections;
|
QSet<ClientConnection *> m_connections;
|
||||||
};
|
};
|
||||||
} // namespace LtsWebSocket
|
} // namespace LtsWebSocket
|
||||||
Loaded 100 of 742 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user