Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
638a37a252 |
No files matched your search
-11
@@ -1,11 +0,0 @@
|
|||||||
build-rti-full
|
|
||||||
build-rti-off
|
|
||||||
build-rti-off-notests
|
|
||||||
build-*
|
|
||||||
build_*
|
|
||||||
CMakeFiles
|
|
||||||
fix_qt6_gui_deps2.py
|
|
||||||
fix_qt6_gui_deps.py
|
|
||||||
fix_rti_conditionals.py
|
|
||||||
fix_target_checks.py
|
|
||||||
build
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
build-rti-full
|
|
||||||
build-rti-off
|
|
||||||
build-rti-off-notests
|
|
||||||
build-*
|
|
||||||
CMakeFiles
|
|
||||||
fix_qt6_gui_deps2.py
|
|
||||||
fix_qt6_gui_deps.py
|
|
||||||
fix_rti_conditionals.py
|
|
||||||
fix_target_checks.py
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../external
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
---
|
|
||||||
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
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
export MIGRATE_PIPELINE_ROOT="/home/torsten/sandbox/qt6-migration-pipeline"
|
|
||||||
export LANG=C.UTF-8
|
|
||||||
export LC_ALL=C.UTF-8
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
build-rti-full
|
|
||||||
build-rti-off
|
|
||||||
build-rti-off-notests
|
|
||||||
build-*
|
|
||||||
CMakeFiles
|
|
||||||
fix_qt6_gui_deps2.py
|
|
||||||
fix_qt6_gui_deps.py
|
|
||||||
fix_rti_conditionals.py
|
|
||||||
fix_target_checks.py
|
|
||||||
Lts/Tools/ArAssetsV2/build
|
|
||||||
Lts/Tools/ArAssetsV3/build
|
|
||||||
Lts/Tools/ArAssetsV3_Qatar/build
|
|
||||||
build/
|
|
||||||
build2/
|
|
||||||
.envrc
|
|
||||||
build4
|
|
||||||
coverage-out/
|
|
||||||
Whitespace-only changes.
@@ -1,675 +0,0 @@
|
|||||||
#
|
|
||||||
# Haupt CMakeLists.txt für das Projekt TDS
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
# Setzen von CMAKE_INSTALL_PREFIX auf "/shd/CTC" falls nicht über Kommandozeile angegeben
|
|
||||||
#
|
|
||||||
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 3.16)
|
|
||||||
IF(POLICY CMP0069)
|
|
||||||
CMAKE_POLICY(SET CMP0069 NEW) # cmake >= 3.9.0 - INTERPROCEDURAL_OPTIMIZATION behavior
|
|
||||||
ENDIF()
|
|
||||||
IF(POLICY CMP0071)
|
|
||||||
CMAKE_POLICY(SET CMP0071 NEW) # cmake >= 3.10.0 - automatically process generated sources with AUTOMOC
|
|
||||||
ENDIF()
|
|
||||||
IF(POLICY CMP0072)
|
|
||||||
CMAKE_POLICY(SET CMP0072 NEW) # cmake >= 3.11.0 - prefer libOpenGL.so over legacy libGL.so
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
|
|
||||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
|
||||||
SET(CMAKE_INSTALL_PREFIX "/shd/CTC" CACHE STRING "Install path prefix, prepended onto install directories." FORCE)
|
|
||||||
ENDIF()
|
|
||||||
#
|
|
||||||
# # Setzen von CMAKE_BUILD_TYPE auf "Debug" falls nicht über Kommandozeile angegeben
|
|
||||||
#
|
|
||||||
IF(NOT DEFINED CMAKE_BUILD_TYPE)
|
|
||||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
|
||||||
ENDIF()
|
|
||||||
ADD_DEFINITIONS(-DEXPORT_BDV_TOPIC_AS_JSON)
|
|
||||||
SET(_ver "1.2.0")
|
|
||||||
IF(DEFINED LTS_VERSION_MAJOR AND DEFINED LTS_VERSION_MINOR AND DEFINED LTS_VERSION_PATCH)
|
|
||||||
SET(_ver "${LTS_VERSION_MAJOR}.${LTS_VERSION_MINOR}.${LTS_VERSION_PATCH}")
|
|
||||||
ENDIF()
|
|
||||||
PROJECT(LTS VERSION ${_ver})
|
|
||||||
MESSAGE(STATUS "LTS Version: ${LTS_VERSION_MAJOR}.${LTS_VERSION_MINOR}.${LTS_VERSION_PATCH}")
|
|
||||||
|
|
||||||
# Enable CTest integration for unit tests
|
|
||||||
include(CTest)
|
|
||||||
|
|
||||||
# Release scope: subdirectories are added unconditionally (no per-module migration builds)
|
|
||||||
function(NGL_ADD_SUBDIR_GUARDED subdir)
|
|
||||||
add_subdirectory(${subdir})
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
SET(LTS_VERSION_DATE "01.01.2018" CACHE STRING "The date when this software was compiled")
|
|
||||||
ADD_DEFINITIONS(-DLTS_VERSION_MAJOR=\"${LTS_VERSION_MAJOR}\")
|
|
||||||
ADD_DEFINITIONS(-DLTS_VERSION_MINOR=\"${LTS_VERSION_MINOR}\")
|
|
||||||
ADD_DEFINITIONS(-DLTS_VERSION_PATCH=\"${LTS_VERSION_PATCH}\")
|
|
||||||
ADD_DEFINITIONS(-DLTS_VERSION_DATE=\"${LTS_VERSION_DATE}\")
|
|
||||||
IF(JENKINS_BUILD_NUMBER)
|
|
||||||
ADD_DEFINITIONS(-DJENKINS_BUILD_NUMBER=\"${JENKINS_BUILD_NUMBER}\")
|
|
||||||
ELSE()
|
|
||||||
ADD_DEFINITIONS(-DJENKINS_BUILD_NUMBER=\"unknown\")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
ADD_DEFINITIONS(-DAPP6C)
|
|
||||||
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
|
|
||||||
# Resolve <DDS/...> and other framework includes to the real headers under
|
|
||||||
# Lts/ BEFORE the migration stub tree in include/. The stub tree shadows them
|
|
||||||
# otherwise and opens namespace DDSGeneric around framework includes, which
|
|
||||||
# pulls Qt/std definitions into that namespace and breaks every consumer.
|
|
||||||
# (The qt5 legacy has no include/ tree; Lts/ is the real include root.)
|
|
||||||
include_directories(BEFORE ${CMAKE_SOURCE_DIR})
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
|
||||||
# Include directory for generated export headers
|
|
||||||
include_directories(${CMAKE_BINARY_DIR})
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Z/src)
|
|
||||||
# Include directories for external dependencies and internal modules
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Z/src)
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Z/src/ngltools)
|
|
||||||
# Lts/Viewer is outside the release scope; only add the include paths when
|
|
||||||
# present to avoid -Wmissing-include-dirs warnings on validation-scope trees
|
|
||||||
if(EXISTS "${CMAKE_SOURCE_DIR}/Lts/Viewer/SituationMap/Symbology")
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Lts/Viewer/SituationMap/Symbology)
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Lts/Viewer/LtsDataView)
|
|
||||||
endif()
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Lts/Proxies/TrainingAreaBase)
|
|
||||||
# Release scope: include path for ProjectDataManagement stub headers
|
|
||||||
IF(RELEASE_BUILD)
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Lts/Services/ProjectDataManagement/stubs)
|
|
||||||
ENDIF()
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Lts/Common)
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Lts/Common/LtsUtils)
|
|
||||||
include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsCore)
|
|
||||||
# LtsUtilsSettings's generated ltsutilssettings_export.h is included by bare name from
|
|
||||||
# settings.h. Consumer targets that reach settings.h transitively (without linking
|
|
||||||
# LtsUtilsSettings themselves) cannot see it through the target's PUBLIC interface, so the
|
|
||||||
# directory holding the generated header has to be visible tree-wide. The directory contains
|
|
||||||
# only that generated header, so appending it cannot shadow an existing include.
|
|
||||||
include_directories(${CMAKE_BINARY_DIR}/Lts/Common/LtsUtils/LtsUtilsSettings)
|
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/Z/src/NGLLogger)
|
|
||||||
SET(CMAKE_CXX_STANDARD 17)
|
|
||||||
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
|
||||||
SET(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
|
||||||
# Qt6 Migration: Removed CMAKE_POSITION_INDEPENDENT_CODE - Qt6 handles PIC automatically
|
|
||||||
# and this setting conflicts with Qt6's reduce_relocations feature
|
|
||||||
# SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
|
|
||||||
IF(CMAKE_VERSION VERSION_GREATER 3.15.9)
|
|
||||||
OPTION(USE_UNITY_BUILDS "Use Unity builds to speed up compilation (cmake 3.16 or newer required!)" OFF)
|
|
||||||
IF (USE_UNITY_BUILDS)
|
|
||||||
SET(CMAKE_UNITY_BUILD ON)
|
|
||||||
SET(CMAKE_UNITY_BUILD_BATCH_SIZE 40)
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Add Lts/ include path globally for QosProfile and other Lts headers
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/Lts)
|
|
||||||
|
|
||||||
OPTION(BUILD_LTSWEBSOCKET "Build LtsWebSocket module (requires NGLLogger)" ON)
|
|
||||||
|
|
||||||
# Set CMAKE_MODULE_PATH early so FIND_PACKAGE can find our custom Find modules
|
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
|
||||||
INCLUDE(FindLibraryWithDebug)
|
|
||||||
|
|
||||||
ENABLE_TESTING()
|
|
||||||
INCLUDE(CTest)
|
|
||||||
CONFIGURE_FILE(CTestCustom.ctest ${CMAKE_BINARY_DIR}/CTestCustom.ctest COPYONLY)
|
|
||||||
CONFIGURE_FILE(lts-cc.conf ${CMAKE_BINARY_DIR}/lts-cc.conf.distrib COPYONLY)
|
|
||||||
|
|
||||||
# Add bundled GeographicLib cmake config to find modern targets (GeographicLib::GeographicLib_SHARED)
|
|
||||||
LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/include/GeographicLib/lib/cmake")
|
|
||||||
SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
|
||||||
IF(WIN32)
|
|
||||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
|
|
||||||
ELSE(WIN32)
|
|
||||||
SET(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Disallow in-source build
|
|
||||||
#
|
|
||||||
INCLUDE(MacroEnsureOutOfSourceBuild)
|
|
||||||
|
|
||||||
macro_ensure_out_of_source_build("In-Source build nicht erlaubt!")
|
|
||||||
|
|
||||||
#
|
|
||||||
# Qt ist wichtig - zuerst suchen
|
|
||||||
#
|
|
||||||
SET(CMAKE_AUTOMOC TRUE)
|
|
||||||
SET(CMAKE_AUTOUIC TRUE)
|
|
||||||
SET(QT_USE_IMPORTED_TARGETS TRUE)
|
|
||||||
|
|
||||||
# Check for OpenGL first (required by Qt6Gui)
|
|
||||||
find_package(OpenGL)
|
|
||||||
|
|
||||||
# Prefer Qt6, fallback to Qt5. Create Qt6::*-aliases when Qt6 is found so existing CMakeLists continue to work.
|
|
||||||
# Try to find Qt6 with GUI components first
|
|
||||||
set(QT6_GUI_AVAILABLE FALSE)
|
|
||||||
set(QT6_FOUND FALSE)
|
|
||||||
set(QT6_CORE5COMPAT_AVAILABLE FALSE)
|
|
||||||
|
|
||||||
# First check if Core5Compat is available
|
|
||||||
find_package(Qt6 6.2 COMPONENTS Core5Compat QUIET)
|
|
||||||
if(Qt6Core5Compat_FOUND)
|
|
||||||
set(QT6_CORE5COMPAT_AVAILABLE TRUE)
|
|
||||||
message(STATUS "Found Qt6Core5Compat")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Find Qt6 core components first (without OpenGL which may not be available)
|
|
||||||
# WebSockets is required by the migrated services (FileManagement's THP script
|
|
||||||
# server uses QWebSocketServer; LtsWebSocket/httq enable their real websocket
|
|
||||||
# paths via QT6_WEBSOCKETS_AVAILABLE when the module is found).
|
|
||||||
find_package(Qt6 6.2 COMPONENTS Concurrent Core LinguistTools Network
|
|
||||||
Multimedia Sql SerialPort Test Xml Positioning Svg WebSockets PrintSupport OpenGL QUIET)
|
|
||||||
|
|
||||||
if(Qt6_FOUND)
|
|
||||||
# Check if OpenGL was found (GUI support available)
|
|
||||||
if(OpenGL_FOUND)
|
|
||||||
set(QT6_GUI_AVAILABLE TRUE)
|
|
||||||
message(STATUS "Found Qt6 with GUI support (OpenGL): ${Qt6Core_VERSION}")
|
|
||||||
else()
|
|
||||||
# Skip GUI find_package - it fails without OpenGL. We'll create manual targets below.
|
|
||||||
set(QT6_GUI_AVAILABLE FALSE)
|
|
||||||
message(STATUS "Found Qt6 (GUI will be manually configured): ${Qt6Core_VERSION}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# If Qt6 not found yet, try with full component list including OpenGL
|
|
||||||
if(NOT Qt6_FOUND)
|
|
||||||
find_package(Qt6 6.2 COMPONENTS Concurrent Core LinguistTools Network OpenGL PrintSupport
|
|
||||||
Multimedia Sql Svg SerialPort Test UiTools WebSockets WebEngineCore WebEngineWidgets
|
|
||||||
Widgets Xml Positioning QUIET)
|
|
||||||
if(Qt6_FOUND AND OpenGL_FOUND)
|
|
||||||
set(QT6_GUI_AVAILABLE TRUE)
|
|
||||||
message(STATUS "Found Qt6 with GUI support (OpenGL): ${Qt6Core_VERSION}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT Qt6_FOUND)
|
|
||||||
# Final fallback - try to find Qt6 with minimum required components
|
|
||||||
find_package(Qt6 6.2 COMPONENTS Core REQUIRED)
|
|
||||||
message(STATUS "Found Qt6 (minimal): ${Qt6Core_VERSION}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Manual Qt6 configuration - create imported targets for available libraries
|
|
||||||
if(NOT TARGET Qt6::Core)
|
|
||||||
find_package(Qt6 6.2 COMPONENTS Core REQUIRED)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Create imported targets for all available Qt6 libraries
|
|
||||||
# Use Qt6 installation path from find_package or fall back to system paths
|
|
||||||
if(Qt6Core_DIR)
|
|
||||||
# <Qt6Core_DIR> is the cmake package dir: <prefix>/lib/cmake/Qt6Core in the
|
|
||||||
# standard Qt layout and <prefix>/<multiarch>/cmake/Qt6Core in the Debian/
|
|
||||||
# Ubuntu layout — so the library dir is two levels up in both. (Going three
|
|
||||||
# levels up and appending /lib only matches the standard layout; in the
|
|
||||||
# Debian validation container it resolved to /usr/lib/lib and every manual
|
|
||||||
# target below was silently skipped, breaking all targets linking
|
|
||||||
# Qt6::Sql / Qt6::Xml / Qt6::Test.)
|
|
||||||
get_filename_component(QT6_LIB_DIR "${Qt6Core_DIR}/../.." ABSOLUTE)
|
|
||||||
get_filename_component(QT6_ARCH_DIR "${QT6_LIB_DIR}" NAME)
|
|
||||||
# The standard layout keeps headers in <prefix>/include; Debian/Ubuntu keeps
|
|
||||||
# them in <prefix>/include/<multiarch>/qt6 — probe the multiarch form first.
|
|
||||||
if(EXISTS "${QT6_LIB_DIR}/../../include/${QT6_ARCH_DIR}/qt6")
|
|
||||||
get_filename_component(QT6_INC_DIR "${QT6_LIB_DIR}/../../include/${QT6_ARCH_DIR}/qt6" ABSOLUTE)
|
|
||||||
else()
|
|
||||||
get_filename_component(QT6_INC_DIR "${QT6_LIB_DIR}/../include" ABSOLUTE)
|
|
||||||
endif()
|
|
||||||
elseif(DEFINED ENV{QT_BASE_DIR} AND DEFINED ENV{QT_VERSION} AND DEFINED ENV{QT_ARCH_DIR})
|
|
||||||
set(QT6_LIB_DIR "$ENV{QT_BASE_DIR}/$ENV{QT_VERSION}/$ENV{QT_ARCH_DIR}/lib")
|
|
||||||
set(QT6_INC_DIR "$ENV{QT_BASE_DIR}/$ENV{QT_VERSION}/$ENV{QT_ARCH_DIR}/include")
|
|
||||||
else()
|
|
||||||
set(QT6_LIB_DIR "/usr/lib/x86_64-linux-gnu")
|
|
||||||
set(QT6_INC_DIR "/usr/include/x86_64-linux-gnu/qt6")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::DBus
|
|
||||||
if(NOT TARGET Qt6::DBus AND EXISTS "${QT6_LIB_DIR}/libQt6DBus.so.6")
|
|
||||||
add_library(Qt6::DBus SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::DBus PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6DBus.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtDBus;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Gui (needs OpenGL libs, X11, EGL)
|
|
||||||
if(NOT TARGET Qt6::Gui AND EXISTS "${QT6_LIB_DIR}/libQt6Gui.so.6")
|
|
||||||
add_library(Qt6::Gui SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Gui PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Gui.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtGui;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::DBus;${QT6_LIB_DIR}/libQt6OpenGL.so.6;${QT6_LIB_DIR}/libEGL.so.1;${QT6_LIB_DIR}/libGLX.so.0;${QT6_LIB_DIR}/libX11.so.6;${CMAKE_DL_LIBS};pthread"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set variable for legacy code that uses ${Qt6_Gui} — like Qt6_Widgets below,
|
|
||||||
# subdirectory CMakeLists contain `set(Qt6_Gui ${Qt6_Gui})` optional-guard
|
|
||||||
# no-ops that keep this root-scope value.
|
|
||||||
if(TARGET Qt6::Gui)
|
|
||||||
set(Qt6_Gui Qt6::Gui)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Widgets - create manual target (find_package fails without OpenGL)
|
|
||||||
if(EXISTS "${QT6_LIB_DIR}/libQt6Widgets.so.6")
|
|
||||||
if(NOT TARGET Qt6::Widgets)
|
|
||||||
add_library(Qt6::Widgets SHARED IMPORTED)
|
|
||||||
endif()
|
|
||||||
set_target_properties(Qt6::Widgets PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Widgets.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "/usr/include/x86_64-linux-gnu/qt6/QtWidgets;/usr/include/x86_64-linux-gnu/qt6"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui"
|
|
||||||
)
|
|
||||||
# Set variable for legacy code that uses ${Qt6_Widgets}
|
|
||||||
set(Qt6_Widgets Qt6::Widgets)
|
|
||||||
set(QT6_GUI_AVAILABLE TRUE)
|
|
||||||
message(STATUS "Manually configured Qt6 Widgets target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Sql - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::Sql AND EXISTS "${QT6_LIB_DIR}/libQt6Sql.so.6")
|
|
||||||
add_library(Qt6::Sql SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Sql PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Sql.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtSql;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 Sql target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Xml - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::Xml AND EXISTS "${QT6_LIB_DIR}/libQt6Xml.so.6")
|
|
||||||
add_library(Qt6::Xml SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Xml PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Xml.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtXml;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 Xml target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Network - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::Network AND EXISTS "${QT6_LIB_DIR}/libQt6Network.so.6")
|
|
||||||
add_library(Qt6::Network SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Network PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Network.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtNetwork;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 Network target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Test - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::Test AND EXISTS "${QT6_LIB_DIR}/libQt6Test.so.6")
|
|
||||||
add_library(Qt6::Test SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Test PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Test.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtTest;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 Test target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Multimedia - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::Multimedia AND EXISTS "${QT6_LIB_DIR}/libQt6Multimedia.so.6")
|
|
||||||
add_library(Qt6::Multimedia SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Multimedia PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Multimedia.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtMultimedia;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 Multimedia target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::Multimedia target if not available (needed by OscSystemGuiPlugin, etc.)
|
|
||||||
if(NOT TARGET Qt6::Multimedia)
|
|
||||||
add_library(Qt6::Multimedia INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::Multimedia PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_MULTIMEDIA"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::Multimedia (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::Svg - create manual target if not found. Also require the headers:
|
|
||||||
# the container can ship the runtime library (libqt6svg6 via Recommends)
|
|
||||||
# without qt6-svg-dev, and an imported target with a non-existent
|
|
||||||
# INTERFACE_INCLUDE_DIRECTORIES entry fails the CMake generate step for
|
|
||||||
# every Svg consumer. Without headers the stub below is used instead.
|
|
||||||
if(NOT TARGET Qt6::Svg AND EXISTS "${QT6_LIB_DIR}/libQt6Svg.so.6" AND EXISTS "${QT6_INC_DIR}/QtSvg")
|
|
||||||
add_library(Qt6::Svg SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::Svg PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6Svg.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtSvg;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 Svg target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::Svg target if not available (needed by various plugins)
|
|
||||||
if(NOT TARGET Qt6::Svg)
|
|
||||||
add_library(Qt6::Svg INTERFACE IMPORTED)
|
|
||||||
message(STATUS "Created stub target for Qt6::Svg (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::SerialPort - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::SerialPort AND EXISTS "${QT6_LIB_DIR}/libQt6SerialPort.so.6")
|
|
||||||
add_library(Qt6::SerialPort SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::SerialPort PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6SerialPort.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtSerialPort;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 SerialPort target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::SerialPort target if not available (needed by TrainingAreaBaseOC)
|
|
||||||
if(NOT TARGET Qt6::SerialPort)
|
|
||||||
add_library(Qt6::SerialPort INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::SerialPort PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_SERIALPORT"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::SerialPort (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::WebEngineCore target if not available (needed by thp_viewer)
|
|
||||||
if(NOT TARGET Qt6::WebEngineCore)
|
|
||||||
add_library(Qt6::WebEngineCore INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::WebEngineCore PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_WEBENGINE"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::WebEngineCore (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::WebEngineWidgets target if not available (needed by thp_viewer)
|
|
||||||
if(NOT TARGET Qt6::WebEngineWidgets)
|
|
||||||
add_library(Qt6::WebEngineWidgets INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::WebEngineWidgets PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_WEBENGINE"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::WebEngineWidgets (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::Core5Compat target if not available (needed by textEditorTest)
|
|
||||||
if(NOT TARGET Qt6::Core5Compat)
|
|
||||||
add_library(Qt6::Core5Compat INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::Core5Compat PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_CORE5COMPAT"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::Core5Compat (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::WebSockets - create manual target if not found (the container's Qt6
|
|
||||||
# discovery takes the minimal path, so find_package never creates the
|
|
||||||
# component targets). The migrated FileManagement service (THP script
|
|
||||||
# server) needs the real module.
|
|
||||||
if(NOT TARGET Qt6::WebSockets AND EXISTS "${QT6_LIB_DIR}/libQt6WebSockets.so.6")
|
|
||||||
add_library(Qt6::WebSockets SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::WebSockets PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6WebSockets.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtWebSockets;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Network"
|
|
||||||
)
|
|
||||||
set(QT6_WEBSOCKETS_REAL_FOUND TRUE)
|
|
||||||
message(STATUS "Manually configured Qt6 WebSockets target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::WebSockets target if not available (needed by LtsWebSocket, httq, etc.)
|
|
||||||
if(NOT TARGET Qt6::WebSockets)
|
|
||||||
add_library(Qt6::WebSockets INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::WebSockets PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_WEBSOCKETS"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::WebSockets (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::PrintSupport - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::PrintSupport AND EXISTS "${QT6_LIB_DIR}/libQt6PrintSupport.so.6")
|
|
||||||
add_library(Qt6::PrintSupport SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::PrintSupport PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6PrintSupport.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtPrintSupport;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui;Qt6::Widgets"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 PrintSupport target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::PrintSupport target if not available (needed by textEditorTest, thp_viewer)
|
|
||||||
if(NOT TARGET Qt6::PrintSupport)
|
|
||||||
add_library(Qt6::PrintSupport INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::PrintSupport PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_PRINTSUPPORT"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::PrintSupport (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Qt6::OpenGL - create manual target if not found
|
|
||||||
if(NOT TARGET Qt6::OpenGL AND EXISTS "${QT6_LIB_DIR}/libQt6OpenGL.so.6")
|
|
||||||
add_library(Qt6::OpenGL SHARED IMPORTED)
|
|
||||||
set_target_properties(Qt6::OpenGL PROPERTIES
|
|
||||||
IMPORTED_LOCATION "${QT6_LIB_DIR}/libQt6OpenGL.so.6"
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${QT6_INC_DIR}/QtOpenGL;${QT6_INC_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "Qt6::Core;Qt6::Gui"
|
|
||||||
)
|
|
||||||
message(STATUS "Manually configured Qt6 OpenGL target")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Stub Qt6::OpenGL target if not available (needed by PwsGuiPlugin)
|
|
||||||
if(NOT TARGET Qt6::OpenGL)
|
|
||||||
add_library(Qt6::OpenGL INTERFACE IMPORTED)
|
|
||||||
set_target_properties(Qt6::OpenGL PROPERTIES
|
|
||||||
INTERFACE_COMPILE_DEFINITIONS "QT_NO_OPENGL"
|
|
||||||
)
|
|
||||||
message(STATUS "Created stub target for Qt6::OpenGL (library not available)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set variable for legacy code that uses ${Qt6_WebSockets} — subdirectory
|
|
||||||
# CMakeLists contain `set(Qt6_WebSockets ${Qt6_WebSockets})` optional-guard
|
|
||||||
# no-ops that keep this root-scope value.
|
|
||||||
if(TARGET Qt6::WebSockets)
|
|
||||||
set(Qt6_WebSockets Qt6::WebSockets)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# The real Qt6 WebSockets module is available (either via find_package or the
|
|
||||||
# manual import above): enable the real websocket code paths in httq,
|
|
||||||
# LtsWebSocket and the migrated services (they check this macro; without it
|
|
||||||
# they fall back to websocket-less operation).
|
|
||||||
if(Qt6WebSockets_FOUND OR QT6_WEBSOCKETS_REAL_FOUND)
|
|
||||||
add_compile_definitions(QT6_WEBSOCKETS_AVAILABLE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
MESSAGE(STATUS "Qt version is ${Qt6Core_VERSION}, GUI available: ${QT6_GUI_AVAILABLE}")
|
|
||||||
|
|
||||||
#
|
|
||||||
ADD_DEFINITIONS(-DQT_USE_QSTRINGBUILDER)
|
|
||||||
ADD_DEFINITIONS(-DQT_NO_CAST_TO_ASCII)
|
|
||||||
ADD_DEFINITIONS(-DQT_NO_CAST_FROM_ASCII)
|
|
||||||
ADD_DEFINITIONS(-DQT_NO_URL_CAST_FROM_STRING)
|
|
||||||
ADD_DEFINITIONS(-DQT_DEPRECATED_WARNINGS)
|
|
||||||
ADD_DEFINITIONS(-DQT_NO_CAST_FROM_BYTEARRAY)
|
|
||||||
#ADD_DEFINITIONS(-DQT_NO_DEPRECATED)
|
|
||||||
ADD_DEFINITIONS(-DQT_DISABLE_DEPRECATED_BEFORE=0x050900)
|
|
||||||
ADD_DEFINITIONS(-DQT_NO_FOREACH)
|
|
||||||
IF(NOT WIN32)
|
|
||||||
ADD_DEFINITIONS(-DQT_STRICT_ITERATORS)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Ein paar NGL-spezifische Macros
|
|
||||||
#
|
|
||||||
INCLUDE(NGLMacros)
|
|
||||||
|
|
||||||
#
|
|
||||||
# Projektspezifische Einstellungen?
|
|
||||||
#
|
|
||||||
NGL_INSTALL(SV AAR WS FILES lts-cc.conf DESTINATION . RENAME lts-cc.conf.distrib)
|
|
||||||
|
|
||||||
OPTION(GUEZ_MODE "Build for GUEZ " ON)
|
|
||||||
IF(GUEZ_MODE)
|
|
||||||
ADD_DEFINITIONS(-DGUEZ_MODE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
#
|
|
||||||
# Doxygen
|
|
||||||
#
|
|
||||||
INCLUDE(DoxygenMacros)
|
|
||||||
IF(NOT DOXYGEN_OUT_DIR)
|
|
||||||
SET(DOXYGEN_OUT_DIR ${CMAKE_BINARY_DIR}/doxygen)
|
|
||||||
ENDIF()
|
|
||||||
ADD_DOXYGEN_TARGET(TDS ${CMAKE_SOURCE_DIR}/doxygen/Doxyfile.in ${CMAKE_BINARY_DIR}/Doxyfile
|
|
||||||
${CMAKE_SOURCE_DIR}/doxygen/rheinmetall_defence_logo.jpg
|
|
||||||
${DOXYGEN_OUT_DIR})
|
|
||||||
|
|
||||||
IF(NOT DOXYGEN_OUT_DIR_2025)
|
|
||||||
SET(DOXYGEN_OUT_DIR_2025 ${CMAKE_BINARY_DIR}/doxygen2025)
|
|
||||||
ENDIF()
|
|
||||||
ADD_DOXYGEN_TARGET(TDS2025 ${CMAKE_SOURCE_DIR}/doxygen/Doxyfile2025.in ${CMAKE_BINARY_DIR}/Doxyfile
|
|
||||||
${CMAKE_SOURCE_DIR}/doxygen/rheinmetall_defence_logo.jpg
|
|
||||||
${DOXYGEN_OUT_DIR_2025})
|
|
||||||
|
|
||||||
#
|
|
||||||
# Compilerflags
|
|
||||||
#
|
|
||||||
IF(WIN32)
|
|
||||||
ADD_DEFINITIONS(-DWIN32 -D_USE_MATH_DEFINES -D_WIN32_WINNT=0x0501 -DUNICODE)
|
|
||||||
ELSE()
|
|
||||||
ADD_DEFINITIONS(-D_LINUX)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(MSVC)
|
|
||||||
# C4250: 'class1' : inherits 'class2::member' via dominance
|
|
||||||
# C4251: 'identifier' : class 'type' needs to have dll-interface to be used by clients of class 'type2'
|
|
||||||
# C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
|
|
||||||
# C4496: 'function': was declared deprecated
|
|
||||||
# C4267: 'var' : conversion from 'size_t' to 'type', possible loss of data
|
|
||||||
ADD_DEFINITIONS(-wd4250
|
|
||||||
-wd4251
|
|
||||||
-wd4290
|
|
||||||
-wd4496
|
|
||||||
-wd4267
|
|
||||||
-D_CRT_SECURE_NO_DEPRECATE
|
|
||||||
-D_CRT_NONSTDC_NO_DEPRECATE
|
|
||||||
-D_SCL_SECURE_NO_WARNINGS
|
|
||||||
-D_WINSOCK_DEPRECATED_NO_WARNINGS
|
|
||||||
/bigobj
|
|
||||||
)
|
|
||||||
# komplette Programmoptimierung
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
|
||||||
# .pdb - Datei nicht gefunden
|
|
||||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /IGNORE:4099")
|
|
||||||
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /IGNORE:4099")
|
|
||||||
# min() und max() nicht als Macros
|
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
|
||||||
SET(CMAKE_MSVCIDE_RUN_PATH "" CACHE PATH "Run path to use when starting programs from MSVC")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(UNIX)
|
|
||||||
# Alle Warnungen aktivieren
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wmissing-include-dirs")
|
|
||||||
# disable
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-overloaded-virtual")
|
|
||||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
|
||||||
IF(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8.0)
|
|
||||||
MESSAGE(FATAL_ERROR "gcc 4.8 or higher is required to build TDS: ${CMAKE_CXX_COMPILER_VERSION}")
|
|
||||||
ENDIF()
|
|
||||||
IF(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.9.99)
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-strict-aliasing")
|
|
||||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-attribute=const")
|
|
||||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-final-types")
|
|
||||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-final-methods")
|
|
||||||
# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsuggest-override")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
OPTION(USE_IPO "Use interprocedural optimizations (cmake 3.9 or higher required)" OFF)
|
|
||||||
IF (USE_IPO AND CMAKE_VERSION VERSION_GREATER 3.8.9)
|
|
||||||
INCLUDE(CheckIPOSupported)
|
|
||||||
check_ipo_supported(RESULT result OUTPUT output)
|
|
||||||
IF(result)
|
|
||||||
SET(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(WARNING "IPO is not supported: ${output}")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
OPTION(USE_ASAN "Use Address Sanitizer (current Clang only)" OFF)
|
|
||||||
IF (USE_ASAN)
|
|
||||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|
||||||
MESSAGE(STATUS "enable Address Sanitizer with Clang (is: ${CMAKE_CXX_COMPILER_ID})")
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1")
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g -O1")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "Address Sanitizer only supported with Clang (is: ${CMAKE_CXX_COMPILER_ID})")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF(USE_ASAN)
|
|
||||||
|
|
||||||
OPTION(USE_UBSAN "Use UndefinedBehavior Sanitizer (current Clang only)" OFF)
|
|
||||||
IF (USE_UBSAN)
|
|
||||||
IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined")
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "UndefinedBehavior only supported with Clang (is: ${CMAKE_CXX_COMPILER_ID})")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF(USE_UBSAN)
|
|
||||||
|
|
||||||
OPTION(BUILD_RPM "Build a RPM - install script in scripts subdir" OFF)
|
|
||||||
|
|
||||||
# Build component options for NGL_ADD_LIBRARY
|
|
||||||
OPTION(BUILD_ALL "Build all components" ON)
|
|
||||||
OPTION(BUILD_SV "Build SV component" ON)
|
|
||||||
OPTION(BUILD_WS "Build WS component" ON)
|
|
||||||
OPTION(BUILD_AAR "Build AAR component" ON)
|
|
||||||
OPTION(BUILD_TOOLSWS "Build TOOLSWS component" ON)
|
|
||||||
OPTION(BUILD_TOOLSSV "Build TOOLSSV component" ON)
|
|
||||||
OPTION(BUILD_HLA "Build HLA component" ON)
|
|
||||||
|
|
||||||
# If BUILD_ALL is ON, enable all individual component flags
|
|
||||||
IF(BUILD_ALL)
|
|
||||||
SET(BUILD_SV ON CACHE BOOL "Build SV component" FORCE)
|
|
||||||
SET(BUILD_WS ON CACHE BOOL "Build WS component" FORCE)
|
|
||||||
SET(BUILD_AAR ON CACHE BOOL "Build AAR component" FORCE)
|
|
||||||
SET(BUILD_TOOLSWS ON CACHE BOOL "Build TOOLSWS component" FORCE)
|
|
||||||
SET(BUILD_TOOLSSV ON CACHE BOOL "Build TOOLSSV component" FORCE)
|
|
||||||
SET(BUILD_HLA ON CACHE BOOL "Build HLA component" FORCE)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(BUILD_RPM)
|
|
||||||
ADD_SUBDIRECTORY(scripts)
|
|
||||||
ELSE()
|
|
||||||
ADD_DEFINITIONS(-DLTS_DEBUG)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (NOT DEFINED _pname)
|
|
||||||
IF(GUEZ_MODE)
|
|
||||||
SET (_pname "guez")
|
|
||||||
ADD_DEFINITIONS(-DPROJECTBUILD="guez")
|
|
||||||
MESSAGE(STATUS "NO ProjectName givin! BUT GUEZ_MODE set PROJECTBUILD to guez")
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(WARNING "NO ProjectName givin! Can't install coresponding lts-cc.conf! and PROJECTBUILD is empty")
|
|
||||||
ADD_DEFINITIONS(-DPROJECTBUILD="")
|
|
||||||
ENDIF()
|
|
||||||
ELSE()
|
|
||||||
MESSAGE(STATUS "ProjectName givin! PROJECTBUILD is ${_pname} ")
|
|
||||||
ADD_DEFINITIONS(-DPROJECTBUILD=\"${_pname}\")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
|
|
||||||
# Release scope: always build only TetraIF, Z/src, and Lts/Common
|
|
||||||
# (TrainingAreaBase is included via Lts/Proxies when Lts is processed)
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(TetraIF)
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(Z/src)
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(Lts)
|
|
||||||
|
|
||||||
# at last, to make sure we get all targets in NGL_TS_TARGETS property
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(translations)
|
|
||||||
#-----------------------------------------------------------------------------------------------------
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
# Minimal CTestCustom.ctest placeholder
|
|
||||||
# Created to satisfy top-level CMake configure step
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
# Prebuilt build image for the release validation-scope branch
|
|
||||||
# (Ubuntu 26.04 + Qt6 + all dependencies for the legatus release build).
|
|
||||||
#
|
|
||||||
# Built by new_docker_build.sh --build-prebuilt-image, which passes the
|
|
||||||
# package list and Qt settings as build args (see build_prebuilt_image()).
|
|
||||||
|
|
||||||
FROM ubuntu:26.04
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
ARG APT_PACKAGES
|
|
||||||
ARG QT_VERSION=6.10.2
|
|
||||||
ARG QT_ARCH=linux_gcc_64
|
|
||||||
ARG QT_BASE_DIR=/opt/Qt
|
|
||||||
|
|
||||||
RUN apt-get update -qq && \
|
|
||||||
apt-get install -y -qq \
|
|
||||||
${APT_PACKAGES} \
|
|
||||||
libqt6svg6-dev \
|
|
||||||
libgtest-dev \
|
|
||||||
libgmock-dev \
|
|
||||||
python3-pip && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Install Qt6 packages via aqtinstall
|
|
||||||
RUN pip3 install --break-system-packages --quiet aqtinstall && \
|
|
||||||
aqt install-qt linux desktop ${QT_VERSION} ${QT_ARCH} \
|
|
||||||
-m qtmultimedia qtserialport qtimageformats qtwebsockets qtwebengine \
|
|
||||||
qtpdf qtwebview qt5compat qtwebchannel qtpositioning qtlocation qtsensors \
|
|
||||||
--outputdir ${QT_BASE_DIR} && \
|
|
||||||
rm -rf /root/.cache/Aqt
|
|
||||||
|
|
||||||
# Install KDReports from source (apt package not available in Ubuntu 22.04/26.04)
|
|
||||||
# Try apt install first (will fail), then build from KDAB GitHub mirror
|
|
||||||
RUN apt-get install -y -qq libkdreports-dev 2>/dev/null || \
|
|
||||||
(git clone --depth 1 https://github.com/KDAB/KDReports.git /tmp/KDReports && \
|
|
||||||
cd /tmp/KDReports && \
|
|
||||||
mkdir build && cd build && \
|
|
||||||
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_PREFIX_PATH=${QT_BASE_DIR} .. && \
|
|
||||||
make -j$(nproc) && \
|
|
||||||
make install && \
|
|
||||||
cd / && rm -rf /tmp/KDReports)
|
|
||||||
|
|
||||||
# Legacy sources include <KDReports/...>
|
|
||||||
RUN ln -sfn KDReports-qt6 /usr/local/include/KDReports
|
|
||||||
|
|
||||||
CMD ["/bin/bash"]
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(LtsPlaceholder)
|
|
||||||
SET(DOXYGEN_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doxygen_Lts)
|
|
||||||
if (EXISTS "${CMAKE_SOURCE_DIR}/doxygen/DoxyfileLts.in")
|
|
||||||
ADD_DOXYGEN_TARGET(Lts ${CMAKE_SOURCE_DIR}/doxygen/DoxyfileLts.in ${CMAKE_BINARY_DIR}/DoxyfileLts
|
|
||||||
${CMAKE_SOURCE_DIR}/doxygen/rheinmetall_defence_logo.jpg
|
|
||||||
${DOXYGEN_OUT_DIR})
|
|
||||||
else()
|
|
||||||
message(WARNING "Doxygen config ${CMAKE_SOURCE_DIR}/doxygen/DoxyfileLts.in not found; skipping ADD_DOXYGEN_TARGET(Lts)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Release scope: only build Lts/Common and Lts/Proxies/TrainingAreaBase (tabTelegrams library)
|
|
||||||
# Excludes: Tools, Application, DDS, Services, most of Proxies, Plugins, Viewer, Projects
|
|
||||||
message(STATUS "Building Lts/Common and Lts/Proxies/TrainingAreaBase")
|
|
||||||
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()
|
|
||||||
|
|
||||||
# Export headers included by bare name from module sources (release scope)
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/NGLLogger/)
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../include/LtsUtilsGuiDds/)
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
# 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
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(CommonUnitTestsPlaceholder)
|
|
||||||
|
|
||||||
include(FetchContent)
|
|
||||||
|
|
||||||
option(BUILD_SMOKE_TESTS "Build QtTest smoke tests" OFF)
|
|
||||||
option(BUILD_GTEST_SMOKE "Build GTest smoke tests" OFF)
|
|
||||||
|
|
||||||
add_subdirectory(mocks)
|
|
||||||
|
|
||||||
if(BUILD_SMOKE_TESTS)
|
|
||||||
if(NOT TARGET Qt6::Test)
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Test)
|
|
||||||
endif()
|
|
||||||
add_executable(coordTransTests_smoke coordTransTests_smoke.cpp)
|
|
||||||
target_link_libraries(coordTransTests_smoke PRIVATE Qt6::Test MockCoordTrans::MockCoordTrans)
|
|
||||||
add_test(NAME coordTransTests_smoke COMMAND coordTransTests_smoke)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_GTEST_SMOKE)
|
|
||||||
find_package(GTest QUIET)
|
|
||||||
if(NOT GTest_FOUND)
|
|
||||||
FetchContent_Declare(
|
|
||||||
googletest
|
|
||||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
|
||||||
GIT_TAG release-1.12.1
|
|
||||||
)
|
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
||||||
FetchContent_MakeAvailable(googletest)
|
|
||||||
endif()
|
|
||||||
add_executable(coordTransTests_gtest coordTransTests_gtest.cpp)
|
|
||||||
target_link_libraries(coordTransTests_gtest PRIVATE GTest::gtest_main MockCoordTrans::MockCoordTrans)
|
|
||||||
add_test(NAME coordTransTests_gtest COMMAND coordTransTests_gtest)
|
|
||||||
endif()
|
|
||||||
-13
@@ -1,13 +0,0 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(CoordTransSmokeTest, StubTest)
|
|
||||||
{
|
|
||||||
EXPECT_TRUE(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
|
|
||||||
#include <QTest>
|
|
||||||
|
|
||||||
class CoordTransSmokeTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void stubTest() { QVERIFY(true); }
|
|
||||||
};
|
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(CoordTransSmokeTest)
|
|
||||||
-5
@@ -1,5 +0,0 @@
|
|||||||
add_library(MockCoordTrans STATIC MockCoordTrans.h)
|
|
||||||
target_include_directories(MockCoordTrans PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
# Export header-only semantics by providing an interface target
|
|
||||||
add_library(MockCoordTrans::MockCoordTrans ALIAS MockCoordTrans)
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
|
|
||||||
#ifndef MOCK_COORD_TRANS_H
|
|
||||||
#define MOCK_COORD_TRANS_H
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QPointF>
|
|
||||||
|
|
||||||
// Minimal stub to satisfy linker requirements
|
|
||||||
namespace LtsCoordTrans
|
|
||||||
{
|
|
||||||
// Placeholder types
|
|
||||||
struct UtmCoordinate
|
|
||||||
{
|
|
||||||
static UtmCoordinate fromMgrs(const QString &) { return UtmCoordinate(); }
|
|
||||||
QPointF geographic() const { return QPointF(); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MOCK_COORD_TRANS_H
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
# Created by Mike Wille, SLSE, 2016-10-24
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
# LtsAppDescriptor (lib)
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
SET(LtsAppDescriptor_SRCS
|
|
||||||
lts_app_descriptor.cpp
|
|
||||||
lts_app_descriptor.h
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(WS LtsAppDescriptor SHARED ${LtsAppDescriptor_SRCS})
|
|
||||||
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsAppDescriptor
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptor
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_INSTALL_TARGET(LtsAppDescriptor)
|
|
||||||
|
|
||||||
# LtsAppDescriptorChecker
|
|
||||||
SET(LtsAppDescriptorChecker_SRCS
|
|
||||||
checker/main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_ADD_EXECUTABLE(WS LtsAppDescriptorChecker ${LtsAppDescriptorChecker_SRCS})
|
|
||||||
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptorChecker
|
|
||||||
PRIVATE
|
|
||||||
LtsAppDescriptor
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
)
|
|
||||||
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
#NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptorEditor
|
|
||||||
# PUBLIC
|
|
||||||
# Qt6::Core
|
|
||||||
# ${Qt6_Widgets}
|
|
||||||
# LtsAppDescriptor
|
|
||||||
#)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
#NGL_INSTALL_TARGET(LtsAppDescriptorEditor) #not visible for end-user
|
|
||||||
|
|
||||||
## Executable:
|
|
||||||
#NGL_ADD_EXECUTABLE(WS NO_TRANSLATION LtsAppDescriptorEditorApp main.cpp)
|
|
||||||
#NGL_TARGET_LINK_LIBRARIES(LtsAppDescriptorEditorApp LtsAppDescriptorEditor)
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QDirIterator>
|
|
||||||
#include <QtCore/QFile>
|
|
||||||
#include <QFileInfoList>
|
|
||||||
#include <QtCore/QRegularExpression>
|
|
||||||
#include <QtCore/QRegularExpressionMatch>
|
|
||||||
#include <QtCore/QTextStream>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QCoreApplication a(argc, argv);
|
|
||||||
|
|
||||||
const QStringList args(a.arguments());
|
|
||||||
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
QString line(ts.readLine().trimmed().simplified());
|
|
||||||
static QString iidIdentifier(QStringLiteral("Q_PLUGIN_METADATA"));
|
|
||||||
|
|
||||||
if (line.contains(iidIdentifier))
|
|
||||||
{
|
|
||||||
QRegularExpression re(QStringLiteral("(?<=gui:3:).*(?=\"\\))"));
|
|
||||||
QRegularExpressionMatch match = re.match(line);
|
|
||||||
if (match.hasMatch())
|
|
||||||
{
|
|
||||||
QString matched = match.captured(0);
|
|
||||||
|
|
||||||
guiPluginIIDs += matched;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = true;
|
|
||||||
|
|
||||||
for (const LtsAppDescriptor::AppDescription &appdesc : std::as_const(adv))
|
|
||||||
{
|
|
||||||
for (const LtsAppDescriptor::PluginInfo &pi : std::as_const(appdesc.pluginInfos))
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return !ok;
|
|
||||||
}
|
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_app_descriptor.h"
|
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QJsonArray>
|
|
||||||
#include <QtCore/QJsonDocument>
|
|
||||||
#include <QtCore/QJsonObject>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QtCore/QJsonValue>
|
|
||||||
|
|
||||||
namespace LtsAppDescriptor
|
|
||||||
{
|
|
||||||
static void addOptionToPlugin(PluginInfo &pluginInfo, const PluginInfo::Flag &flag)
|
|
||||||
{
|
|
||||||
pluginInfo.flags |= flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void addOptionToPlugin(QVector<PluginInfo> &pluginInfos, const PluginInfo::Flag &flag, const QString &pluginName)
|
|
||||||
{
|
|
||||||
for (PluginInfo &pi : pluginInfos)
|
|
||||||
{
|
|
||||||
if (pi.iid == pluginName)
|
|
||||||
{
|
|
||||||
addOptionToPlugin(pi, flag);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginInfo pi;
|
|
||||||
pi.iid = pluginName;
|
|
||||||
pi.type = PluginInfo::PluginType::GUI;
|
|
||||||
addOptionToPlugin(pi, flag);
|
|
||||||
pluginInfos.append(pi);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool addOptionsToPlugin(AppDescription &appDesc,
|
|
||||||
const QString &optionIdentifier,
|
|
||||||
const QStringList &ignoredPlugins,
|
|
||||||
const QJsonObject &optionsObject,
|
|
||||||
const PluginInfo::Flag flag,
|
|
||||||
QStringList &lastErrors,
|
|
||||||
bool atLeastOnePluginNeeded)
|
|
||||||
{
|
|
||||||
bool hasPlugins = false;
|
|
||||||
auto optionsObjectIt = optionsObject.constFind(optionIdentifier);
|
|
||||||
if (optionsObjectIt != optionsObject.constEnd())
|
|
||||||
{
|
|
||||||
const QJsonArray plugins((*optionsObjectIt).toObject()[QStringLiteral("Plugins")].toArray());
|
|
||||||
|
|
||||||
for (const auto &pluginElem : plugins)
|
|
||||||
{
|
|
||||||
const QString pluginName = pluginElem.toString();
|
|
||||||
if (!ignoredPlugins.contains(pluginName))
|
|
||||||
{
|
|
||||||
addOptionToPlugin(appDesc.pluginInfos, flag, pluginName);
|
|
||||||
hasPlugins = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (atLeastOnePluginNeeded && !hasPlugins)
|
|
||||||
{
|
|
||||||
lastErrors.append(QCoreApplication::tr("No plugins specified for '%1' option for app '%2'").arg(optionIdentifier, appDesc.appName));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
App LtsAppDescriptor::appFromInteger(int i)
|
|
||||||
{
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case int(App::Login):
|
|
||||||
case int(App::Situation):
|
|
||||||
case int(App::ResourceManager):
|
|
||||||
case int(App::PlanEditor):
|
|
||||||
case int(App::BuildingViewer):
|
|
||||||
case int(App::OC):
|
|
||||||
case int(App::OrgChart):
|
|
||||||
case int(App::Scripts):
|
|
||||||
|
|
||||||
case int(App::Snapshot):
|
|
||||||
case int(App::SystemMonitor):
|
|
||||||
case int(App::Timeline):
|
|
||||||
case int(App::SymbolEditor):
|
|
||||||
case int(App::ScriptEditorEssentialsView):
|
|
||||||
case int(App::BaseDownloader):
|
|
||||||
case int(App::OnlineHelp):
|
|
||||||
case int(App::ThpSituationReplay):
|
|
||||||
case int(App::SituationTablet):
|
|
||||||
case int(App::SilhouetteEditor):
|
|
||||||
case int(App::Shootback):
|
|
||||||
case int(App::SAAs):
|
|
||||||
return static_cast<App>(i);
|
|
||||||
}
|
|
||||||
Q_ASSERT_X(false, "LtsAppDescriptor::appFromInteger", qPrintable(QStringLiteral("Unknown app id: %1").arg(i)));
|
|
||||||
return App::Login;
|
|
||||||
}
|
|
||||||
|
|
||||||
AppDescriptionVector LtsAppDescriptor::getAppDescriptionVector(const QByteArray &jsonDocument,
|
|
||||||
QStringList &lastErrors,
|
|
||||||
const QStringList &ignoredPlugins,
|
|
||||||
QString &loginPluginIid)
|
|
||||||
{
|
|
||||||
|
|
||||||
AppDescriptionVector appDescriptions;
|
|
||||||
|
|
||||||
QJsonParseError parseError;
|
|
||||||
QJsonDocument appsDoc(QJsonDocument::fromJson(jsonDocument, &parseError));
|
|
||||||
|
|
||||||
if (parseError.error != QJsonParseError::NoError)
|
|
||||||
{
|
|
||||||
|
|
||||||
int row = 0;
|
|
||||||
int column = 0;
|
|
||||||
QChar x = QLatin1Char('\n');
|
|
||||||
|
|
||||||
for (int i = 0; i < jsonDocument.size(); i++)
|
|
||||||
{
|
|
||||||
if (i == parseError.offset)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (QChar::fromLatin1(jsonDocument[i]) == x)
|
|
||||||
{
|
|
||||||
row++;
|
|
||||||
column = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
column++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastErrors.append(QCoreApplication::tr("JSON: %1<br>Row: %2, Column: %3").arg(parseError.errorString()).arg(row + 1).arg(column + 1));
|
|
||||||
return appDescriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonObject root(appsDoc.object());
|
|
||||||
|
|
||||||
loginPluginIid = root[QStringLiteral("LoginPlugin")].toString();
|
|
||||||
|
|
||||||
const QJsonArray appArray(root[QStringLiteral("Apps")].toArray());
|
|
||||||
if (appArray.isEmpty())
|
|
||||||
{
|
|
||||||
lastErrors.append(QCoreApplication::tr("Invalid json: Could not find 'Apps' array"));
|
|
||||||
return appDescriptions;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &appElem : appArray)
|
|
||||||
{
|
|
||||||
AppDescription appDesc;
|
|
||||||
const QJsonObject appObject = appElem.toObject();
|
|
||||||
|
|
||||||
appDesc.id = appFromInteger(appObject.value(QStringLiteral("Id")).toInt(-1));
|
|
||||||
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': 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"));
|
|
||||||
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());
|
|
||||||
for (const QJsonValue &value : array)
|
|
||||||
appDesc.requiredAcls.append(value.toInt());
|
|
||||||
|
|
||||||
const QJsonObject optionsObject(appObject.value(QStringLiteral("Options")).toObject());
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsAppDescriptor
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* App Descriptor - Class to modify App Descriptor JSON Documents
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*
|
|
||||||
* Created by Mike Wille, SLSE, 2016-10-24
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QVector>
|
|
||||||
#include <QStringList>
|
|
||||||
|
|
||||||
#ifndef LTSAPPDESCRIPTOR_EXPORT
|
|
||||||
#ifdef BUILD_STATIC_LIBRARIES
|
|
||||||
#define LTSAPPDESCRIPTOR_EXPORT
|
|
||||||
#else
|
|
||||||
#if defined(MAKE_LTSAPPDESCRIPTOR_LIB)
|
|
||||||
#define LTSAPPDESCRIPTOR_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
#define LTSAPPDESCRIPTOR_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace LtsAppDescriptor
|
|
||||||
{
|
|
||||||
|
|
||||||
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,
|
|
||||||
DATA,
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AppDescription
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
namespace LtsAppDescriptor // TODO: make qobject class singleton - for tr
|
|
||||||
{
|
|
||||||
LTSAPPDESCRIPTOR_EXPORT App appFromInteger(int i);
|
|
||||||
LTSAPPDESCRIPTOR_EXPORT AppDescriptionVector getAppDescriptionVector(const QByteArray &jsonDocument,
|
|
||||||
QStringList &lastErrors,
|
|
||||||
const QStringList &ignoredPlugins,
|
|
||||||
QString &loginPluginIid);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsAppDescriptor
|
|
||||||
-532
@@ -1,532 +0,0 @@
|
|||||||
#include "lts_app_descriptor_editor.h"
|
|
||||||
|
|
||||||
#include "ui_lts_app_descriptor_editor.h"
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
#include <QtCore/QFile>
|
|
||||||
#include <QtWidgets/QFileDialog>
|
|
||||||
#include <QtCore/QJsonDocument>
|
|
||||||
#include <QtWidgets/QMessageBox>
|
|
||||||
#include <QStringListModel>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QtWidgets/QListView>
|
|
||||||
#include <QtWidgets/QLineEdit>
|
|
||||||
#include <QtWidgets/QPushButton>
|
|
||||||
|
|
||||||
LtsAppDescriptorEditor::LtsAppDescriptorEditor(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, m_ui(new Ui_LtsAppDescriptionEditor)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
m_vector = LtsAppDescriptor::AppDescriptionVector();
|
|
||||||
m_appIndex = QModelIndex();
|
|
||||||
m_pluginIndex = QModelIndex();
|
|
||||||
m_fileName = QString();
|
|
||||||
m_changed = false;
|
|
||||||
|
|
||||||
connect(m_ui->lvApps, &QListView::clicked, this, &LtsAppDescriptorEditor::onAppsClicked);
|
|
||||||
connect(m_ui->lvPlugins, &QListView::clicked, this, &LtsAppDescriptorEditor::onPluginsClicked);
|
|
||||||
connect(m_ui->lePluginType, &QLineEdit::editingFinished, this, &LtsAppDescriptorEditor::pluginTypeChanged);
|
|
||||||
connect(m_ui->pbAddApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onAppAddClicked);
|
|
||||||
connect(m_ui->pbAddPlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onPluginAddClicked);
|
|
||||||
connect(m_ui->pbDeleteApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onAppDeleteClicked);
|
|
||||||
connect(m_ui->pbDeletePlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onPluginDeletedClicked);
|
|
||||||
connect(m_ui->pbUpdate, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onUpdateClicked);
|
|
||||||
connect(m_ui->pbNewPlugin, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onNewpluginClicked);
|
|
||||||
connect(m_ui->pbNewApp, &QPushButton::pressed, this, &LtsAppDescriptorEditor::onNewAppClicked);
|
|
||||||
connect(m_ui->lePluginName, &QLineEdit::textChanged, this, &LtsAppDescriptorEditor::enableNewPlugin);
|
|
||||||
connect(m_ui->lePluginType, &QLineEdit::textChanged, this, &LtsAppDescriptorEditor::enableNewPlugin);
|
|
||||||
|
|
||||||
m_ui->gbPlugins->setEnabled(false);
|
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
|
||||||
m_ui->pbDeleteApp->setEnabled(false);
|
|
||||||
m_ui->pbAddPlugin->setEnabled(false);
|
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
|
||||||
m_ui->pbNewApp->setEnabled(false);
|
|
||||||
QTimer::singleShot(0, this, &LtsAppDescriptorEditor::getAppDescriptionVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptorEditor::~LtsAppDescriptorEditor()
|
|
||||||
{
|
|
||||||
checkSave();
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::getAppDescriptionVector()
|
|
||||||
{
|
|
||||||
m_fileName =
|
|
||||||
QFileDialog::getOpenFileName(this, tr("Open JSON"), QLatin1Literal("/shd/CTC/TOOLS/TDS/TDS-source/Lts/Projects/Legatus/resources/"), tr("JSON File (*.json)"));
|
|
||||||
if (m_fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QFile file;
|
|
||||||
file.setFileName(m_fileName);
|
|
||||||
file.open(QIODevice::ReadOnly | QIODevice::Text);
|
|
||||||
QString val(QString::fromUtf8(file.readAll()));
|
|
||||||
file.close();
|
|
||||||
|
|
||||||
QStringList errors;
|
|
||||||
m_vector = LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(val.toUtf8(), errors);
|
|
||||||
|
|
||||||
updateAppModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onAppsClicked(const QModelIndex &index)
|
|
||||||
{
|
|
||||||
m_ui->gbPlugins->setEnabled(true);
|
|
||||||
m_ui->pbDeleteApp->setEnabled(true);
|
|
||||||
m_ui->pbAddPlugin->setEnabled(true);
|
|
||||||
m_ui->pbNewApp->setEnabled(true);
|
|
||||||
m_appIndex = index;
|
|
||||||
|
|
||||||
QStringList pluginList;
|
|
||||||
Q_FOREACH (const LtsAppDescriptor::PluginInfo &reqPlugin, m_vector.at(m_appIndex.row()).requiredPlugins)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
if (m_ui->lePluginType->text().isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
|
||||||
{
|
|
||||||
m_ui->chbActions->setEnabled(true);
|
|
||||||
m_ui->chbMain->setEnabled(true);
|
|
||||||
m_ui->chbPayload->setEnabled(true);
|
|
||||||
}
|
|
||||||
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Information, tr("Error"), tr("Plugin Type must either be \"gui\" or \"data\"."));
|
|
||||||
msgBox.exec();
|
|
||||||
m_ui->lePluginType->setText(QString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onAppAddClicked()
|
|
||||||
{
|
|
||||||
m_changed = true;
|
|
||||||
|
|
||||||
if (m_ui->leAppName->text().isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The App needs to have a name."));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList appList;
|
|
||||||
Q_FOREACH (const LtsAppDescriptor::AppDescription &appDesc, m_vector)
|
|
||||||
{
|
|
||||||
appList << appDesc.appName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appList.contains(m_ui->leAppName->text(), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("There already exists an app named \"%1\".").arg(m_ui->leAppName->text()));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescription newApp;
|
|
||||||
newApp.appName = m_ui->leAppName->text();
|
|
||||||
newApp.active = m_ui->chbAppActive->isChecked();
|
|
||||||
m_vector.append(newApp);
|
|
||||||
|
|
||||||
updateAppModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onPluginAddClicked()
|
|
||||||
{
|
|
||||||
m_changed = true;
|
|
||||||
|
|
||||||
if (m_ui->lePluginType->text().isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to contain a type."));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_ui->lePluginName->text().isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to have a name."));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList pluginList;
|
|
||||||
Q_FOREACH (const LtsAppDescriptor::PluginInfo &pluginDesc, m_vector.at(m_appIndex.row()).requiredPlugins)
|
|
||||||
{
|
|
||||||
pluginList << pluginDesc.iid;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pluginList.contains(m_ui->lePluginName->text(), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("There already exists an plugin named \"%1\".").arg(m_ui->lePluginName->text()));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo newPlugin;
|
|
||||||
|
|
||||||
newPlugin.iid = m_ui->lePluginName->text();
|
|
||||||
|
|
||||||
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
|
||||||
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::GUI;
|
|
||||||
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
|
||||||
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
|
||||||
else
|
|
||||||
newPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::UNKNOWN;
|
|
||||||
|
|
||||||
if (m_ui->chbActions->isChecked())
|
|
||||||
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::ACTIONS;
|
|
||||||
if (m_ui->chbMain->isChecked())
|
|
||||||
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::MAIN;
|
|
||||||
if (m_ui->chbPayload->isChecked())
|
|
||||||
newPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
|
||||||
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins.append(newPlugin);
|
|
||||||
|
|
||||||
onAppsClicked(m_appIndex);
|
|
||||||
onNewpluginClicked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onAppDeleteClicked()
|
|
||||||
{
|
|
||||||
m_changed = true;
|
|
||||||
|
|
||||||
if (!m_appIndex.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMessageBox msgBox(tr("Warning"),
|
|
||||||
tr("The App \n\"%1\" \nwill be removed. Continue?").arg(m_appIndex.data().toString()),
|
|
||||||
QMessageBox::Warning,
|
|
||||||
QMessageBox::Yes | QMessageBox::Default,
|
|
||||||
QMessageBox::No | QMessageBox::Escape,
|
|
||||||
QMessageBox::NoButton);
|
|
||||||
|
|
||||||
if (msgBox.exec() == QMessageBox::No)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_vector.remove(m_appIndex.row());
|
|
||||||
|
|
||||||
updateAppModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onPluginDeletedClicked()
|
|
||||||
{
|
|
||||||
m_changed = true;
|
|
||||||
|
|
||||||
if (!m_pluginIndex.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMessageBox msgBox(tr("Warning"),
|
|
||||||
tr("The Plugin \n\"%1\" \nwill be removed. Continue?").arg(m_pluginIndex.data().toString()),
|
|
||||||
QMessageBox::Warning,
|
|
||||||
QMessageBox::Yes | QMessageBox::Default,
|
|
||||||
QMessageBox::No | QMessageBox::Escape,
|
|
||||||
QMessageBox::NoButton);
|
|
||||||
|
|
||||||
if (msgBox.exec() == QMessageBox::No)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins.remove(m_pluginIndex.row());
|
|
||||||
m_pluginIndex = QModelIndex();
|
|
||||||
m_ui->lePluginName->setText(QString());
|
|
||||||
m_ui->lePluginType->setText(QString());
|
|
||||||
m_ui->chbActions->setChecked(false);
|
|
||||||
m_ui->chbMain->setChecked(false);
|
|
||||||
m_ui->chbPayload->setChecked(false);
|
|
||||||
|
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
|
||||||
|
|
||||||
onAppsClicked(m_appIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onUpdateClicked()
|
|
||||||
{
|
|
||||||
m_changed = true;
|
|
||||||
|
|
||||||
if (m_ui->lePluginType->text().isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to contain a type."));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_ui->lePluginName->text().isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(QMessageBox::Critical, tr("Error"), tr("The Plugin needs to have a name."));
|
|
||||||
msgBox.exec();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].iid = m_ui->lePluginName->text();
|
|
||||||
|
|
||||||
if (m_ui->lePluginType->text() == QLatin1String("gui"))
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = LtsAppDescriptor::PluginInfo::PluginType::GUI;
|
|
||||||
else if (m_ui->lePluginType->text() == QLatin1String("data"))
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
|
||||||
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 = QFlags<LtsAppDescriptor::PluginInfo::Flag>();
|
|
||||||
|
|
||||||
if (m_ui->chbActions->isChecked())
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::ACTIONS;
|
|
||||||
if (m_ui->chbMain->isChecked())
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::MAIN;
|
|
||||||
if (m_ui->chbPayload->isChecked())
|
|
||||||
m_vector[m_appIndex.row()].requiredPlugins[m_pluginIndex.row()].flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
|
||||||
|
|
||||||
onAppsClicked(m_appIndex);
|
|
||||||
onNewpluginClicked();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onNewpluginClicked()
|
|
||||||
{
|
|
||||||
m_ui->lePluginName->setText(QString());
|
|
||||||
m_ui->lePluginType->setText(QString());
|
|
||||||
m_ui->chbActions->setEnabled(true);
|
|
||||||
m_ui->chbMain->setEnabled(true);
|
|
||||||
m_ui->chbPayload->setEnabled(true);
|
|
||||||
m_ui->chbActions->setChecked(false);
|
|
||||||
m_ui->chbMain->setChecked(false);
|
|
||||||
m_ui->chbPayload->setChecked(false);
|
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
|
||||||
|
|
||||||
if (m_pluginIndex.isValid())
|
|
||||||
m_ui->lvPlugins->selectionModel()->select(m_pluginIndex, QItemSelectionModel::Deselect);
|
|
||||||
m_pluginIndex = QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onNewAppClicked()
|
|
||||||
{
|
|
||||||
updatePluginModel(QStringList());
|
|
||||||
|
|
||||||
m_ui->gbPlugins->setEnabled(false);
|
|
||||||
m_ui->pbDeletePlugin->setEnabled(false);
|
|
||||||
m_ui->pbDeleteApp->setEnabled(false);
|
|
||||||
m_ui->pbAddPlugin->setEnabled(false);
|
|
||||||
m_ui->pbUpdate->setEnabled(false);
|
|
||||||
m_ui->pbNewPlugin->setEnabled(false);
|
|
||||||
m_ui->leAppName->setText(QString());
|
|
||||||
m_ui->chbAppActive->setChecked(false);
|
|
||||||
m_ui->lePluginName->setText(QString());
|
|
||||||
m_ui->lePluginType->setText(QString());
|
|
||||||
m_ui->chbActions->setChecked(false);
|
|
||||||
m_ui->chbMain->setChecked(false);
|
|
||||||
m_ui->chbPayload->setChecked(false);
|
|
||||||
m_ui->pbNewApp->setEnabled(false);
|
|
||||||
|
|
||||||
if (m_appIndex.isValid())
|
|
||||||
m_ui->lvApps->selectionModel()->select(m_appIndex, QItemSelectionModel::Deselect);
|
|
||||||
m_appIndex = QModelIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::updateAppModel()
|
|
||||||
{
|
|
||||||
onNewAppClicked();
|
|
||||||
QStringList appList;
|
|
||||||
Q_FOREACH (const LtsAppDescriptor::AppDescription &appDesc, m_vector)
|
|
||||||
{
|
|
||||||
appList << appDesc.appName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_ui->lvApps->model())
|
|
||||||
m_ui->lvApps->setModel(new QStringListModel(this));
|
|
||||||
QStringListModel *m = qobject_cast<QStringListModel *>(m_ui->lvApps->model());
|
|
||||||
if (!m)
|
|
||||||
return;
|
|
||||||
m->setStringList(appList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::updatePluginModel(const QStringList &list)
|
|
||||||
{
|
|
||||||
if (!m_ui->lvPlugins->model())
|
|
||||||
m_ui->lvPlugins->setModel(new QStringListModel(this));
|
|
||||||
QStringListModel *m = qobject_cast<QStringListModel *>(m_ui->lvPlugins->model());
|
|
||||||
if (!m)
|
|
||||||
return;
|
|
||||||
m->setStringList(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::checkSave()
|
|
||||||
{
|
|
||||||
if (m_changed)
|
|
||||||
{
|
|
||||||
QMessageBox msgBox(tr("Warning"),
|
|
||||||
tr("The Data has been modified.\nDo you want to save your changes?"),
|
|
||||||
QMessageBox::Warning,
|
|
||||||
QMessageBox::Yes | QMessageBox::Default,
|
|
||||||
QMessageBox::No | QMessageBox::Escape,
|
|
||||||
QMessageBox::NoButton);
|
|
||||||
|
|
||||||
if (msgBox.exec() == QMessageBox::Yes)
|
|
||||||
onSaveAsClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onSaveAsClicked()
|
|
||||||
{
|
|
||||||
QString fileName =
|
|
||||||
QFileDialog::getSaveFileName(this, tr("Save JSON"), QLatin1Literal("/shd/CTC/TOOLS/TDS/TDS-source/Lts/Projects/Legatus/resources/"), tr("JSON File (*.json)"));
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QByteArray jsonByteArray;
|
|
||||||
jsonByteArray = LtsAppDescriptor::LtsAppDescriptor::createJson(m_vector);
|
|
||||||
|
|
||||||
QFile f(fileName);
|
|
||||||
f.open(QIODevice::WriteOnly);
|
|
||||||
f.write(jsonByteArray);
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
m_changed = false;
|
|
||||||
|
|
||||||
QMessageBox msgBox(QMessageBox::Information, tr("Success"), tr("Your file has been saved."));
|
|
||||||
msgBox.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onSaveClicked()
|
|
||||||
{
|
|
||||||
const QByteArray jsonByteArray(LtsAppDescriptor::LtsAppDescriptor::createJson(m_vector));
|
|
||||||
|
|
||||||
QFile f(m_fileName);
|
|
||||||
f.open(QIODevice::WriteOnly);
|
|
||||||
f.write(jsonByteArray);
|
|
||||||
f.close();
|
|
||||||
|
|
||||||
m_changed = false;
|
|
||||||
|
|
||||||
QMessageBox msgBox(QMessageBox::Information, tr("Success"), tr("Your file has been saved."));
|
|
||||||
msgBox.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onOpenClicked()
|
|
||||||
{
|
|
||||||
checkSave();
|
|
||||||
getAppDescriptionVector();
|
|
||||||
m_changed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onNewClicked()
|
|
||||||
{
|
|
||||||
checkSave();
|
|
||||||
m_ui->chbActions->setChecked(false);
|
|
||||||
m_ui->chbMain->setChecked(false);
|
|
||||||
m_ui->chbPayload->setChecked(false);
|
|
||||||
m_ui->chbAppActive->setChecked(false);
|
|
||||||
m_ui->leAppName->setText(QString());
|
|
||||||
m_ui->lePluginName->setText(QString());
|
|
||||||
m_ui->lePluginType->setText(QString());
|
|
||||||
m_ui->gbPlugins->setEnabled(false);
|
|
||||||
|
|
||||||
m_vector = LtsAppDescriptor::AppDescriptionVector();
|
|
||||||
|
|
||||||
updateAppModel();
|
|
||||||
updatePluginModel(QStringList());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::enableNewPlugin()
|
|
||||||
{
|
|
||||||
m_ui->pbNewPlugin->setEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppDescriptorEditor::onQuitClicked()
|
|
||||||
{
|
|
||||||
QApplication::quit();
|
|
||||||
}
|
|
||||||
-65
@@ -1,65 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "lts_app_descriptor.h"
|
|
||||||
|
|
||||||
#include <QtCore/QModelIndex>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
#ifndef LTSAPPDESCRIPTOREDITOR_EXPORT
|
|
||||||
#ifdef BUILD_STATIC_LIBRARIES
|
|
||||||
#define LTSAPPDESCRIPTOREDITOR_EXPORT
|
|
||||||
#else
|
|
||||||
#if defined(MAKE_LTSAPPDESCRIPTOREDITOR_LIB)
|
|
||||||
#define LTSAPPDESCRIPTOREDITOR_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
#define LTSAPPDESCRIPTOREDITOR_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Ui_LtsAppDescriptionEditor;
|
|
||||||
|
|
||||||
class LTSAPPDESCRIPTOREDITOR_EXPORT LtsAppDescriptorEditor : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit LtsAppDescriptorEditor(QWidget *parent = 0);
|
|
||||||
~LtsAppDescriptorEditor();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui_LtsAppDescriptionEditor *m_ui;
|
|
||||||
LtsAppDescriptor::AppDescriptionVector m_vector;
|
|
||||||
QModelIndex m_appIndex;
|
|
||||||
QModelIndex m_pluginIndex;
|
|
||||||
|
|
||||||
QString m_fileName;
|
|
||||||
|
|
||||||
bool m_changed;
|
|
||||||
|
|
||||||
void getAppDescriptionVector();
|
|
||||||
void setupMainWindow();
|
|
||||||
void updateAppModel();
|
|
||||||
void updatePluginModel(const QStringList &list);
|
|
||||||
void checkSave();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onAppsClicked(const QModelIndex &index);
|
|
||||||
void onPluginsClicked(const QModelIndex &index);
|
|
||||||
void pluginTypeChanged();
|
|
||||||
void onAppAddClicked();
|
|
||||||
void onPluginAddClicked();
|
|
||||||
void onAppDeleteClicked();
|
|
||||||
void onPluginDeletedClicked();
|
|
||||||
void onUpdateClicked();
|
|
||||||
void onNewpluginClicked();
|
|
||||||
void onNewAppClicked();
|
|
||||||
void enableNewPlugin();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onSaveClicked();
|
|
||||||
void onSaveAsClicked();
|
|
||||||
void onOpenClicked();
|
|
||||||
void onNewClicked();
|
|
||||||
void onQuitClicked();
|
|
||||||
};
|
|
||||||
-434
@@ -1,434 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>LtsAppDescriptionEditor</class>
|
|
||||||
<widget class="QWidget" name="LtsAppDescriptionEditor">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>865</width>
|
|
||||||
<height>337</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="autoFillBackground">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="3" column="3" colspan="2">
|
|
||||||
<widget class="QLabel" name="Plugins">
|
|
||||||
<property name="text">
|
|
||||||
<string>Required Plugins:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="3">
|
|
||||||
<widget class="QLabel" name="AppLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>App:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" rowspan="4" colspan="3">
|
|
||||||
<widget class="QListView" name="lvApps">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>150</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="7">
|
|
||||||
<widget class="QPushButton" name="pbNewPlugin">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>New</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="3" colspan="2">
|
|
||||||
<widget class="QLabel" name="AppName">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Name:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="6">
|
|
||||||
<widget class="QPushButton" name="pbDeletePlugin">
|
|
||||||
<property name="text">
|
|
||||||
<string>Delete</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="7" rowspan="4" colspan="3">
|
|
||||||
<widget class="QGroupBox" name="gbPlugins">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="title">
|
|
||||||
<string>New Plugin Requirements</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="PluginType">
|
|
||||||
<property name="text">
|
|
||||||
<string>Type:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="lePluginType">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>210</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>200</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>gui/data</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="PluginName">
|
|
||||||
<property name="text">
|
|
||||||
<string>IID:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="lePluginName">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>210</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Name of the Plugin</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="PluginFlags">
|
|
||||||
<property name="text">
|
|
||||||
<string>Flags:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QCheckBox" name="chbActions">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>25</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Actions</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QCheckBox" name="chbMain">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>25</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Main</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QCheckBox" name="chbPayload">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>25</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Payload</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Expanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3" colspan="2">
|
|
||||||
<widget class="QLabel" name="AppActive">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Active:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QPushButton" name="pbDeleteApp">
|
|
||||||
<property name="text">
|
|
||||||
<string>Delete</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="3" colspan="4">
|
|
||||||
<widget class="QListView" name="lvPlugins">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>300</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="editTriggers">
|
|
||||||
<set>QAbstractItemView::NoEditTriggers</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="9">
|
|
||||||
<widget class="QPushButton" name="pbUpdate">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Update</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="5">
|
|
||||||
<widget class="QLineEdit" name="leAppName">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>30</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>30</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Name of the App</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="8">
|
|
||||||
<widget class="QPushButton" name="pbAddPlugin">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Add</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QPushButton" name="pbNewApp">
|
|
||||||
<property name="text">
|
|
||||||
<string>New</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="5">
|
|
||||||
<widget class="QCheckBox" name="chbAppActive">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>80</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QPushButton" name="pbAddApp">
|
|
||||||
<property name="text">
|
|
||||||
<string>Add</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>List of Apps</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="6" rowspan="3">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<tabstops>
|
|
||||||
<tabstop>lvApps</tabstop>
|
|
||||||
<tabstop>pbNewApp</tabstop>
|
|
||||||
<tabstop>pbAddApp</tabstop>
|
|
||||||
<tabstop>pbDeleteApp</tabstop>
|
|
||||||
<tabstop>chbAppActive</tabstop>
|
|
||||||
<tabstop>leAppName</tabstop>
|
|
||||||
<tabstop>lvPlugins</tabstop>
|
|
||||||
<tabstop>pbDeletePlugin</tabstop>
|
|
||||||
<tabstop>pbNewPlugin</tabstop>
|
|
||||||
<tabstop>lePluginType</tabstop>
|
|
||||||
<tabstop>lePluginName</tabstop>
|
|
||||||
<tabstop>chbPayload</tabstop>
|
|
||||||
<tabstop>chbMain</tabstop>
|
|
||||||
<tabstop>chbActions</tabstop>
|
|
||||||
<tabstop>pbAddPlugin</tabstop>
|
|
||||||
<tabstop>pbUpdate</tabstop>
|
|
||||||
</tabstops>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_app_descriptor_editor.h"
|
|
||||||
|
|
||||||
#include <QtGui/QAction>
|
|
||||||
#include <QtWidgets/QApplication>
|
|
||||||
#include <QtWidgets/QMainWindow>
|
|
||||||
#include <QtWidgets/QMenuBar>
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
QApplication a(argc, argv);
|
|
||||||
|
|
||||||
QMainWindow *mainWindow = new QMainWindow();
|
|
||||||
QMenu *fileMenu = mainWindow->menuBar()->addMenu(QObject::tr("&File"));
|
|
||||||
|
|
||||||
QAction *openAct = new QAction(QObject::tr("&Open"), mainWindow);
|
|
||||||
openAct->setShortcuts(QKeySequence::Open);
|
|
||||||
openAct->setStatusTip(QObject::tr("Open an existing file"));
|
|
||||||
fileMenu->addAction(openAct);
|
|
||||||
|
|
||||||
QAction *newAct = new QAction(QObject::tr("&New"), mainWindow);
|
|
||||||
newAct->setShortcuts(QKeySequence::New);
|
|
||||||
newAct->setStatusTip(QObject::tr("Create a new App"));
|
|
||||||
fileMenu->addAction(newAct);
|
|
||||||
|
|
||||||
QAction *saveAct = new QAction(QObject::tr("&Save"), mainWindow);
|
|
||||||
saveAct->setShortcuts(QKeySequence::Save);
|
|
||||||
saveAct->setStatusTip(QObject::tr("Save modified file"));
|
|
||||||
fileMenu->addAction(saveAct);
|
|
||||||
|
|
||||||
QAction *saveAsAct = new QAction(QObject::tr("&SaveAs"), mainWindow);
|
|
||||||
saveAsAct->setShortcuts(QKeySequence::SaveAs);
|
|
||||||
saveAsAct->setStatusTip(QObject::tr("Save modified file as"));
|
|
||||||
fileMenu->addAction(saveAsAct);
|
|
||||||
|
|
||||||
QAction *quitAct = new QAction(QObject::tr("&Quit"), mainWindow);
|
|
||||||
quitAct->setShortcuts(QKeySequence::Quit);
|
|
||||||
quitAct->setStatusTip(QObject::tr("Quit the Application"));
|
|
||||||
fileMenu->addAction(quitAct);
|
|
||||||
|
|
||||||
LtsAppDescriptorEditor *editor = new LtsAppDescriptorEditor(mainWindow);
|
|
||||||
mainWindow->setCentralWidget(editor);
|
|
||||||
QObject::connect(openAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onOpenClicked);
|
|
||||||
QObject::connect(newAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onNewClicked);
|
|
||||||
QObject::connect(saveAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onSaveClicked);
|
|
||||||
QObject::connect(saveAsAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onSaveAsClicked);
|
|
||||||
QObject::connect(quitAct, &QAction::triggered, editor, &LtsAppDescriptorEditor::onQuitClicked);
|
|
||||||
|
|
||||||
mainWindow->show();
|
|
||||||
|
|
||||||
int ret = a.exec();
|
|
||||||
delete mainWindow;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(ALL LtsCommandLineParser SHARED
|
|
||||||
LtsCommandLineParser.cpp
|
|
||||||
LtsCommandLineParser.h
|
|
||||||
)
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsCommandLineParser
|
|
||||||
INTERFACE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsCommandLineParser
|
|
||||||
PRIVATE
|
|
||||||
ngltools
|
|
||||||
Qt6::Network
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
)
|
|
||||||
-175
@@ -1,175 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "LtsCommandLineParser.h"
|
|
||||||
|
|
||||||
#include <QtCore/QFlags>
|
|
||||||
#include <QNetworkInterface>
|
|
||||||
#include <QtCore/QSettings>
|
|
||||||
#include <QtCore/QUrl>
|
|
||||||
#include <ngltools/ngltools_filesystem.h>
|
|
||||||
|
|
||||||
namespace LtsCommandLineParser
|
|
||||||
{
|
|
||||||
static constexpr int s_maxDomainId = 232;
|
|
||||||
|
|
||||||
LtsCommandLineParser::LtsCommandLineParser(ProvideCommandLineParameterOptions opts)
|
|
||||||
: QCommandLineParser()
|
|
||||||
, m_enabledOptions(opts)
|
|
||||||
{
|
|
||||||
if (NGL::isAppInBuildBasePath() || m_enabledOptions.testFlag(CreateDomainIdFromIp))
|
|
||||||
{
|
|
||||||
const QList<QHostAddress> addresses = QNetworkInterface::allAddresses();
|
|
||||||
for (const QHostAddress &address : addresses)
|
|
||||||
{
|
|
||||||
if (address.isLoopback() || address.isNull())
|
|
||||||
continue;
|
|
||||||
if (address.protocol() != QAbstractSocket::IPv4Protocol)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
m_generatedDomainId = (address.toIPv4Address() & 0x000000ff) % 232;
|
|
||||||
if (m_generatedDomainId == 0)
|
|
||||||
m_generatedDomainId = s_maxDomainId;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_enabledOptions.testFlag(ExerciseId))
|
|
||||||
addOption({{QStringLiteral("e"), QStringLiteral("exerciseid")},
|
|
||||||
QStringLiteral("Default: -1 (invalid, get from lts-cc.conf)"),
|
|
||||||
QStringLiteral("exerciseId"),
|
|
||||||
QStringLiteral("-1")});
|
|
||||||
if (m_enabledOptions.testFlag(DomainId))
|
|
||||||
addOption({{QStringLiteral("d"), QStringLiteral("domainid")},
|
|
||||||
QStringLiteral("Default: ") + QString::number(m_generatedDomainId),
|
|
||||||
QStringLiteral("domainId"),
|
|
||||||
QString::number(m_generatedDomainId)});
|
|
||||||
if (m_enabledOptions.testFlag(CustomConfigFile))
|
|
||||||
{
|
|
||||||
const QString cf(NGL::findProjectConfigFile());
|
|
||||||
addOption({{QStringLiteral("i"), QStringLiteral("ini")}, QStringLiteral("Default: ") + cf, QStringLiteral("filename"), cf});
|
|
||||||
}
|
|
||||||
if (m_enabledOptions.testFlag(TcpConnectionUrl))
|
|
||||||
{
|
|
||||||
const QString defaultTcpUrl(QStringLiteral("EXCTDS01:7400"));
|
|
||||||
addOption({{QStringLiteral("t"), QStringLiteral("tcpurl")}, QStringLiteral("Default: ") + defaultTcpUrl, QStringLiteral("hostname:port"), defaultTcpUrl});
|
|
||||||
}
|
|
||||||
addHelpOption();
|
|
||||||
|
|
||||||
if (!m_enabledOptions.testFlag(NoVersion))
|
|
||||||
addVersionOption();
|
|
||||||
}
|
|
||||||
|
|
||||||
int LtsCommandLineParser::domainId() const
|
|
||||||
{
|
|
||||||
if (m_domainId == 0 && m_generatedDomainId != 0 && !m_domainIdSetByFunction)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
|
|
||||||
fprintf(stdout,
|
|
||||||
"\n\nAttention: using a default domain id != 0 because executable is run inside builddir - default "
|
|
||||||
"domainid is %d\n\n",
|
|
||||||
m_generatedDomainId);
|
|
||||||
#else
|
|
||||||
fprintf(stdout,
|
|
||||||
"\n\n\e[31mAttention: using a default domain id != 0 because executable is run inside builddir - "
|
|
||||||
"default domainid is %d\e[0m\n\n",
|
|
||||||
m_generatedDomainId);
|
|
||||||
#endif
|
|
||||||
return m_generatedDomainId;
|
|
||||||
}
|
|
||||||
return m_domainId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCommandLineParser::setDomainId(int id)
|
|
||||||
{
|
|
||||||
m_domainIdSetByFunction = true;
|
|
||||||
m_domainId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCommandLineParser::iniFileSet() const
|
|
||||||
{
|
|
||||||
if (!m_enabledOptions.testFlag(CustomConfigFile))
|
|
||||||
return false;
|
|
||||||
return isSet(QStringLiteral("i"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCommandLineParser::useTcpConnection() const
|
|
||||||
{
|
|
||||||
if (!m_enabledOptions.testFlag(TcpConnectionUrl))
|
|
||||||
return false;
|
|
||||||
return isSet(QStringLiteral("t"));
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl LtsCommandLineParser::tcpConnectionUrl() const
|
|
||||||
{
|
|
||||||
if (!m_enabledOptions.testFlag(TcpConnectionUrl))
|
|
||||||
return QUrl();
|
|
||||||
if (!useTcpConnection())
|
|
||||||
return QUrl();
|
|
||||||
QString str = value(QStringLiteral("t"));
|
|
||||||
|
|
||||||
str.replace(QLatin1String("tcpv4_lan"), QLatin1String("tcpv4lan"));
|
|
||||||
QUrl url = QUrl::fromUserInput(str);
|
|
||||||
if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("file"))
|
|
||||||
url.setScheme(QStringLiteral("tcpv4lan"));
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCommandLineParser::init(bool bParseHelp)
|
|
||||||
{
|
|
||||||
if (!parse(QCoreApplication::arguments()))
|
|
||||||
{
|
|
||||||
fprintf(stdout, "\nBad option: %s \n", qPrintable(errorText()));
|
|
||||||
if (!m_unitModuleTestMode)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_enabledOptions.testFlag(ExerciseId))
|
|
||||||
m_exerciseId = value(QStringLiteral("e")).toInt();
|
|
||||||
if (m_enabledOptions.testFlag(DomainId))
|
|
||||||
m_domainId = value(QStringLiteral("d")).toInt();
|
|
||||||
if (m_enabledOptions.testFlag(CustomConfigFile))
|
|
||||||
m_iniFile = value(QStringLiteral("i"));
|
|
||||||
|
|
||||||
if (bParseHelp && isSet(QStringLiteral("h")))
|
|
||||||
showHelp();
|
|
||||||
if (!m_unitModuleTestMode && isSet(QStringLiteral("v")))
|
|
||||||
showVersion();
|
|
||||||
if (!domainIdProvided())
|
|
||||||
{
|
|
||||||
const QString iniFile = m_iniFile.isEmpty() ? NGL::findProjectConfigFile() : m_iniFile;
|
|
||||||
if (!iniFile.isEmpty())
|
|
||||||
{
|
|
||||||
QSettings s(iniFile, QSettings::IniFormat);
|
|
||||||
bool bOk;
|
|
||||||
int domainId = s.value(QStringLiteral("Global/DomainId"), m_domainId).toInt(&bOk);
|
|
||||||
if (bOk && domainId > 0 && domainId <= s_maxDomainId)
|
|
||||||
m_domainId = domainId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCommandLineParser::showHelp(int exitCode)
|
|
||||||
{
|
|
||||||
if (!m_additionalHelpStr.isEmpty())
|
|
||||||
fprintf(stdout, "%s", qPrintable(m_additionalHelpStr));
|
|
||||||
|
|
||||||
QCommandLineParser::showHelp(exitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCommandLineParser::domainIdProvided() const
|
|
||||||
{
|
|
||||||
if (!m_enabledOptions.testFlag(DomainId))
|
|
||||||
return false;
|
|
||||||
return isSet(QStringLiteral("d"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCommandLineParser::exerciseIdProvided() const
|
|
||||||
{
|
|
||||||
if (!m_enabledOptions.testFlag(ExerciseId))
|
|
||||||
return false;
|
|
||||||
return isSet(QStringLiteral("e"));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsCommandLineParser
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltscommandlineparser_export.h"
|
|
||||||
|
|
||||||
#include <QCommandLineParser>
|
|
||||||
|
|
||||||
class QUrl;
|
|
||||||
|
|
||||||
namespace LtsCommandLineParser
|
|
||||||
{
|
|
||||||
class LTSCOMMANDLINEPARSER_EXPORT LtsCommandLineParser : public QCommandLineParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum ProvideCommandLineParameterOptions
|
|
||||||
{
|
|
||||||
None = 0x0000,
|
|
||||||
CreateDomainIdFromIp = 0x0001,
|
|
||||||
DomainId = 0x0002,
|
|
||||||
ExerciseId = 0x0004,
|
|
||||||
CustomConfigFile = 0x0008,
|
|
||||||
TcpConnectionUrl = 0x0010,
|
|
||||||
NoVersion = 0x0020
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit LtsCommandLineParser(ProvideCommandLineParameterOptions opts = ProvideCommandLineParameterOptions(CreateDomainIdFromIp | DomainId | ExerciseId |
|
|
||||||
CustomConfigFile));
|
|
||||||
virtual ~LtsCommandLineParser() = default;
|
|
||||||
int domainId() const;
|
|
||||||
void setDomainId(int id);
|
|
||||||
|
|
||||||
int exerciseId() const { return m_exerciseId; }
|
|
||||||
|
|
||||||
QString iniFile() const { return m_iniFile; }
|
|
||||||
|
|
||||||
bool iniFileSet() const;
|
|
||||||
bool useTcpConnection() const;
|
|
||||||
QUrl tcpConnectionUrl() const;
|
|
||||||
virtual bool init(bool bParseHelp = true);
|
|
||||||
|
|
||||||
void showHelp(int exitCode = 0);
|
|
||||||
bool domainIdProvided() const;
|
|
||||||
bool exerciseIdProvided() const;
|
|
||||||
|
|
||||||
void setUnitModuleTestMode(bool onOff) { m_unitModuleTestMode = onOff; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QString m_additionalHelpStr;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QFlags<ProvideCommandLineParameterOptions> m_enabledOptions;
|
|
||||||
int m_exerciseId{0};
|
|
||||||
int m_domainId{0};
|
|
||||||
int m_generatedDomainId{0};
|
|
||||||
bool m_domainIdSetByFunction{false};
|
|
||||||
bool m_unitModuleTestMode{false};
|
|
||||||
QString m_iniFile;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsCommandLineParser
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Christian Ehrlicher, SLSE, 2016-08-31
|
|
||||||
#
|
|
||||||
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Add system GeographicLib Find module path
|
|
||||||
list(APPEND CMAKE_MODULE_PATH /usr/share/cmake/geographiclib)
|
|
||||||
FIND_PACKAGE(GeographicLib)
|
|
||||||
NGL_ADD_LIBRARY2(LtsCoordTrans WS AAR SV HLA SHARED
|
|
||||||
lts_coord_trans.h
|
|
||||||
lts_coord_trans.cpp
|
|
||||||
)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsCoordTrans
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
)
|
|
||||||
if (GeographicLib_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(LtsCoordTrans
|
|
||||||
PRIVATE ${GeographicLib_LIBRARIES}
|
|
||||||
)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(LtsCoordTrans PRIVATE ${GeographicLib_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${GeographicLib_LIBRARY_DIRS})
|
|
||||||
else()
|
|
||||||
message(STATUS "GeographicLib not found; building LtsCoordTrans without it")
|
|
||||||
endif()
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsCoordTrans
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
SET(ltsCoordWidget_SRCS
|
|
||||||
lts_coord_widget.cpp
|
|
||||||
lts_coord_widget.h
|
|
||||||
lts_coord_widget_p.cpp
|
|
||||||
lts_coord_widget_p.h
|
|
||||||
)
|
|
||||||
NGL_WRAP_UI(ltsCoordWidget_SRCS
|
|
||||||
lts_coord_widget_mgrs.ui
|
|
||||||
lts_coord_widget_wgs84.ui
|
|
||||||
)
|
|
||||||
NGL_ADD_LIBRARY2(ltsCoordWidget WS AAR SV SHARED ${ltsCoordWidget_SRCS})
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(ltsCoordWidget
|
|
||||||
PRIVATE
|
|
||||||
LtsCoordTrans
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
${Qt6_Widgets}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(ltsCoordWidget
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../LtsUtils/LtsUtilsCore
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(TARGET LtsCoordTrans)
|
|
||||||
SET(_tools lonlat2mgrs mgrs2lonlat)
|
|
||||||
FOREACH(_tool ${_tools})
|
|
||||||
NGL_ADD_EXECUTABLE(ALL ${_tool} ${_tool}.cpp)
|
|
||||||
TARGET_LINK_LIBRARIES(${_tool}
|
|
||||||
Qt6::Core
|
|
||||||
${GeographicLib_LIBRARIES}
|
|
||||||
)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(${_tool} PRIVATE ${GeographicLib_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${GeographicLib_LIBRARY_DIRS})
|
|
||||||
NGL_INSTALL_TARGET(${_tool})
|
|
||||||
ENDFOREACH()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(BUILD_TESTING AND TARGET ltsCoordWidget)
|
|
||||||
ADD_EXECUTABLE(lts_coord_widget_test lts_coord_widget_test.cpp)
|
|
||||||
TARGET_LINK_LIBRARIES(lts_coord_widget_test
|
|
||||||
ltsCoordWidget
|
|
||||||
LtsCoordTrans
|
|
||||||
)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF(BUILD_TESTING AND TARGET LtsCoordTrans)
|
|
||||||
ADD_EXECUTABLE(lts_coord_trans_unit_test
|
|
||||||
lts_coord_trans_unit_test.cpp
|
|
||||||
lts_coord_trans_unit_test.h
|
|
||||||
)
|
|
||||||
TARGET_LINK_LIBRARIES(lts_coord_trans_unit_test
|
|
||||||
LtsCoordTrans
|
|
||||||
Qt6::Test
|
|
||||||
${GeographicLib_LIBRARIES}
|
|
||||||
)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(lts_coord_trans_unit_test PRIVATE ${GeographicLib_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${GeographicLib_LIBRARY_DIRS})
|
|
||||||
ADD_TEST(NAME lts_coord_trans_unit_test COMMAND $<TARGET_FILE:lts_coord_trans_unit_test>)
|
|
||||||
ENDIF()
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <GeographicLib/MGRS.hpp>
|
|
||||||
#include <GeographicLib/UTMUPS.hpp>
|
|
||||||
#include <cstring>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc < 3 || argc > 5)
|
|
||||||
{
|
|
||||||
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]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lonLatInRad = false;
|
|
||||||
double lon = atof(argv[1]);
|
|
||||||
double lat = atof(argv[2]);
|
|
||||||
int prec = 5;
|
|
||||||
if (argc >= 4)
|
|
||||||
{
|
|
||||||
int precArgId = -1;
|
|
||||||
if (strcmp(argv[3], "-r") == 0)
|
|
||||||
{
|
|
||||||
lonLatInRad = true;
|
|
||||||
if (argc == 5)
|
|
||||||
precArgId = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
precArgId = 3;
|
|
||||||
if (precArgId > 0)
|
|
||||||
prec = atoi(argv[precArgId]);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string mgrs;
|
|
||||||
|
|
||||||
int zone;
|
|
||||||
bool northp;
|
|
||||||
double x, y;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
const double latDeg = lonLatInRad ? lat * 180 / M_PI : lat;
|
|
||||||
const double lonDeg = lonLatInRad ? lon * 180 / M_PI : lon;
|
|
||||||
GeographicLib::UTMUPS::Forward(latDeg, lonDeg, zone, northp, x, y);
|
|
||||||
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error converting %9.6f, %9.6f to MGRS coords\n", lat, lon);
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
std::string part1, part2, part3, part4;
|
|
||||||
part1 = mgrs.substr(0, 3);
|
|
||||||
part2 = mgrs.substr(3, 2);
|
|
||||||
if (prec > 0)
|
|
||||||
{
|
|
||||||
part3 = mgrs.substr(5, 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(),
|
|
||||||
part3.c_str(),
|
|
||||||
part4.c_str(),
|
|
||||||
zone,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
northp ? 'N' : 'S');
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,437 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_coord_trans.h"
|
|
||||||
|
|
||||||
#include <GeographicLib/Geocentric.hpp>
|
|
||||||
#include <GeographicLib/MGRS.hpp>
|
|
||||||
#include <GeographicLib/UTMUPS.hpp>
|
|
||||||
#include <QtCore/QPointF>
|
|
||||||
#include <QtCore/QRectF>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace LtsCoordTrans
|
|
||||||
{
|
|
||||||
|
|
||||||
static long s_conversion_counter_MGRS_Forward = 0;
|
|
||||||
static long s_conversion_counter_MGRS_Reverse = 0;
|
|
||||||
|
|
||||||
static long s_conversion_counter_WGS84_Forward = 0;
|
|
||||||
static long s_conversion_counter_WGS84_Reverse = 0;
|
|
||||||
|
|
||||||
static long s_conversion_counter_UTMUPS_Forward = 0;
|
|
||||||
static long s_conversion_counter_UTMUPS_Reverse = 0;
|
|
||||||
|
|
||||||
inline void incrementCounter(long &counterRef)
|
|
||||||
{
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
++counterRef;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline std::string cleanupMgrsString(const QString &in)
|
|
||||||
{
|
|
||||||
const QByteArray ba(in.toLatin1());
|
|
||||||
std::string ret;
|
|
||||||
ret.reserve(ba.size());
|
|
||||||
for (const char c : ba)
|
|
||||||
{
|
|
||||||
if (c != ' ')
|
|
||||||
ret += c;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString UtmCoordinate::mgrs(int prec, bool withSpaces) const
|
|
||||||
{
|
|
||||||
if (prec < 0)
|
|
||||||
prec = 0;
|
|
||||||
if (prec > 11)
|
|
||||||
prec = 11;
|
|
||||||
|
|
||||||
std::string mgrs;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
|
||||||
incrementCounter(s_conversion_counter_MGRS_Forward);
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
mgrs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ret;
|
|
||||||
if (withSpaces && mgrs.size() == static_cast<size_t>(5 + 2 * prec))
|
|
||||||
{
|
|
||||||
|
|
||||||
const char *ptr = mgrs.c_str();
|
|
||||||
|
|
||||||
ret = QString::fromLatin1(ptr, 3) + QLatin1Char(' ') + QString::fromLatin1(ptr + 3, 2);
|
|
||||||
if (prec > 0)
|
|
||||||
{
|
|
||||||
ret += QLatin1Char(' ') + QString::fromLatin1(ptr + 5, prec) + QLatin1Char(' ') + QString::fromLatin1(ptr + 5 + prec, prec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = QString::fromLatin1(mgrs.c_str(), mgrs.size());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF UtmCoordinate::toPoint() const
|
|
||||||
{
|
|
||||||
return {x, y};
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF UtmCoordinate::geographic(double offsetX, double offsetY) const
|
|
||||||
{
|
|
||||||
QPointF ret;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GeographicLib::UTMUPS::Reverse(zone, northp, x + offsetX, y + offsetY, ret.ry(), ret.rx());
|
|
||||||
incrementCounter(s_conversion_counter_UTMUPS_Reverse);
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error while calculating geographic from utm %d, %9.6f, %9.6f: %s\n", zone, x + offsetX, y + offsetY, e.what());
|
|
||||||
ret = QPointF();
|
|
||||||
}
|
|
||||||
return ret * deg2rad();
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF UtmCoordinate::geographic(const QPointF &offset) const
|
|
||||||
{
|
|
||||||
return geographic(offset.x(), offset.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF UtmCoordinate::relativeTo(const UtmCoordinate &other) const
|
|
||||||
{
|
|
||||||
if (zone == other.zone)
|
|
||||||
return QPointF(x - other.x, y - other.y);
|
|
||||||
|
|
||||||
UtmCoordinate otherInMyZone = fromGeographic(other.geographic(), zone);
|
|
||||||
return QPointF(x - otherInMyZone.x, y - otherInMyZone.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
UtmCoordinate UtmCoordinate::fromGeographic(double lon, double lat, int setZone)
|
|
||||||
{
|
|
||||||
|
|
||||||
lon *= rad2deg();
|
|
||||||
lat *= rad2deg();
|
|
||||||
|
|
||||||
UtmCoordinate ret;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
GeographicLib::UTMUPS::Forward(lat, lon, ret.zone, ret.northp, ret.x, ret.y, setZone);
|
|
||||||
incrementCounter(s_conversion_counter_UTMUPS_Forward);
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error while calculating mgrs base point from %9.6f, %9.6f: %s\n", lat, lon, e.what());
|
|
||||||
ret = UtmCoordinate();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
UtmCoordinate UtmCoordinate::fromGeographic(const QPointF &lonLat, int setZone)
|
|
||||||
{
|
|
||||||
return fromGeographic(lonLat.x(), lonLat.y(), setZone);
|
|
||||||
}
|
|
||||||
|
|
||||||
UtmCoordinate UtmCoordinate::fromMgrs(const QString &mgrs)
|
|
||||||
{
|
|
||||||
UtmCoordinate utm;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int prec;
|
|
||||||
|
|
||||||
GeographicLib::MGRS::Reverse(cleanupMgrsString(mgrs), utm.zone, utm.northp, utm.x, utm.y, prec, true);
|
|
||||||
incrementCounter(s_conversion_counter_MGRS_Reverse);
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error while converting mgrs coordinate %s to utm: %s\n", qPrintable(mgrs), e.what());
|
|
||||||
utm = UtmCoordinate();
|
|
||||||
}
|
|
||||||
return utm;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString mgrsFromGeographic(double lon, double lat, int prec, bool withSpaces)
|
|
||||||
{
|
|
||||||
return UtmCoordinate::fromGeographic(lon, lat, -1).mgrs(prec, withSpaces);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF geographicFromMgrs(const QString &mgrs)
|
|
||||||
{
|
|
||||||
return UtmCoordinate::fromMgrs(mgrs).geographic();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> &staticDefaultSquaresHelper()
|
|
||||||
{
|
|
||||||
static QVector<UtmCoordinate> s_defaultMgrsSquares;
|
|
||||||
return s_defaultMgrsSquares;
|
|
||||||
}
|
|
||||||
|
|
||||||
UtmCoordinate &staticPreferedMgrsSquareHelper()
|
|
||||||
{
|
|
||||||
static UtmCoordinate s_preferedMgrsSquare;
|
|
||||||
return s_preferedMgrsSquare;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> &staticMgrsSquaresWithOffsetsHelper()
|
|
||||||
{
|
|
||||||
static QVector<UtmCoordinate> s_mgrsSquaresWithOffsets;
|
|
||||||
return s_mgrsSquaresWithOffsets;
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF addMarginToArea(const QRectF &rect_LatLon_radiant, const QSize &marginMeter)
|
|
||||||
{
|
|
||||||
double lonMin, lonMax, latMin, latMmax;
|
|
||||||
rect_LatLon_radiant.normalized().getCoords(&lonMin, &latMin, &lonMax, &latMmax);
|
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate basePoint;
|
|
||||||
{
|
|
||||||
|
|
||||||
const QPointF centerRad = rect_LatLon_radiant.center();
|
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(centerRad.x(), centerRad.y(), -1);
|
|
||||||
mgrs += QStringLiteral("00000000000000");
|
|
||||||
|
|
||||||
basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(mgrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin, basePoint.zone));
|
|
||||||
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax, basePoint.zone));
|
|
||||||
|
|
||||||
int offsetX = marginMeter.width();
|
|
||||||
int offsetY = marginMeter.height();
|
|
||||||
|
|
||||||
const QPointF topLeft(lowerLeft.geographic(-offsetX, -offsetY));
|
|
||||||
const QPointF bottomRight(upperRight.geographic(offsetX, offsetY));
|
|
||||||
|
|
||||||
QRectF res = QRectF(topLeft, bottomRight);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> getMgrsSquares(const QRectF &rect, bool setAsDefaultSquares, bool setAsPreferedSquare, bool setAsSquareWithMargin)
|
|
||||||
{
|
|
||||||
QVector<UtmCoordinate> ret = getMgrsSquaresInternal(rect);
|
|
||||||
|
|
||||||
if (setAsDefaultSquares)
|
|
||||||
staticDefaultSquaresHelper() = ret;
|
|
||||||
|
|
||||||
if (setAsPreferedSquare)
|
|
||||||
staticPreferedMgrsSquareHelper() = LtsCoordTrans::UtmCoordinate::fromGeographic(rect.center());
|
|
||||||
|
|
||||||
if (setAsSquareWithMargin)
|
|
||||||
staticMgrsSquaresWithOffsetsHelper() = ret;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF &rect)
|
|
||||||
{
|
|
||||||
QVector<UtmCoordinate> ret;
|
|
||||||
QVector<QString> tmpMgrsSquares;
|
|
||||||
|
|
||||||
double lonMin, lonMax, latMin, latMmax;
|
|
||||||
rect.normalized().getCoords(&lonMin, &latMin, &lonMax, &latMmax);
|
|
||||||
|
|
||||||
bool withInSingleUtmSquare = true;
|
|
||||||
{
|
|
||||||
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax));
|
|
||||||
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin));
|
|
||||||
withInSingleUtmSquare = upperRight.zone == lowerLeft.zone;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate basePoint;
|
|
||||||
{
|
|
||||||
|
|
||||||
QPointF centerRad = rect.center();
|
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(centerRad.x(), centerRad.y(), -1);
|
|
||||||
mgrs += QStringLiteral("00000000000000");
|
|
||||||
|
|
||||||
basePoint = LtsCoordTrans::UtmCoordinate::fromMgrs(mgrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
const UtmCoordinate upperRight(UtmCoordinate::fromGeographic(lonMax, latMmax, basePoint.zone));
|
|
||||||
const UtmCoordinate lowerLeft(UtmCoordinate::fromGeographic(lonMin, latMin, basePoint.zone));
|
|
||||||
|
|
||||||
const double maxX(upperRight.x - lowerLeft.x);
|
|
||||||
const double maxY(upperRight.y - lowerLeft.y);
|
|
||||||
|
|
||||||
const int increment = withInSingleUtmSquare ? 10000 : 1000;
|
|
||||||
for (double x = 0; x <= maxX + increment; x += increment)
|
|
||||||
{
|
|
||||||
const double xOfs = std::min(x, maxX);
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
tmpMgrsSquares += mgrs;
|
|
||||||
ret += utm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList getMgrsSurroundingSquares(const QRectF &geoRect, const QSize &offsetMeter)
|
|
||||||
{
|
|
||||||
|
|
||||||
const QVector<UtmCoordinate> mainUtms = getMgrsSquaresInternal(geoRect);
|
|
||||||
QStringList mainSquares;
|
|
||||||
mainSquares.reserve(mainUtms.count());
|
|
||||||
for (const auto &utm : mainUtms)
|
|
||||||
mainSquares.append(utm.mgrs(0));
|
|
||||||
|
|
||||||
const QRectF rectWithOffset = addMarginToArea(geoRect, offsetMeter);
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> mainUtmsWithOffset = getMgrsSquaresInternal(rectWithOffset);
|
|
||||||
QStringList mainSquaresWithOffset;
|
|
||||||
mainSquaresWithOffset.reserve(mainUtmsWithOffset.count());
|
|
||||||
for (const auto &utm : std::as_const(mainUtmsWithOffset))
|
|
||||||
mainSquaresWithOffset.append(utm.mgrs(0));
|
|
||||||
|
|
||||||
QStringList surroundingSquares;
|
|
||||||
surroundingSquares.reserve(mainSquaresWithOffset.count());
|
|
||||||
for (const auto &mgrs0 : mainSquaresWithOffset)
|
|
||||||
{
|
|
||||||
if (!mainSquares.contains(mgrs0))
|
|
||||||
surroundingSquares.append(mgrs0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return surroundingSquares;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> defaultMgrsSquareWithOffsets()
|
|
||||||
{
|
|
||||||
return staticMgrsSquaresWithOffsetsHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDefaultMgrsSquares(const QVector<QString> &squares)
|
|
||||||
{
|
|
||||||
QVector<UtmCoordinate> coords;
|
|
||||||
coords.reserve(squares.size());
|
|
||||||
for (const QString &s : squares)
|
|
||||||
coords += UtmCoordinate::fromMgrs(s + QStringLiteral("00000000000000"));
|
|
||||||
staticDefaultSquaresHelper() = coords;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> defaultMgrsSquares()
|
|
||||||
{
|
|
||||||
return staticDefaultSquaresHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
UtmCoordinate preferedMgrsSquare()
|
|
||||||
{
|
|
||||||
return staticPreferedMgrsSquareHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool lonLatAltToGeocentric(double lon, double lat, double altitude, double &xOut, double &yOut, double &zOut)
|
|
||||||
{
|
|
||||||
|
|
||||||
lon *= rad2deg();
|
|
||||||
lat *= rad2deg();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GeographicLib::Geocentric::WGS84().Forward(lat, lon, altitude, xOut, yOut, zOut);
|
|
||||||
incrementCounter(s_conversion_counter_WGS84_Forward);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
xOut = 0;
|
|
||||||
yOut = 0;
|
|
||||||
zOut = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool geocentric2LonLatAlt(double x, double y, double z, double &lon, double &lat, double &altitude)
|
|
||||||
{
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
GeographicLib::Geocentric::WGS84().Reverse(x, y, z, lat, lon, altitude);
|
|
||||||
incrementCounter(s_conversion_counter_WGS84_Reverse);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
lon = 0;
|
|
||||||
lat = 0;
|
|
||||||
altitude = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
lon *= deg2rad();
|
|
||||||
lat *= deg2rad();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
double distance(const QPointF &p1, const QPointF &p2)
|
|
||||||
{
|
|
||||||
return distance(p1.x(), p1.y(), p2.x(), p2.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
double squareDistance(const QPointF &p1, const QPointF &p2)
|
|
||||||
{
|
|
||||||
return squareDistance(p1.x(), p1.y(), p2.x(), p2.y());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &stream, const UtmCoordinate &coord)
|
|
||||||
{
|
|
||||||
|
|
||||||
stream << "UtmCoordinate(" << std::setprecision(8) << coord.x << "#" << std::setprecision(8) << coord.y << " zone=" << coord.zone << ")";
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpConversionCounter()
|
|
||||||
{
|
|
||||||
fprintf(stderr, "LtsCoordTrans: s_conversion_counter_MGRS_Forward : - mgrs : %ld\n", 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_WGS84_Forward - lonLatAltToGeocentric : %ld\n", s_conversion_counter_WGS84_Forward);
|
|
||||||
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()
|
|
||||||
{
|
|
||||||
return s_conversion_counter_MGRS_Forward;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getConversionCounter_MGRS_Reverse()
|
|
||||||
{
|
|
||||||
return s_conversion_counter_MGRS_Reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getConversionCounter_WGS84_Forward()
|
|
||||||
{
|
|
||||||
return s_conversion_counter_WGS84_Forward;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getConversionCounter_WGS84_Reverse()
|
|
||||||
{
|
|
||||||
return s_conversion_counter_WGS84_Reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getConversionCounter_UTMUPS_Forward()
|
|
||||||
{
|
|
||||||
return s_conversion_counter_UTMUPS_Forward;
|
|
||||||
}
|
|
||||||
|
|
||||||
long getConversionCounter_UTMUPS_Reverse()
|
|
||||||
{
|
|
||||||
return s_conversion_counter_UTMUPS_Reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsCoordTrans
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <cmath>
|
|
||||||
#include "ltscoordtrans_export.h"
|
|
||||||
#include <string>
|
|
||||||
class QPointF;
|
|
||||||
class QRectF;
|
|
||||||
class QSize;
|
|
||||||
class QString;
|
|
||||||
|
|
||||||
namespace LtsCoordTrans
|
|
||||||
{
|
|
||||||
|
|
||||||
inline Q_CONSTEXPR double pi()
|
|
||||||
{
|
|
||||||
return M_PI;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Q_CONSTEXPR double deg2rad()
|
|
||||||
{
|
|
||||||
return pi() / 180.;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Q_CONSTEXPR double rad2deg()
|
|
||||||
{
|
|
||||||
return 1. / deg2rad();
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LTSCOORDTRANS_EXPORT UtmCoordinate
|
|
||||||
{
|
|
||||||
int zone = -1;
|
|
||||||
bool northp = true;
|
|
||||||
double x = 0.;
|
|
||||||
double y = 0.;
|
|
||||||
|
|
||||||
UtmCoordinate() = default;
|
|
||||||
|
|
||||||
UtmCoordinate(int zone_, double x_, double y_, bool northp_ = true)
|
|
||||||
: zone(zone_)
|
|
||||||
, northp(northp_)
|
|
||||||
, x(x_)
|
|
||||||
, y(y_)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isValid() const { return zone > 0 && zone <= 60; }
|
|
||||||
|
|
||||||
QString mgrs(int prec = 5, bool withSpaces = true) const;
|
|
||||||
|
|
||||||
QPointF toPoint() const;
|
|
||||||
|
|
||||||
QPointF geographic(double offsetX = 0., double offsetY = 0.) const;
|
|
||||||
|
|
||||||
QPointF geographic(const QPointF &offset) const;
|
|
||||||
|
|
||||||
QPointF relativeTo(const UtmCoordinate &other) const;
|
|
||||||
|
|
||||||
static UtmCoordinate fromGeographic(double lon, double lat, int setZone = -1);
|
|
||||||
|
|
||||||
static UtmCoordinate fromGeographic(const QPointF &lonLat, int setZone = -1);
|
|
||||||
|
|
||||||
static UtmCoordinate fromMgrs(const QString &mgrs);
|
|
||||||
};
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QString mgrsFromGeographic(double lon, double lat, int prec = 5, bool withSpaces = true);
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QPointF geographicFromMgrs(const QString &mgrs);
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QRectF addMarginToArea(const QRectF &rect_LatLon_radiant, const QSize &marginMeter);
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> getMgrsSquares(const QRectF &rect, bool setAsDefaultSquares, bool setAsPreferedSquare, bool setAsSquareWithMargin = false);
|
|
||||||
|
|
||||||
QVector<UtmCoordinate> getMgrsSquaresInternal(const QRectF &rect);
|
|
||||||
|
|
||||||
QStringList getMgrsSurroundingSquares(const QRectF &geoRect, const QSize &offsetMeter);
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> defaultMgrsSquareWithOffsets();
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT void setDefaultMgrsSquares(const QVector<QString> &squares);
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT QVector<UtmCoordinate> defaultMgrsSquares();
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT UtmCoordinate preferedMgrsSquare();
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT bool lonLatAltToGeocentric(double lon, double lat, double altitude, double &xOut, double &yOut, double &zOut);
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT bool geocentric2LonLatAlt(double x, double y, double z, double &lon, double &lat, double &altitude);
|
|
||||||
|
|
||||||
inline double squareDistance(const UtmCoordinate &p1, const UtmCoordinate &p2)
|
|
||||||
{
|
|
||||||
if (p1.zone != p2.zone)
|
|
||||||
{
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return std::nan("");
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
|
||||||
inline double squareDistance(const double lon1, const double lat1, const double lon2, const double lat2)
|
|
||||||
{
|
|
||||||
const auto p1(UtmCoordinate::fromGeographic(lon1, lat1));
|
|
||||||
const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone));
|
|
||||||
return squareDistance(p1, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double squareDistance(const UtmCoordinate &p1, const double lon2, const double lat2)
|
|
||||||
{
|
|
||||||
const auto p2(UtmCoordinate::fromGeographic(lon2, lat2, p1.zone));
|
|
||||||
return squareDistance(p1, p2);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double distance(const UtmCoordinate &p1, const UtmCoordinate &p2)
|
|
||||||
{
|
|
||||||
if (p1.zone != p2.zone)
|
|
||||||
{
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return std::nan("");
|
|
||||||
}
|
|
||||||
return sqrt(squareDistance(p1, 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)
|
|
||||||
{
|
|
||||||
return sqrt(squareDistance(lon1, lat1, lon2, lat2));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline double distance(const UtmCoordinate &p1, const double lon2, const double lat2)
|
|
||||||
{
|
|
||||||
return sqrt(squareDistance(p1, lon2, lat2));
|
|
||||||
}
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT void dumpConversionCounter();
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Forward();
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_MGRS_Reverse();
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Forward();
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_WGS84_Reverse();
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Forward();
|
|
||||||
LTSCOORDTRANS_EXPORT long getConversionCounter_UTMUPS_Reverse();
|
|
||||||
|
|
||||||
LTSCOORDTRANS_EXPORT std::ostream &operator<<(std::ostream &stream, const UtmCoordinate &coord);
|
|
||||||
|
|
||||||
class LTSCOORDTRANS_EXPORT UtmCoordinate3D : public LtsCoordTrans::UtmCoordinate
|
|
||||||
{
|
|
||||||
using BaseClass = LtsCoordTrans::UtmCoordinate;
|
|
||||||
|
|
||||||
public:
|
|
||||||
UtmCoordinate3D() { reset(); }
|
|
||||||
|
|
||||||
explicit UtmCoordinate3D(const LtsCoordTrans::UtmCoordinate &utm2d, double _zValue = std::nan(""))
|
|
||||||
: BaseClass()
|
|
||||||
{
|
|
||||||
zone = utm2d.zone;
|
|
||||||
northp = utm2d.northp;
|
|
||||||
x = utm2d.x;
|
|
||||||
y = utm2d.y;
|
|
||||||
zValue = _zValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
|
||||||
zone = -1;
|
|
||||||
northp = true;
|
|
||||||
|
|
||||||
x = 0.;
|
|
||||||
y = 0.;
|
|
||||||
zValue = std::nan("");
|
|
||||||
}
|
|
||||||
|
|
||||||
double z() const { return zValue; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
double zValue{std::nan("")};
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsCoordTrans
|
|
||||||
-414
@@ -1,414 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_coord_trans_unit_test.h"
|
|
||||||
|
|
||||||
#include "lts_coord_trans.h"
|
|
||||||
|
|
||||||
#include <GeographicLib/Math.hpp>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
#include <QtTest/QTest>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
QTEST_MAIN(coordtrans_test)
|
|
||||||
|
|
||||||
void coordtrans_test::initTestCase()
|
|
||||||
{
|
|
||||||
qDebug("sizeof(UtmCoordinate) = %lu", sizeof(LtsCoordTrans::UtmCoordinate));
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::cleanupTestCase() {}
|
|
||||||
|
|
||||||
void coordtrans_test::testFromGeographic()
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate utm;
|
|
||||||
QPointF lonlat;
|
|
||||||
|
|
||||||
lonlat = QPointF(8.6264954126, 53.1138437183) * LtsCoordTrans::deg2rad();
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("32U MD"));
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
|
||||||
QCOMPARE(utm.mgrs(8), QStringLiteral("32U MD 74999999 84999999"));
|
|
||||||
|
|
||||||
lonlat = QPointF(11.3003696521, 52.8224535191) * LtsCoordTrans::deg2rad();
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("32U PD"));
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
|
||||||
QCOMPARE(utm.mgrs(5), QStringLiteral("32U PD 55000 55000"));
|
|
||||||
|
|
||||||
lonlat = QPointF(54.8821607021, 24.2631973752) * LtsCoordTrans::deg2rad();
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y(), -1);
|
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("40R BM"));
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
|
||||||
QCOMPARE(utm.mgrs(5), QStringLiteral("40R BM 85000 85000"));
|
|
||||||
|
|
||||||
utm = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("40R BM 00000 00000"));
|
|
||||||
QCOMPARE(utm.mgrs(0), QStringLiteral("40Q BM"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testMgrsFromGeographic()
|
|
||||||
{
|
|
||||||
|
|
||||||
QString mgrs;
|
|
||||||
QPointF lonlat;
|
|
||||||
|
|
||||||
lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
|
||||||
mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9);
|
|
||||||
QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000"));
|
|
||||||
|
|
||||||
mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 8, false);
|
|
||||||
QCOMPARE(mgrs, QStringLiteral("32UMD7450000084000000"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testRelativeMetricalOffet_data()
|
|
||||||
{
|
|
||||||
|
|
||||||
QTest::addColumn<QPoint>("offset");
|
|
||||||
QTest::addColumn<QString>("correctMgrs");
|
|
||||||
|
|
||||||
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 3") << QPoint(500, 500) << QStringLiteral("32U QE 00490 00490");
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testRelativeMetricalOffet()
|
|
||||||
{
|
|
||||||
QFETCH(QPoint, offset);
|
|
||||||
QFETCH(QString, correctMgrs);
|
|
||||||
|
|
||||||
const LtsCoordTrans::UtmCoordinate &utmRef = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 99990 99990"));
|
|
||||||
qDebug() << "utmRef = " << utmRef.mgrs();
|
|
||||||
|
|
||||||
{
|
|
||||||
LtsCoordTrans::UtmCoordinate utmRaw;
|
|
||||||
utmRaw.x = utmRef.x + offset.x();
|
|
||||||
utmRaw.y = utmRef.y + offset.y();
|
|
||||||
utmRaw.zone = utmRef.zone;
|
|
||||||
qDebug() << "offset = " << offset << " - utmRaw = " << utmRaw.mgrs();
|
|
||||||
|
|
||||||
QCOMPARE(utmRaw.mgrs(), correctMgrs);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const LtsCoordTrans::UtmCoordinate utmSimple(utmRef.zone, utmRef.x + offset.x(), utmRef.y + offset.y());
|
|
||||||
|
|
||||||
qDebug() << "offset = " << offset << " - utmSimple = " << utmSimple.mgrs();
|
|
||||||
QCOMPARE(utmSimple.mgrs(), correctMgrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF createArea(const QString &base, int xCenter, int yCenter, int width, int height)
|
|
||||||
{
|
|
||||||
|
|
||||||
QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height);
|
|
||||||
LtsCoordTrans::UtmCoordinate utmBase(LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
|
|
||||||
const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top()));
|
|
||||||
const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom()));
|
|
||||||
|
|
||||||
QRectF rect(topLeft, bottomRight);
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testAddMarginToArea()
|
|
||||||
{
|
|
||||||
|
|
||||||
{
|
|
||||||
qDebug() << "Altmark";
|
|
||||||
QRectF area = createArea(QStringLiteral("32U PD 0000000000"), 50000, 10000, 30000, 30000);
|
|
||||||
QRectF area1Increased = LtsCoordTrans::addMarginToArea(area, QSize(5000, 20000));
|
|
||||||
|
|
||||||
qDebug() << "topLeft : " << qSetRealNumberPrecision(15) << area.topLeft() << " - degree:" << area.topLeft() * LtsCoordTrans::rad2deg();
|
|
||||||
qDebug() << "topLeftInc : " << qSetRealNumberPrecision(15) << area1Increased.topLeft() << " - degree:" << area1Increased.topLeft() * LtsCoordTrans::rad2deg();
|
|
||||||
|
|
||||||
qDebug() << "bottomRight : " << qSetRealNumberPrecision(15) << area.bottomRight() << " - degree:" << area.bottomRight() * LtsCoordTrans::rad2deg();
|
|
||||||
qDebug() << "bottomRightInc : " << qSetRealNumberPrecision(15) << area1Increased.bottomRight()
|
|
||||||
<< " - degree:" << area1Increased.bottomRight() * LtsCoordTrans::rad2deg();
|
|
||||||
|
|
||||||
QVERIFY2(area1Increased.topLeft().x() < area.topLeft().x(), "addMarginToArea topLeft X 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().y() > area.bottomRight().y(), "addMarginToArea bottomRight Y failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
qDebug() << "Luxemburg";
|
|
||||||
QRectF area = createArea(QStringLiteral("32U LA 0000000000"), 100, 100, 5000, 5000);
|
|
||||||
QRectF area1Increased = LtsCoordTrans::addMarginToArea(area, QSize(50000, 20000));
|
|
||||||
|
|
||||||
qDebug() << "topLeft : " << qSetRealNumberPrecision(15) << area.topLeft() << " - degree:" << area.topLeft() * LtsCoordTrans::rad2deg();
|
|
||||||
qDebug() << "topLeftInc : " << qSetRealNumberPrecision(15) << area1Increased.topLeft() << " - degree:" << area1Increased.topLeft() * LtsCoordTrans::rad2deg();
|
|
||||||
|
|
||||||
qDebug() << "bottomRight : " << qSetRealNumberPrecision(15) << area.bottomRight() << " - degree:" << area.bottomRight() * LtsCoordTrans::rad2deg();
|
|
||||||
qDebug() << "bottomRightInc : " << qSetRealNumberPrecision(15) << area1Increased.bottomRight()
|
|
||||||
<< " - degree:" << area1Increased.bottomRight() * LtsCoordTrans::rad2deg();
|
|
||||||
|
|
||||||
QVERIFY2(area1Increased.topLeft().x() < area.topLeft().x(), "addMarginToArea topLeft X 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().y() > area.bottomRight().y(), "addMarginToArea bottomRight Y failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testIncreaseRect()
|
|
||||||
{
|
|
||||||
|
|
||||||
QPointF lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9);
|
|
||||||
QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000"));
|
|
||||||
|
|
||||||
const LtsCoordTrans::UtmCoordinate centerPoint = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate topLeftUtm;
|
|
||||||
LtsCoordTrans::UtmCoordinate topLeftUtm2;
|
|
||||||
|
|
||||||
{
|
|
||||||
QPointF topLeftGeo = centerPoint.geographic(-1111, 2222);
|
|
||||||
QPointF bottomRightGeo = centerPoint.geographic(3000, -4000);
|
|
||||||
|
|
||||||
topLeftUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(topLeftGeo);
|
|
||||||
const LtsCoordTrans::UtmCoordinate bottomRightUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(bottomRightGeo);
|
|
||||||
qDebug() << "topLeftUtm: " << topLeftUtm.x << " - " << qSetRealNumberPrecision(15) << topLeftUtm.y;
|
|
||||||
qDebug() << "bottomRightUtm: " << bottomRightUtm.x << " - " << qSetRealNumberPrecision(15) << bottomRightUtm.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
topLeftUtm2.x = centerPoint.x - 1111;
|
|
||||||
topLeftUtm2.y = centerPoint.y + 2222;
|
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate bottomRightUtm2;
|
|
||||||
bottomRightUtm2.x = centerPoint.x + 3000;
|
|
||||||
bottomRightUtm2.y = centerPoint.y - 4000;
|
|
||||||
|
|
||||||
qDebug() << "topLeftUtm2: " << topLeftUtm2.x << " - " << qSetRealNumberPrecision(15) << topLeftUtm2.y;
|
|
||||||
qDebug() << "bottomRightUtm2: " << bottomRightUtm2.x << " - " << qSetRealNumberPrecision(15) << bottomRightUtm2.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVERIFY2(qFuzzyCompare(topLeftUtm.x, topLeftUtm2.x), "testIncreaseRect x failed");
|
|
||||||
QVERIFY2(qFuzzyCompare(topLeftUtm.y, topLeftUtm2.y), "testIncreaseRect y failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testIncreaseRect2()
|
|
||||||
{
|
|
||||||
|
|
||||||
QPointF lonlat = QPointF(8.6191049344, 53.1048309844) * LtsCoordTrans::deg2rad();
|
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(lonlat.x(), lonlat.y(), 9);
|
|
||||||
QCOMPARE(mgrs, QStringLiteral("32U MD 745000000 840000000"));
|
|
||||||
|
|
||||||
QRectF myRect;
|
|
||||||
QRectF myRectIncreased;
|
|
||||||
|
|
||||||
{
|
|
||||||
const LtsCoordTrans::UtmCoordinate centerPoint = LtsCoordTrans::UtmCoordinate::fromGeographic(lonlat.x(), lonlat.y());
|
|
||||||
|
|
||||||
QPointF topLeftGeo = centerPoint.geographic(-3000, 2000);
|
|
||||||
QPointF bottomRightGeo = centerPoint.geographic(3000, -2000);
|
|
||||||
myRect = QRectF(topLeftGeo, bottomRightGeo).normalized();
|
|
||||||
|
|
||||||
qDebug() << "myRect : " << myRect;
|
|
||||||
qDebug() << "myRect center : " << myRect.center();
|
|
||||||
qDebug() << "myRect height : " << myRect.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const QPointF centerGeo = myRect.center();
|
|
||||||
const LtsCoordTrans::UtmCoordinate centerUtm = LtsCoordTrans::UtmCoordinate::fromGeographic(centerGeo);
|
|
||||||
|
|
||||||
QPointF topLeftGeo = centerUtm.geographic(-6000, 4000);
|
|
||||||
QPointF bottomRightGeo = centerUtm.geographic(6000, -4000);
|
|
||||||
|
|
||||||
myRectIncreased = QRectF(topLeftGeo, bottomRightGeo).normalized();
|
|
||||||
|
|
||||||
qDebug() << "myRectIncreased : " << myRectIncreased;
|
|
||||||
qDebug() << "myRectIncreased center: " << myRectIncreased.center();
|
|
||||||
qDebug() << "myRectIncreased height: " << myRectIncreased.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVERIFY2((int)(myRectIncreased.center().x() * 10000) == (int)(myRect.center().x() * 10000), "testIncreaseRect2 centerX 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.height() > myRect.height(), "testIncreaseRect2 height failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testGeographicFromMgrs()
|
|
||||||
{
|
|
||||||
|
|
||||||
QString mgrs(QStringLiteral("32UPD7654398765"));
|
|
||||||
|
|
||||||
QPointF geographic = LtsCoordTrans::geographicFromMgrs(mgrs);
|
|
||||||
QCOMPARE(geographic, QPointF(11.6436815550, 53.2088411454) * LtsCoordTrans::deg2rad());
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testMgrsSquares()
|
|
||||||
{
|
|
||||||
|
|
||||||
checkArea(QStringLiteral("32U PD 0000000000"), 50000, 10000, 30000, 30000, {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"),
|
|
||||||
89999,
|
|
||||||
89999,
|
|
||||||
21000,
|
|
||||||
21000,
|
|
||||||
{QStringLiteral("32U MD"), QStringLiteral("32U ME"), QStringLiteral("32U ND"), QStringLiteral("32U NE")});
|
|
||||||
|
|
||||||
checkArea(QStringLiteral("39Q XG 0000000000"), 40000, 35000, 60000, 70000, {QStringLiteral("39Q XG"), QStringLiteral("39R XG")});
|
|
||||||
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,
|
|
||||||
96760,
|
|
||||||
30000,
|
|
||||||
30000,
|
|
||||||
{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,
|
|
||||||
{
|
|
||||||
QStringLiteral("32U LA"),
|
|
||||||
});
|
|
||||||
|
|
||||||
checkArea(QStringLiteral("32U LA 0000000000"),
|
|
||||||
100,
|
|
||||||
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,
|
|
||||||
{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,
|
|
||||||
{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, int height)
|
|
||||||
{
|
|
||||||
|
|
||||||
QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height);
|
|
||||||
LtsCoordTrans::UtmCoordinate utmBase(LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
|
|
||||||
const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top()));
|
|
||||||
const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom()));
|
|
||||||
|
|
||||||
const auto squares = LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), false, false);
|
|
||||||
|
|
||||||
QStringList src;
|
|
||||||
src.reserve(squares.size());
|
|
||||||
for (const auto &utm : squares)
|
|
||||||
src += utm.mgrs(0);
|
|
||||||
src.sort();
|
|
||||||
|
|
||||||
return squares;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::testMgrsSquaresWithSurrounding()
|
|
||||||
{
|
|
||||||
|
|
||||||
int initialSize = 5000;
|
|
||||||
|
|
||||||
QVector<LtsCoordTrans::UtmCoordinate> squares1 = checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, initialSize, initialSize);
|
|
||||||
|
|
||||||
QVERIFY2(squares1.size() == 1, "checkAreaGetMgrsSquares failed");
|
|
||||||
|
|
||||||
int biggerSize = initialSize + (1 * 110000);
|
|
||||||
QVector<LtsCoordTrans::UtmCoordinate> squares9 = checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, biggerSize, biggerSize);
|
|
||||||
|
|
||||||
QVERIFY2(squares9.size() == 9, "checkAreaGetMgrsSquares biggerSize failed");
|
|
||||||
|
|
||||||
int muchBiggerSize = initialSize + (3 * 110000);
|
|
||||||
QVector<LtsCoordTrans::UtmCoordinate> square33 = checkAreaGetMgrsSquares(QStringLiteral("32U NC 0000000000"), 50000, 50000, muchBiggerSize, muchBiggerSize);
|
|
||||||
|
|
||||||
QVERIFY2(square33.size() == 33, "checkAreaGetMgrsSquares muchBiggerSize failed");
|
|
||||||
|
|
||||||
QStringList string1;
|
|
||||||
string1.reserve(squares1.size());
|
|
||||||
for (const LtsCoordTrans::UtmCoordinate &item : std::as_const(squares1))
|
|
||||||
string1.append(item.mgrs(0));
|
|
||||||
|
|
||||||
QStringList string9;
|
|
||||||
string9.reserve(squares9.size());
|
|
||||||
for (const LtsCoordTrans::UtmCoordinate &item : std::as_const(squares9))
|
|
||||||
string9.append(item.mgrs(0));
|
|
||||||
|
|
||||||
QStringList string33;
|
|
||||||
string33.reserve(square33.size());
|
|
||||||
for (const LtsCoordTrans::UtmCoordinate &item : std::as_const(square33))
|
|
||||||
string33.append(item.mgrs(0));
|
|
||||||
|
|
||||||
{
|
|
||||||
QStringList surroundingStrings;
|
|
||||||
surroundingStrings.reserve(squares9.size());
|
|
||||||
for (const QString &str : std::as_const(string9))
|
|
||||||
if (!string1.contains(str))
|
|
||||||
surroundingStrings.append(str);
|
|
||||||
|
|
||||||
QVERIFY2(surroundingStrings.size() == 8, "checkAreaGetMgrsSquares squaresDiff failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
QStringList surroundingStrings;
|
|
||||||
surroundingStrings.reserve(string33.size());
|
|
||||||
for (const QString &str : std::as_const(string33))
|
|
||||||
if (!string1.contains(str))
|
|
||||||
surroundingStrings.append(str);
|
|
||||||
|
|
||||||
QVERIFY2(surroundingStrings.size() == 32, "checkAreaGetMgrsSquares squaresDiff failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void coordtrans_test::checkArea(const QString &base, int xCenter, int yCenter, int width, int height, const QStringList &coords)
|
|
||||||
{
|
|
||||||
qDebug() << "checkArea : base: " << base;
|
|
||||||
QRectF areaRect = QRectF(xCenter - width / 2, yCenter - height / 2, width, height);
|
|
||||||
LtsCoordTrans::UtmCoordinate utmBase(LtsCoordTrans::UtmCoordinate::fromGeographic(LtsCoordTrans::geographicFromMgrs(base)));
|
|
||||||
const QPointF topLeft(utmBase.geographic(areaRect.left(), areaRect.top()));
|
|
||||||
const QPointF bottomRight(utmBase.geographic(areaRect.right(), areaRect.bottom()));
|
|
||||||
qDebug() << "TopLeft: " << topLeft * LtsCoordTrans::rad2deg();
|
|
||||||
qDebug() << "BottomRight: " << bottomRight * LtsCoordTrans::rad2deg();
|
|
||||||
|
|
||||||
const auto squares = LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), false, false);
|
|
||||||
|
|
||||||
QStringList src;
|
|
||||||
src.reserve(squares.size());
|
|
||||||
for (const auto &utm : squares)
|
|
||||||
src += utm.mgrs(0);
|
|
||||||
src.sort();
|
|
||||||
qDebug() << "src: '" << src << "' expected: '" << coords << "'";
|
|
||||||
QCOMPARE(src, coords);
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
|
|
||||||
class coordtrans_test : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private Q_SLOTS:
|
|
||||||
void initTestCase();
|
|
||||||
void cleanupTestCase();
|
|
||||||
void testFromGeographic();
|
|
||||||
void testMgrsFromGeographic();
|
|
||||||
|
|
||||||
void testRelativeMetricalOffet_data();
|
|
||||||
void testRelativeMetricalOffet();
|
|
||||||
|
|
||||||
void testAddMarginToArea();
|
|
||||||
void testIncreaseRect();
|
|
||||||
void testIncreaseRect2();
|
|
||||||
|
|
||||||
void testGeographicFromMgrs();
|
|
||||||
void testMgrsSquares();
|
|
||||||
|
|
||||||
void testMgrsSquaresWithSurrounding();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void checkArea(const QString &base, int xCenter, int yCenter, int width, int height, const QStringList &coords);
|
|
||||||
};
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_coord_widget.h"
|
|
||||||
|
|
||||||
#include "lts_coord_widget_p.h"
|
|
||||||
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <QtWidgets/QToolButton>
|
|
||||||
|
|
||||||
namespace LtsCoordWidget
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsCoordWidget::LtsCoordWidget(DisplayType dt, QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, m_displayType(dt)
|
|
||||||
{
|
|
||||||
setFocusPolicy(Qt::StrongFocus);
|
|
||||||
rebuildUi();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setCoordinate(const QPointF &geoCoord, bool bUseAsDefaultValue)
|
|
||||||
{
|
|
||||||
if (m_coordinate != geoCoord)
|
|
||||||
emit coordinateChanged(geoCoord);
|
|
||||||
if (bUseAsDefaultValue)
|
|
||||||
m_defaultCoordinate = geoCoord;
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
m_inputWidgetHandler->setCoordinate(geoCoord);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::clear()
|
|
||||||
{
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
m_inputWidgetHandler->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setCoordinate(double lon, double lat, bool bUseAsDefaultValue)
|
|
||||||
{
|
|
||||||
setCoordinate(QPointF(lon, lat), bUseAsDefaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF LtsCoordWidget::coordinate() const
|
|
||||||
{
|
|
||||||
if (!m_inputWidgetHandler)
|
|
||||||
return QPointF();
|
|
||||||
return m_inputWidgetHandler->coordinate();
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsCoordWidget::DisplayType LtsCoordWidget::displayType() const
|
|
||||||
{
|
|
||||||
return m_displayType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setDisplayType(LtsCoordWidget::DisplayType dt)
|
|
||||||
{
|
|
||||||
if (m_displayType == dt)
|
|
||||||
return;
|
|
||||||
m_displayType = dt;
|
|
||||||
rebuildUi();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCoordWidget::withResetButton() const
|
|
||||||
{
|
|
||||||
return m_bWithResetButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setWithResetButton(bool bWith)
|
|
||||||
{
|
|
||||||
if (m_bWithResetButton == bWith)
|
|
||||||
return;
|
|
||||||
m_bWithResetButton = bWith;
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
m_inputWidgetHandler->resetButton()->setVisible(m_bWithResetButton);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCoordWidget::showToolTip() const
|
|
||||||
{
|
|
||||||
return m_bShowToolTip;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setShowToolTip(bool bShow)
|
|
||||||
{
|
|
||||||
if (m_bShowToolTip == bShow)
|
|
||||||
return;
|
|
||||||
m_bShowToolTip = bShow;
|
|
||||||
|
|
||||||
updateToolTip();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCoordWidget::mgrsSquareEditable() const
|
|
||||||
{
|
|
||||||
return m_bMgrsSquareEditable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setMgrsSquareEditable(bool bEditable)
|
|
||||||
{
|
|
||||||
if (m_bMgrsSquareEditable == bEditable)
|
|
||||||
return;
|
|
||||||
m_bMgrsSquareEditable = bEditable;
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
m_inputWidgetHandler->setSquaresEditable(bEditable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setWithSurroundingMgrsSquares(bool bEnable)
|
|
||||||
{
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
m_inputWidgetHandler->setWithSurroundingSquare(bEnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords)
|
|
||||||
{
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
m_inputWidgetHandler->setMgrsSquares(geoCoords);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsCoordWidget::event(QEvent *event)
|
|
||||||
{
|
|
||||||
if (event->type() == QEvent::ToolTip)
|
|
||||||
updateToolTip();
|
|
||||||
return QWidget::event(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::rebuildUi()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (m_inputWidgetHandler)
|
|
||||||
{
|
|
||||||
m_inputWidgetHandler->cleanup();
|
|
||||||
delete m_inputWidgetHandler;
|
|
||||||
delete layout();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_displayType)
|
|
||||||
{
|
|
||||||
case DisplayType::MGRS5:
|
|
||||||
m_inputWidgetHandler = new MgrsEdit(5, this);
|
|
||||||
break;
|
|
||||||
case DisplayType::MGRS7:
|
|
||||||
m_inputWidgetHandler = new MgrsEdit(7, this);
|
|
||||||
break;
|
|
||||||
case DisplayType::UTM:
|
|
||||||
|
|
||||||
qt_assert("DisplayType::UTM not yet implemented", __FILE__, __LINE__);
|
|
||||||
break;
|
|
||||||
case DisplayType::WGS84:
|
|
||||||
m_inputWidgetHandler = new Wgs84Edit(this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!m_inputWidgetHandler)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_inputWidgetHandler->setSquaresEditable(m_bMgrsSquareEditable);
|
|
||||||
m_inputWidgetHandler->resetButton()->setVisible(m_bWithResetButton);
|
|
||||||
connect(m_inputWidgetHandler->resetButton(), &QToolButton::clicked, this, &LtsCoordWidget::onResetToDefaultCoordinate);
|
|
||||||
connect(m_inputWidgetHandler, &LtsCoordInputWidgetHandler::coordinateChanged, this, &LtsCoordWidget::coordinateChanged);
|
|
||||||
connect(m_inputWidgetHandler, &LtsCoordInputWidgetHandler::invalidCoordinate, this, &LtsCoordWidget::invalidCoordinate);
|
|
||||||
if (!m_defaultCoordinate.isNull())
|
|
||||||
m_inputWidgetHandler->setCoordinate(m_defaultCoordinate);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::updateToolTip()
|
|
||||||
{
|
|
||||||
QString tt;
|
|
||||||
if (m_bShowToolTip)
|
|
||||||
{
|
|
||||||
const QPointF p(coordinate());
|
|
||||||
if (!p.isNull())
|
|
||||||
{
|
|
||||||
const QString mgrs = LtsCoordTrans::mgrsFromGeographic(p.x(), p.y());
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setToolTip(tt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsCoordWidget::onResetToDefaultCoordinate()
|
|
||||||
{
|
|
||||||
if (!m_inputWidgetHandler)
|
|
||||||
return;
|
|
||||||
if (m_defaultCoordinate.isNull())
|
|
||||||
m_inputWidgetHandler->clear();
|
|
||||||
m_inputWidgetHandler->setCoordinate(m_defaultCoordinate);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsCoordWidget
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <LtsCoordTrans/ltscoordwidget_export.h>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
class QToolButton;
|
|
||||||
|
|
||||||
namespace LtsCoordWidget
|
|
||||||
{
|
|
||||||
class LtsCoordInputWidgetHandler;
|
|
||||||
|
|
||||||
class LTSCOORDWIDGET_EXPORT LtsCoordWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum class DisplayType
|
|
||||||
{
|
|
||||||
MGRS5,
|
|
||||||
MGRS7,
|
|
||||||
UTM,
|
|
||||||
WGS84,
|
|
||||||
MGRS = DisplayType::MGRS5
|
|
||||||
};
|
|
||||||
Q_ENUM(DisplayType)
|
|
||||||
Q_PROPERTY(DisplayType displayType READ displayType WRITE setDisplayType)
|
|
||||||
Q_PROPERTY(bool withResetButton READ withResetButton WRITE setWithResetButton)
|
|
||||||
Q_PROPERTY(bool showToolTip READ showToolTip WRITE setShowToolTip)
|
|
||||||
Q_PROPERTY(bool mgrsSquareEditable READ mgrsSquareEditable WRITE setMgrsSquareEditable)
|
|
||||||
|
|
||||||
explicit LtsCoordWidget(QWidget *parent = nullptr)
|
|
||||||
: LtsCoordWidget(LtsCoordWidget::DisplayType::MGRS, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit LtsCoordWidget(DisplayType dt, QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
QPointF coordinate() const;
|
|
||||||
DisplayType displayType() const;
|
|
||||||
bool withResetButton() const;
|
|
||||||
bool showToolTip() const;
|
|
||||||
bool mgrsSquareEditable() const;
|
|
||||||
bool event(QEvent *event) override;
|
|
||||||
public Q_SLOTS:
|
|
||||||
|
|
||||||
void setCoordinate(const QPointF &geoCoord, bool bUseAsDefaultValue = true);
|
|
||||||
void setCoordinate(double lon, double lat, bool bUseAsDefaultValue = true);
|
|
||||||
void setDisplayType(LtsCoordWidget::DisplayType dt);
|
|
||||||
void setWithResetButton(bool bWith);
|
|
||||||
void setShowToolTip(bool bShow);
|
|
||||||
void setMgrsSquareEditable(bool bEditable);
|
|
||||||
void setWithSurroundingMgrsSquares(bool bEnable);
|
|
||||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void coordinateChanged(const QPointF &newGeoCoord);
|
|
||||||
void invalidCoordinate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void rebuildUi();
|
|
||||||
void updateToolTip();
|
|
||||||
private Q_SLOTS:
|
|
||||||
void onResetToDefaultCoordinate();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_bWithResetButton = false;
|
|
||||||
bool m_bShowToolTip = true;
|
|
||||||
bool m_bMgrsSquareEditable = false;
|
|
||||||
LtsCoordWidget::DisplayType m_displayType = LtsCoordWidget::DisplayType::MGRS;
|
|
||||||
LtsCoordInputWidgetHandler *m_inputWidgetHandler = nullptr;
|
|
||||||
QPointF m_coordinate;
|
|
||||||
QPointF m_defaultCoordinate;
|
|
||||||
};
|
|
||||||
} // namespace LtsCoordWidget
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Mgrs</class>
|
|
||||||
<widget class="QWidget" name="Mgrs">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>322</width>
|
|
||||||
<height>32</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="cbxZone"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="leEast">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Pos X</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="leNorth">
|
|
||||||
<property name="toolTip">
|
|
||||||
<string>Pos Y</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="tbReset">
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:/style/arrow_back.svg</normaloff>:/style/arrow_back.svg</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,304 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_coord_widget_p.h"
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace LtsCoordWidget
|
|
||||||
{
|
|
||||||
|
|
||||||
void LtsCoordInputWidgetHandler::onCoordinateDataChanged()
|
|
||||||
{
|
|
||||||
const QPointF coord(coordinate());
|
|
||||||
if (coord.isNull())
|
|
||||||
{
|
|
||||||
emit invalidCoordinate();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
emit coordinateChanged(coord);
|
|
||||||
}
|
|
||||||
|
|
||||||
MgrsEdit::MgrsEdit(int precision, QWidget *widget)
|
|
||||||
: LtsCoordInputWidgetHandler(widget)
|
|
||||||
, m_precision(precision)
|
|
||||||
, m_ui(new Ui::Mgrs)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(widget);
|
|
||||||
|
|
||||||
if (m_precision < 0)
|
|
||||||
m_precision = 0;
|
|
||||||
if (m_precision > 11)
|
|
||||||
m_precision = 11;
|
|
||||||
const int upperLimit = pow(10, m_precision) - 1;
|
|
||||||
m_ui->leEast->setValidator(new QIntValidator(0, upperLimit, m_ui->leEast));
|
|
||||||
m_ui->leNorth->setValidator(new QIntValidator(0, upperLimit, m_ui->leNorth));
|
|
||||||
setDefaultMgrsSquares();
|
|
||||||
|
|
||||||
connect(m_ui->cbxZone, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MgrsEdit::onCoordinateDataChanged);
|
|
||||||
connect(m_ui->leEast, &QLineEdit::editingFinished, this, &MgrsEdit::onCoordinateDataChanged);
|
|
||||||
connect(m_ui->leNorth, &QLineEdit::editingFinished, this, &MgrsEdit::onCoordinateDataChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
MgrsEdit::~MgrsEdit()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MgrsEdit::isValid()
|
|
||||||
{
|
|
||||||
|
|
||||||
const QString &east = m_ui->leEast->text();
|
|
||||||
if (east.size() != m_precision)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const QString &north = m_ui->leNorth->text();
|
|
||||||
if (north.size() != m_precision)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_ui->cbxZone->currentIndex() < 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_ui->cbxZone->currentText().isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::setCoordinate(const QPointF &geoCoord)
|
|
||||||
{
|
|
||||||
const QString mgrsString = LtsCoordTrans::mgrsFromGeographic(geoCoord.x(), geoCoord.y(), m_precision, false);
|
|
||||||
if (mgrsString.isEmpty())
|
|
||||||
{
|
|
||||||
m_ui->leEast->clear();
|
|
||||||
m_ui->leNorth->clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ui->leEast->setText(QString());
|
|
||||||
m_ui->leNorth->setText(QString());
|
|
||||||
|
|
||||||
const QString mgrsSquare = mgrsString.left(3) + QLatin1Char(' ') + mgrsString.mid(3, 2);
|
|
||||||
QString east = mgrsString.mid(5, m_precision);
|
|
||||||
QString north = mgrsString.mid(5 + m_precision, m_precision);
|
|
||||||
int idx = m_ui->cbxZone->findText(mgrsSquare);
|
|
||||||
if (idx < 0)
|
|
||||||
{
|
|
||||||
addMgrsSquare(mgrsSquare);
|
|
||||||
idx = m_ui->cbxZone->findText(mgrsSquare);
|
|
||||||
}
|
|
||||||
m_ui->cbxZone->setCurrentIndex(idx);
|
|
||||||
m_ui->leEast->setText(east);
|
|
||||||
m_ui->leNorth->setText(north);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline QString getMgrsCoord(QLineEdit *le, int prec)
|
|
||||||
{
|
|
||||||
QString ret = le->text();
|
|
||||||
if (ret.isEmpty())
|
|
||||||
return ret;
|
|
||||||
while (ret.size() < prec)
|
|
||||||
ret += QLatin1Char('0');
|
|
||||||
le->setText(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF MgrsEdit::coordinate() const
|
|
||||||
{
|
|
||||||
const QString east = getMgrsCoord(m_ui->leEast, m_precision);
|
|
||||||
const QString north = getMgrsCoord(m_ui->leNorth, m_precision);
|
|
||||||
if (east.isEmpty() || north.isEmpty() || m_ui->cbxZone->currentIndex() < 0)
|
|
||||||
return QPointF();
|
|
||||||
|
|
||||||
const QString mgrsString(m_ui->cbxZone->currentText() + east + north);
|
|
||||||
return LtsCoordTrans::geographicFromMgrs(mgrsString);
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton *MgrsEdit::resetButton()
|
|
||||||
{
|
|
||||||
return m_ui->tbReset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::cleanup()
|
|
||||||
{
|
|
||||||
|
|
||||||
delete m_ui->horizontalLayout;
|
|
||||||
delete m_ui->cbxZone;
|
|
||||||
delete m_ui->leEast;
|
|
||||||
delete m_ui->leNorth;
|
|
||||||
delete m_ui->tbReset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::clear()
|
|
||||||
{
|
|
||||||
m_ui->cbxZone->clear();
|
|
||||||
m_ui->leEast->clear();
|
|
||||||
m_ui->leNorth->clear();
|
|
||||||
setDefaultMgrsSquares();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::setSquaresEditable(bool bEditable)
|
|
||||||
{
|
|
||||||
m_ui->cbxZone->setEditable(bEditable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::setWithSurroundingSquare(bool bEnabled)
|
|
||||||
{
|
|
||||||
m_withMgrsSquareOffset = bEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QStringList defaultMgrsSquares()
|
|
||||||
{
|
|
||||||
const QVector<LtsCoordTrans::UtmCoordinate> squares(LtsCoordTrans::defaultMgrsSquares());
|
|
||||||
QStringList sl;
|
|
||||||
sl.reserve(squares.size());
|
|
||||||
for (const LtsCoordTrans::UtmCoordinate &c : squares)
|
|
||||||
sl += c.mgrs(0);
|
|
||||||
std::sort(sl.begin(), sl.end());
|
|
||||||
return sl;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString preferedMgrsSquare()
|
|
||||||
{
|
|
||||||
const LtsCoordTrans::UtmCoordinate c(LtsCoordTrans::preferedMgrsSquare());
|
|
||||||
return c.mgrs(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::setDefaultMgrsSquares()
|
|
||||||
{
|
|
||||||
m_ui->cbxZone->addItems(defaultMgrsSquares());
|
|
||||||
m_ui->cbxZone->setCurrentIndex(m_ui->cbxZone->findText(preferedMgrsSquare()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::addMgrsSquare(const QString &newMgrsSquare)
|
|
||||||
{
|
|
||||||
QStringList sl = defaultMgrsSquares();
|
|
||||||
sl += newMgrsSquare;
|
|
||||||
if (m_withMgrsSquareOffset)
|
|
||||||
{
|
|
||||||
QStringList squares = utmCoordsToList(LtsCoordTrans::defaultMgrsSquareWithOffsets());
|
|
||||||
|
|
||||||
for (const auto &sq : std::as_const(squares))
|
|
||||||
if (!sl.contains(sq))
|
|
||||||
sl.append(sq);
|
|
||||||
}
|
|
||||||
std::sort(sl.begin(), sl.end());
|
|
||||||
m_ui->cbxZone->clear();
|
|
||||||
m_ui->cbxZone->addItems(sl);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList MgrsEdit::utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate> &coords)
|
|
||||||
{
|
|
||||||
QStringList list;
|
|
||||||
list.reserve(coords.count());
|
|
||||||
for (const auto &utm : coords)
|
|
||||||
list.append(utm.mgrs(0));
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MgrsEdit::setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords)
|
|
||||||
{
|
|
||||||
QStringList sl = utmCoordsToList(geoCoords);
|
|
||||||
if (sl.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::sort(sl.begin(), sl.end());
|
|
||||||
m_ui->cbxZone->clear();
|
|
||||||
m_ui->cbxZone->addItems(sl);
|
|
||||||
}
|
|
||||||
|
|
||||||
Wgs84Edit::Wgs84Edit(QWidget *widget)
|
|
||||||
: LtsCoordInputWidgetHandler(widget)
|
|
||||||
, m_ui(new Ui::Wgs84)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(widget);
|
|
||||||
|
|
||||||
DoubleValidator *v = new DoubleValidator(-180, 180, 9, m_ui->leLon);
|
|
||||||
v->setNotation(QDoubleValidator::StandardNotation);
|
|
||||||
m_ui->leLon->setValidator(v);
|
|
||||||
|
|
||||||
v = new DoubleValidator(-180, 180, 9, m_ui->leLat);
|
|
||||||
v->setNotation(QDoubleValidator::StandardNotation);
|
|
||||||
m_ui->leLat->setValidator(v);
|
|
||||||
|
|
||||||
connect(m_ui->leLon, &QLineEdit::editingFinished, this, &Wgs84Edit::onCoordinateDataChanged);
|
|
||||||
connect(m_ui->leLat, &QLineEdit::editingFinished, this, &Wgs84Edit::onCoordinateDataChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
Wgs84Edit::~Wgs84Edit()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Wgs84Edit::isValid()
|
|
||||||
{
|
|
||||||
|
|
||||||
return (!m_ui->leLon->text().isEmpty()) && (!m_ui->leLat->text().isEmpty());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Wgs84Edit::setCoordinate(const QPointF &geoCoord)
|
|
||||||
{
|
|
||||||
const QPointF coord(geoCoord * LtsCoordTrans::rad2deg());
|
|
||||||
const QLocale l;
|
|
||||||
m_ui->leLon->setText(l.toString(coord.x(), 'f', 9));
|
|
||||||
m_ui->leLat->setText(l.toString(coord.y(), 'f', 9));
|
|
||||||
}
|
|
||||||
|
|
||||||
QPointF Wgs84Edit::coordinate() const
|
|
||||||
{
|
|
||||||
QPointF ret;
|
|
||||||
const QLocale l;
|
|
||||||
|
|
||||||
const QString lonStr = m_ui->leLon->text().remove(l.groupSeparator());
|
|
||||||
const QString latStr = m_ui->leLat->text().remove(l.groupSeparator());
|
|
||||||
if (lonStr.isEmpty() || latStr.isEmpty())
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret.rx() = l.toDouble(lonStr);
|
|
||||||
ret.ry() = l.toDouble(latStr);
|
|
||||||
|
|
||||||
return ret * LtsCoordTrans::deg2rad();
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton *Wgs84Edit::resetButton()
|
|
||||||
{
|
|
||||||
return m_ui->tbReset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Wgs84Edit::cleanup()
|
|
||||||
{
|
|
||||||
|
|
||||||
delete m_ui->horizontalLayout;
|
|
||||||
delete m_ui->leLon;
|
|
||||||
delete m_ui->leLat;
|
|
||||||
delete m_ui->tbReset;
|
|
||||||
delete m_ui->lblLon;
|
|
||||||
delete m_ui->lblLat;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Wgs84Edit::clear()
|
|
||||||
{
|
|
||||||
m_ui->leLon->clear();
|
|
||||||
m_ui->leLat->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
DoubleValidator::DoubleValidator(double bottom, double top, int decimals, QObject *parent)
|
|
||||||
: QDoubleValidator(bottom, top, decimals, parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
QValidator::State DoubleValidator::validate(QString &input, int &pos) const
|
|
||||||
{
|
|
||||||
const QValidator::State ret = QDoubleValidator::validate(input, pos);
|
|
||||||
if (ret != QValidator::Acceptable)
|
|
||||||
return ret;
|
|
||||||
QLocale l;
|
|
||||||
const QChar gs = l.groupSeparator().at(0);
|
|
||||||
if (gs.isNull())
|
|
||||||
return ret;
|
|
||||||
if (input.contains(gs))
|
|
||||||
return QValidator::Invalid;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsCoordWidget
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ui_lts_coord_widget_mgrs.h"
|
|
||||||
#include "ui_lts_coord_widget_wgs84.h"
|
|
||||||
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <QtWidgets/QComboBox>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtWidgets/QVBoxLayout>
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
namespace LtsCoordWidget
|
|
||||||
{
|
|
||||||
class LtsCoordInputWidgetHandler : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit LtsCoordInputWidgetHandler(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool isValid() = 0;
|
|
||||||
virtual void setCoordinate(const QPointF &geoCoord) = 0;
|
|
||||||
virtual QPointF coordinate() const = 0;
|
|
||||||
virtual QToolButton *resetButton() = 0;
|
|
||||||
virtual void cleanup() = 0;
|
|
||||||
virtual void clear() = 0;
|
|
||||||
virtual void setSquaresEditable(bool bEditable) = 0;
|
|
||||||
virtual void setWithSurroundingSquare(bool bEnabled) = 0;
|
|
||||||
virtual void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords) = 0;
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onCoordinateDataChanged();
|
|
||||||
Q_SIGNALS:
|
|
||||||
void coordinateChanged(const QPointF &newGeoCoord);
|
|
||||||
void invalidCoordinate();
|
|
||||||
};
|
|
||||||
|
|
||||||
class MgrsEdit final : public LtsCoordInputWidgetHandler
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit MgrsEdit(int precision, QWidget *widget);
|
|
||||||
~MgrsEdit();
|
|
||||||
|
|
||||||
bool isValid() override;
|
|
||||||
void setCoordinate(const QPointF &geoCoord) override;
|
|
||||||
QPointF coordinate() const override;
|
|
||||||
QToolButton *resetButton() override;
|
|
||||||
void cleanup() override;
|
|
||||||
void clear() override;
|
|
||||||
void setSquaresEditable(bool bEditable) override;
|
|
||||||
void setWithSurroundingSquare(bool bEnabled) override;
|
|
||||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setDefaultMgrsSquares();
|
|
||||||
void addMgrsSquare(const QString &newMgrsSquare);
|
|
||||||
QStringList utmCoordsToList(const QVector<LtsCoordTrans::UtmCoordinate> &coords);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_precision;
|
|
||||||
bool m_withMgrsSquareOffset = false;
|
|
||||||
Ui::Mgrs *m_ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Wgs84Edit final : public LtsCoordInputWidgetHandler
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Wgs84Edit(QWidget *widget);
|
|
||||||
~Wgs84Edit();
|
|
||||||
|
|
||||||
bool isValid() override;
|
|
||||||
void setCoordinate(const QPointF &geoCoord) override;
|
|
||||||
QPointF coordinate() const override;
|
|
||||||
QToolButton *resetButton() override;
|
|
||||||
void cleanup() override;
|
|
||||||
void clear() override;
|
|
||||||
|
|
||||||
void setSquaresEditable(bool bEditable) override { Q_UNUSED(bEditable); }
|
|
||||||
|
|
||||||
void setWithSurroundingSquare(bool bEnabled) override { Q_UNUSED(bEnabled); }
|
|
||||||
|
|
||||||
void setMgrsSquares(const QVector<LtsCoordTrans::UtmCoordinate> &geoCoords) override { Q_UNUSED(geoCoords); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::Wgs84 *m_ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DoubleValidator final : public QDoubleValidator
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
DoubleValidator(double bottom, double top, int decimals, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
QValidator::State validate(QString &input, int &pos) const override;
|
|
||||||
};
|
|
||||||
} // namespace LtsCoordWidget
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_coord_widget.h"
|
|
||||||
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <QtWidgets/QApplication>
|
|
||||||
#include <QtWidgets/QDialog>
|
|
||||||
#include <QtWidgets/QLabel>
|
|
||||||
#include <QtWidgets/QPushButton>
|
|
||||||
#include <QtWidgets/QVBoxLayout>
|
|
||||||
|
|
||||||
static void updateLabel(const QPointF &coord, QLabel *lbl, int prec)
|
|
||||||
{
|
|
||||||
QString mgrs = LtsCoordTrans::mgrsFromGeographic(coord.x(), coord.y(), prec);
|
|
||||||
QString str =
|
|
||||||
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);
|
|
||||||
lbl->setText(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
LtsCoordTrans::UtmCoordinate base(LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32UMD00")));
|
|
||||||
QPointF topLeft(base.geographic(+50000, -50000));
|
|
||||||
QPointF bottomRight(base.geographic(-50000, 50000));
|
|
||||||
LtsCoordTrans::getMgrsSquares(QRectF(topLeft, bottomRight), true, true);
|
|
||||||
|
|
||||||
QDialog *dialog(new QDialog);
|
|
||||||
QVBoxLayout *lay(new QVBoxLayout(dialog));
|
|
||||||
|
|
||||||
const QPointF defCoord(QPointF(53.0, 8.0) * LtsCoordTrans::deg2rad());
|
|
||||||
|
|
||||||
LtsCoordWidget::LtsCoordWidget *wMgrs5(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS, dialog));
|
|
||||||
wMgrs5->setWithResetButton(true);
|
|
||||||
wMgrs5->setCoordinate(defCoord, true);
|
|
||||||
lay->addWidget(wMgrs5);
|
|
||||||
QLabel *lbl5(new QLabel(dialog));
|
|
||||||
lay->addWidget(lbl5);
|
|
||||||
QObject::connect(wMgrs5, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, lbl5, [lbl5](const QPointF &coord) { updateLabel(coord, lbl5, 5); });
|
|
||||||
|
|
||||||
LtsCoordWidget::LtsCoordWidget *wMgrs7(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7, dialog));
|
|
||||||
wMgrs7->setWithResetButton(true);
|
|
||||||
wMgrs7->setCoordinate(defCoord, true);
|
|
||||||
lay->addWidget(wMgrs7);
|
|
||||||
QLabel *lbl7(new QLabel(dialog));
|
|
||||||
lay->addWidget(lbl7);
|
|
||||||
QObject::connect(wMgrs7, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, wMgrs7, [lbl7](const QPointF &coord) { updateLabel(coord, lbl7, 7); });
|
|
||||||
|
|
||||||
LtsCoordWidget::LtsCoordWidget *w84(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84, dialog));
|
|
||||||
w84->setWithResetButton(true);
|
|
||||||
w84->setCoordinate(defCoord, true);
|
|
||||||
lay->addWidget(w84);
|
|
||||||
QLabel *lbl84(new QLabel(dialog));
|
|
||||||
lay->addWidget(lbl84);
|
|
||||||
QObject::connect(w84, &LtsCoordWidget::LtsCoordWidget::coordinateChanged, w84, [lbl84](const QPointF &coord) { updateLabel(coord, lbl84, 11); });
|
|
||||||
|
|
||||||
QHBoxLayout *hLay = new QHBoxLayout;
|
|
||||||
lay->addLayout(hLay);
|
|
||||||
LtsCoordWidget::LtsCoordWidget *wChange(new LtsCoordWidget::LtsCoordWidget(LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84, dialog));
|
|
||||||
wChange->setWithResetButton(true);
|
|
||||||
wChange->setCoordinate(defCoord, true);
|
|
||||||
hLay->addWidget(wChange);
|
|
||||||
QPushButton *pbReset(new QPushButton(QStringLiteral("With Reset"), dialog));
|
|
||||||
hLay->addWidget(pbReset);
|
|
||||||
QObject::connect(pbReset, &QPushButton::clicked, wChange, [wChange]() { wChange->setWithResetButton(!wChange->withResetButton()); });
|
|
||||||
QPushButton *pbNext(new QPushButton(QStringLiteral("Next Type"), dialog));
|
|
||||||
hLay->addWidget(pbNext);
|
|
||||||
QObject::connect(pbNext,
|
|
||||||
&QPushButton::clicked,
|
|
||||||
wChange,
|
|
||||||
[wChange]()
|
|
||||||
{
|
|
||||||
LtsCoordWidget::LtsCoordWidget::DisplayType dt = wChange->displayType();
|
|
||||||
switch (dt)
|
|
||||||
{
|
|
||||||
case LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS5:
|
|
||||||
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7;
|
|
||||||
break;
|
|
||||||
case LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS7:
|
|
||||||
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84;
|
|
||||||
break;
|
|
||||||
case LtsCoordWidget::LtsCoordWidget::DisplayType::WGS84:
|
|
||||||
dt = LtsCoordWidget::LtsCoordWidget::DisplayType::MGRS5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
wChange->setDisplayType(dt);
|
|
||||||
});
|
|
||||||
|
|
||||||
QPushButton *pb(new QPushButton(QStringLiteral("Quit"), dialog));
|
|
||||||
lay->addWidget(pb);
|
|
||||||
QObject::connect(pb, &QPushButton::clicked, qApp, QCoreApplication::quit);
|
|
||||||
|
|
||||||
dialog->show();
|
|
||||||
int ret = app.exec();
|
|
||||||
delete dialog;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>Wgs84</class>
|
|
||||||
<widget class="QWidget" name="Wgs84">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>293</width>
|
|
||||||
<height>32</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblLat">
|
|
||||||
<property name="text">
|
|
||||||
<string>Lat:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="leLat"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblLon">
|
|
||||||
<property name="text">
|
|
||||||
<string>Lon:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="leLon"/>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="tbReset">
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>icon:arrow_back.svg</normaloff>icon:arrow_back.svg</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <GeographicLib/MGRS.hpp>
|
|
||||||
#include <GeographicLib/UTMUPS.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc != 2)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Usage: %s <mgrs>\n", argv[0]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string mgrs = argv[1];
|
|
||||||
mgrs.erase(remove_if(mgrs.begin(), mgrs.end(), isspace), mgrs.end());
|
|
||||||
|
|
||||||
int prec;
|
|
||||||
double lonDeg, latDeg;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int zone;
|
|
||||||
bool northp;
|
|
||||||
double x, y;
|
|
||||||
GeographicLib::MGRS::Reverse(mgrs, zone, northp, x, y, prec, true);
|
|
||||||
GeographicLib::UTMUPS::Reverse(zone, northp, x, y, latDeg, lonDeg);
|
|
||||||
|
|
||||||
GeographicLib::UTMUPS::Forward(latDeg, lonDeg, zone, northp, x, y);
|
|
||||||
GeographicLib::MGRS::Forward(zone, northp, x, y, prec, mgrs);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error converting %s to Lon/Lat coords\n", mgrs.c_str());
|
|
||||||
return -2;
|
|
||||||
}
|
|
||||||
std::string part1, part2, part3, part4;
|
|
||||||
part1 = mgrs.substr(0, 3);
|
|
||||||
part2 = mgrs.substr(3, 2);
|
|
||||||
part3 = mgrs.substr(5, 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(),
|
|
||||||
part3.c_str(),
|
|
||||||
part4.c_str(),
|
|
||||||
lonDeg,
|
|
||||||
latDeg,
|
|
||||||
lonDeg / 180. * M_PI,
|
|
||||||
latDeg / 180. * M_PI);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by hjl, SLSE, 2016-05-31
|
|
||||||
#
|
|
||||||
|
|
||||||
FIND_PACKAGE(OpenSSL)
|
|
||||||
|
|
||||||
SET(ltslicence_SRCS
|
|
||||||
aes_crypt.cpp
|
|
||||||
aes_crypt.h
|
|
||||||
lts_licence.cpp
|
|
||||||
lts_licence.h
|
|
||||||
)
|
|
||||||
|
|
||||||
if(OPENSSL_FOUND)
|
|
||||||
NGL_ADD_LIBRARY2(AAR SV WS LtsLicence SHARED ${ltslicence_SRCS})
|
|
||||||
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsLicence
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsLicence
|
|
||||||
PRIVATE
|
|
||||||
${OPENSSL_LIBRARIES}
|
|
||||||
Qt6::Xml
|
|
||||||
NGLLogger
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
)
|
|
||||||
|
|
||||||
IF (BUILD_TESTING AND TARGET LtsLicence)
|
|
||||||
ADD_EXECUTABLE(aes_crypt_test aes_crypt_test.cpp aes_crypt_test.h)
|
|
||||||
TARGET_LINK_LIBRARIES(aes_crypt_test
|
|
||||||
LtsLicence
|
|
||||||
NGLLogger
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Test
|
|
||||||
)
|
|
||||||
ADD_TEST(NAME aes_crypt_test COMMAND $<TARGET_FILE:aes_crypt_test>)
|
|
||||||
ENDIF()
|
|
||||||
else()
|
|
||||||
message(WARNING "LtsLicence skipped: OpenSSL not found")
|
|
||||||
endif()
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "aes_crypt.h"
|
|
||||||
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
#include <QtCore/QRandomGenerator>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
|
|
||||||
namespace LtsLicence
|
|
||||||
{
|
|
||||||
struct AesCryptPrivate
|
|
||||||
{
|
|
||||||
AesCryptPrivate()
|
|
||||||
: passPhrase(QLatin1String("LTS " LTS_VERSION_MAJOR "." LTS_VERSION_MINOR))
|
|
||||||
, logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicenceLib.AesCrypt"))
|
|
||||||
{
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
|
|
||||||
ERR_load_crypto_strings();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
~AesCryptPrivate()
|
|
||||||
{
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
|
|
||||||
ERR_free_strings();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
QString passPhrase;
|
|
||||||
NGL::INGLLogger &logger;
|
|
||||||
};
|
|
||||||
Q_GLOBAL_STATIC(AesCryptPrivate, s_Private)
|
|
||||||
|
|
||||||
void setPassPhrase(const QString &passPhrase)
|
|
||||||
{
|
|
||||||
s_Private->passPhrase = passPhrase;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString passPhrase()
|
|
||||||
{
|
|
||||||
return s_Private->passPhrase;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray decryptData(const QByteArray &dataToDecrypt, const QString &pw, bool *bOk)
|
|
||||||
{
|
|
||||||
if (bOk)
|
|
||||||
*bOk = false;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
int outSize1 = 0;
|
|
||||||
int outSize2 = 0;
|
|
||||||
unsigned char key[32];
|
|
||||||
|
|
||||||
const QByteArray baPassword = pw.toUtf8();
|
|
||||||
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);
|
|
||||||
if (i != 32)
|
|
||||||
{
|
|
||||||
ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
const QByteArray baSalt = dataToDecrypt.left(EVP_MAX_IV_LENGTH);
|
|
||||||
const unsigned char *salt = reinterpret_cast<const unsigned char *>(baSalt.data());
|
|
||||||
|
|
||||||
const QByteArray bufEncrypted = dataToDecrypt.mid(EVP_MAX_IV_LENGTH);
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
||||||
ret = EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt);
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
char errbuf[256];
|
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_DecryptInit_ex failed";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray bufDecrypted;
|
|
||||||
bufDecrypted.resize(bufEncrypted.size() + EVP_CIPHER_CTX_block_size(ctx));
|
|
||||||
const unsigned char *dataIn = reinterpret_cast<const unsigned char *>(bufEncrypted.data());
|
|
||||||
unsigned char *dataOut = reinterpret_cast<unsigned char *>(bufDecrypted.data());
|
|
||||||
|
|
||||||
ret = EVP_DecryptUpdate(ctx, dataOut, &outSize1, dataIn, bufEncrypted.size());
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
char errbuf[256];
|
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_DecryptUpdate failed";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = EVP_DecryptFinal_ex(ctx, dataOut + outSize1, &outSize2);
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
char errbuf[256];
|
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_DecryptFinal_ex failed";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
|
|
||||||
bufDecrypted.resize(outSize1 + outSize2);
|
|
||||||
|
|
||||||
if (bOk)
|
|
||||||
*bOk = true;
|
|
||||||
return bufDecrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray encryptData(const QByteArray &dataToEncrypt, const QString &pw, bool *bOk)
|
|
||||||
{
|
|
||||||
if (bOk)
|
|
||||||
*bOk = false;
|
|
||||||
|
|
||||||
int ret;
|
|
||||||
int outSize1 = 0;
|
|
||||||
int outSize2 = 0;
|
|
||||||
unsigned char key[32];
|
|
||||||
QByteArray bufEncrypted;
|
|
||||||
|
|
||||||
const QByteArray baPassword = pw.toUtf8();
|
|
||||||
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);
|
|
||||||
if (i != 32)
|
|
||||||
{
|
|
||||||
ERROR_LOG(s_Private->logger) << "Wrong key size - should be 256 bits";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray baSalt(EVP_MAX_IV_LENGTH, 0);
|
|
||||||
for (int i = 0; i < EVP_MAX_IV_LENGTH; ++i)
|
|
||||||
baSalt[i] = static_cast<char>(QRandomGenerator::global()->bounded(256));
|
|
||||||
const unsigned char *salt = reinterpret_cast<const unsigned char *>(baSalt.data());
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
||||||
ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, salt);
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
char errbuf[256];
|
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_EncryptInit_ex failed";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
bufEncrypted = QByteArray::fromRawData(reinterpret_cast<const char *>(salt), EVP_MAX_IV_LENGTH);
|
|
||||||
bufEncrypted.resize(bufEncrypted.size() + dataToEncrypt.size() + EVP_CIPHER_CTX_block_size(ctx));
|
|
||||||
const unsigned char *dataIn = reinterpret_cast<const unsigned char *>(dataToEncrypt.data());
|
|
||||||
unsigned char *dataOut = reinterpret_cast<unsigned char *>(bufEncrypted.data());
|
|
||||||
dataOut += baSalt.size();
|
|
||||||
ret = EVP_EncryptUpdate(ctx, dataOut, &outSize1, dataIn, dataToEncrypt.size());
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
char errbuf[256];
|
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_EncryptUpdate failed";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = EVP_EncryptFinal_ex(ctx, dataOut + outSize1, &outSize2);
|
|
||||||
if (ret == 0)
|
|
||||||
{
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
char errbuf[256];
|
|
||||||
ERR_error_string_n(ERR_get_error(), errbuf, sizeof(errbuf));
|
|
||||||
ERROR_LOG(s_Private->logger) << "EVP_EncryptFinal_ex failed";
|
|
||||||
return QByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_free(ctx);
|
|
||||||
|
|
||||||
bufEncrypted.resize(outSize1 + outSize2 + baSalt.size());
|
|
||||||
|
|
||||||
if (bOk)
|
|
||||||
*bOk = true;
|
|
||||||
return bufEncrypted;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsLicence
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltslicence_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
|
|
||||||
namespace LtsLicence
|
|
||||||
{
|
|
||||||
|
|
||||||
LTSLICENCE_EXPORT void setPassPhrase(const QString &passPhrase);
|
|
||||||
LTSLICENCE_EXPORT QString passPhrase();
|
|
||||||
|
|
||||||
LTSLICENCE_EXPORT QByteArray decryptData(const QByteArray &dataToDecrypt, const QString &pw = passPhrase(), bool *bOk = nullptr);
|
|
||||||
|
|
||||||
LTSLICENCE_EXPORT QByteArray encryptData(const QByteArray &dataToEncrypt, const QString &pw = passPhrase(), bool *bOk = nullptr);
|
|
||||||
} // namespace LtsLicence
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "aes_crypt_test.h"
|
|
||||||
|
|
||||||
#include "aes_crypt.h"
|
|
||||||
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtTest/QTest>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
|
|
||||||
QTEST_MAIN(aes_crypt_test)
|
|
||||||
|
|
||||||
void aes_crypt_test::initTestCase()
|
|
||||||
{
|
|
||||||
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void aes_crypt_test::truePassTest()
|
|
||||||
{
|
|
||||||
qDebug("Simple TestCase");
|
|
||||||
bool bOk;
|
|
||||||
const QByteArray content("30.06.2013");
|
|
||||||
const QString pw(QStringLiteral("aes_crypt_test"));
|
|
||||||
const QByteArray enc = LtsLicence::encryptData(content, pw, &bOk);
|
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
|
||||||
|
|
||||||
QCOMPARE(((content.size() + 15 + EVP_MAX_IV_LENGTH) / 18) * 16, enc.size());
|
|
||||||
const QByteArray dec = LtsLicence::decryptData(enc, pw, &bOk);
|
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
|
||||||
QCOMPARE(dec, content);
|
|
||||||
|
|
||||||
const QByteArray bigContent(12345, '1');
|
|
||||||
const QByteArray bigEnc = LtsLicence::encryptData(bigContent, pw, &bOk);
|
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
|
||||||
|
|
||||||
QCOMPARE(((bigContent.size() + 15 + EVP_MAX_IV_LENGTH) / 16) * 16, bigEnc.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void aes_crypt_test::falsePassTest()
|
|
||||||
{
|
|
||||||
qDebug("False Password TestCase");
|
|
||||||
bool bOk;
|
|
||||||
const QByteArray content("30.06.2013");
|
|
||||||
const QString pw(QStringLiteral("aes_crypt_test"));
|
|
||||||
const QString pw2(QStringLiteral("aes_crypt_test2"));
|
|
||||||
const QByteArray enc = LtsLicence::encryptData(content, pw, &bOk);
|
|
||||||
QVERIFY2(bOk, "Error encrypting data...");
|
|
||||||
QVERIFY2(enc.size() != 20, "Error encrypting data...");
|
|
||||||
const QByteArray dec = LtsLicence::decryptData(enc, pw2, &bOk);
|
|
||||||
QVERIFY2(!bOk, "Error encrypting data...");
|
|
||||||
QVERIFY2(dec.isEmpty(), "decrypted data is not empty...");
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
class aes_crypt_test : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private Q_SLOTS:
|
|
||||||
void initTestCase();
|
|
||||||
void truePassTest();
|
|
||||||
void falsePassTest();
|
|
||||||
};
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_licence.h"
|
|
||||||
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
#include <QtXml/QDomDocument>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
namespace LtsLicence
|
|
||||||
{
|
|
||||||
static bool extractLicence(const QDomElement &licenceElement, QVector<Licence> &licenceVec);
|
|
||||||
|
|
||||||
static NGL::INGLLogger &getLogger()
|
|
||||||
{
|
|
||||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("LtsLicence");
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<Licence> readLicences(const QByteArray &unencryptedXmlData)
|
|
||||||
{
|
|
||||||
QVector<Licence> licenceVec;
|
|
||||||
|
|
||||||
QDomDocument xmlDoc;
|
|
||||||
|
|
||||||
const auto parseResult = xmlDoc.setContent(unencryptedXmlData);
|
|
||||||
if (!parseResult)
|
|
||||||
{
|
|
||||||
ERROR_LOG(getLogger()) << "Error reading xml data, "
|
|
||||||
<< "error in line " << int(parseResult.errorLine) << ", column " << int(parseResult.errorColumn)
|
|
||||||
<< ", message: " << parseResult.errorMessage;
|
|
||||||
return licenceVec;
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(getLogger()) << "Try to extract licences";
|
|
||||||
|
|
||||||
QDomElement licenceElement = xmlDoc.documentElement().firstChildElement(QLatin1String("licence"));
|
|
||||||
|
|
||||||
while (!licenceElement.isNull())
|
|
||||||
{
|
|
||||||
if (!extractLicence(licenceElement, licenceVec))
|
|
||||||
{
|
|
||||||
licenceVec.clear();
|
|
||||||
return licenceVec;
|
|
||||||
}
|
|
||||||
|
|
||||||
licenceElement = licenceElement.nextSiblingElement(QLatin1String("licence"));
|
|
||||||
}
|
|
||||||
return licenceVec;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray writeUnencryptedLicences(const QVector<Licence> &licences)
|
|
||||||
{
|
|
||||||
QDomDocument xmlDoc;
|
|
||||||
|
|
||||||
QDomProcessingInstruction instr = xmlDoc.createProcessingInstruction(QLatin1String("xml"), QLatin1String("version='1.0' encoding='UTF-8' standalone='yes'"));
|
|
||||||
xmlDoc.appendChild(instr);
|
|
||||||
|
|
||||||
QDomElement root = xmlDoc.createElement(QLatin1String("licences"));
|
|
||||||
xmlDoc.appendChild(root);
|
|
||||||
|
|
||||||
for (int i = 0; i < licences.size(); ++i)
|
|
||||||
{
|
|
||||||
QDomElement lic = xmlDoc.createElement(QLatin1String("licence"));
|
|
||||||
root.appendChild(lic);
|
|
||||||
|
|
||||||
QDomElement element = xmlDoc.createElement(QLatin1String("name"));
|
|
||||||
QDomText text = xmlDoc.createTextNode(licences[i].name);
|
|
||||||
element.appendChild(text);
|
|
||||||
lic.appendChild(element);
|
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("ignoreMaxCount"));
|
|
||||||
text = xmlDoc.createTextNode(QString::number(licences[i].ignoreMaxCount));
|
|
||||||
element.appendChild(text);
|
|
||||||
lic.appendChild(element);
|
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("ignoreExpiration"));
|
|
||||||
text = xmlDoc.createTextNode(QString::number(licences[i].ignoreExpiration));
|
|
||||||
element.appendChild(text);
|
|
||||||
lic.appendChild(element);
|
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("maxCount"));
|
|
||||||
text = xmlDoc.createTextNode(QString::number(licences[i].maxCount));
|
|
||||||
element.appendChild(text);
|
|
||||||
lic.appendChild(element);
|
|
||||||
|
|
||||||
const QLatin1String format("dd.MM.yyyy hh:mm:ss");
|
|
||||||
const QString qs = licences[i].expiration.toString(format);
|
|
||||||
|
|
||||||
element = xmlDoc.createElement(QLatin1String("expiration"));
|
|
||||||
text = xmlDoc.createTextNode(qs);
|
|
||||||
element.appendChild(text);
|
|
||||||
lic.appendChild(element);
|
|
||||||
}
|
|
||||||
INFO_LOG(getLogger()) << "Generated XML Data...\n" << xmlDoc.toByteArray();
|
|
||||||
return xmlDoc.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool extractLicence(const QDomElement &licenceElement, QVector<Licence> &licenceVec)
|
|
||||||
{
|
|
||||||
Licence licence;
|
|
||||||
|
|
||||||
QDomElement tag = licenceElement.firstChildElement(QLatin1String("name"));
|
|
||||||
licence.name = tag.text();
|
|
||||||
|
|
||||||
tag = licenceElement.firstChildElement(QLatin1String("ignoreMaxCount"));
|
|
||||||
licence.ignoreMaxCount = tag.text().toInt();
|
|
||||||
|
|
||||||
tag = licenceElement.firstChildElement(QLatin1String("ignoreExpiration"));
|
|
||||||
licence.ignoreExpiration = tag.text().toInt();
|
|
||||||
|
|
||||||
tag = licenceElement.firstChildElement(QLatin1String("maxCount"));
|
|
||||||
licence.maxCount = tag.text().toInt();
|
|
||||||
|
|
||||||
tag = licenceElement.firstChildElement(QLatin1String("expiration"));
|
|
||||||
|
|
||||||
const QString qs(tag.text());
|
|
||||||
|
|
||||||
const QLatin1String format("dd.MM.yyyy hh:mm:ss");
|
|
||||||
const QDateTime qdt = QDateTime::fromString(qs, format);
|
|
||||||
|
|
||||||
if (!qdt.isValid())
|
|
||||||
{
|
|
||||||
ERROR_LOG(getLogger()) << "Invalid expiration format! " << qs << " used format: " << format;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
licence.expiration = qdt;
|
|
||||||
INFO_LOG(getLogger()) << "Read licence for:'" << licence.name << "'"
|
|
||||||
<< " IgnoreMaxCount: " << licence.ignoreMaxCount << " IgnoreExpiration: " << licence.ignoreExpiration << " MaxCount: " << licence.maxCount
|
|
||||||
<< " Expiration: " << licence.expiration.date().toString() << " " << licence.expiration.time().toString()
|
|
||||||
<< " RefCount: " << licence.licenceRefCount;
|
|
||||||
|
|
||||||
licenceVec.append(licence);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Licence::toString() const
|
|
||||||
{
|
|
||||||
return QObject::tr("Name: %1, Count: %2, ExpireDate: %3, Expires: %4, UseMaxCount: %5")
|
|
||||||
.arg(name)
|
|
||||||
.arg(maxCount)
|
|
||||||
.arg(expiration.toString())
|
|
||||||
.arg(ignoreExpiration)
|
|
||||||
.arg(ignoreMaxCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsLicence
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltslicence_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QDateTime>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
|
|
||||||
namespace LtsLicence
|
|
||||||
{
|
|
||||||
|
|
||||||
struct LTSLICENCE_EXPORT Licence
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
bool ignoreMaxCount = false;
|
|
||||||
bool ignoreExpiration = false;
|
|
||||||
int maxCount = 0;
|
|
||||||
QDateTime expiration;
|
|
||||||
int licenceRefCount = 0;
|
|
||||||
|
|
||||||
QString toString() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
LTSLICENCE_EXPORT QVector<Licence> readLicences(const QByteArray &unencryptedXmlData);
|
|
||||||
|
|
||||||
LTSLICENCE_EXPORT QByteArray writeUnencryptedLicences(const QVector<Licence> &licences);
|
|
||||||
} // namespace LtsLicence
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Mike Wille, SLSE, 2016-01-13
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
SET(LtsNoti_SRCS
|
|
||||||
lts_notification.h
|
|
||||||
lts_notification.cpp
|
|
||||||
lts_notification_ctl.h
|
|
||||||
lts_notification_ctl.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(WS LtsNotification SHARED ${LtsNoti_SRCS})
|
|
||||||
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsNotification
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
|
||||||
)
|
|
||||||
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsNotification
|
|
||||||
${Qt6_Widgets}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
NGL_INSTALL_TARGET(LtsNotification)
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_notification.h"
|
|
||||||
|
|
||||||
#include "lts_notification_ctl.h"
|
|
||||||
|
|
||||||
#include <QtGui/QIcon>
|
|
||||||
|
|
||||||
namespace LtsNotification
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsNotification::LtsNotification(LtsNotificationController *ctl)
|
|
||||||
: QObject()
|
|
||||||
, m_controller(ctl)
|
|
||||||
{
|
|
||||||
connect(ctl, &LtsNotificationController::destroyed, this, &LtsNotification::slotCtlDestroyed);
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsNotification::~LtsNotification()
|
|
||||||
{
|
|
||||||
delete m_controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::setIcon(const QIcon &icon)
|
|
||||||
{
|
|
||||||
m_controller->setIcon(icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::setAction(const std::function<void(void)> &action)
|
|
||||||
{
|
|
||||||
m_controller->setAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::setToolTip(const QString &toolTip)
|
|
||||||
{
|
|
||||||
m_controller->setToolTip(toolTip);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString &LtsNotification::tooltip() const
|
|
||||||
{
|
|
||||||
return m_controller->tooltip();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::setCount(const int count)
|
|
||||||
{
|
|
||||||
m_controller->setCount(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::setEnabled(bool enable)
|
|
||||||
{
|
|
||||||
m_controller->setEnabled(enable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::setBackground(const int r, const int g, const int b)
|
|
||||||
{
|
|
||||||
m_controller->setBackground(r, g, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotification::slotCtlDestroyed(QObject *obj)
|
|
||||||
{
|
|
||||||
(void)obj;
|
|
||||||
|
|
||||||
m_controller = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsNotification
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "lts_notification_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace LtsSession
|
|
||||||
{
|
|
||||||
class LtsSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsNotification
|
|
||||||
{
|
|
||||||
class LtsNotificationController;
|
|
||||||
|
|
||||||
class LTSNOTIFICATION_EXPORT LtsNotification : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit LtsNotification(LtsNotificationController *ctl);
|
|
||||||
~LtsNotification();
|
|
||||||
|
|
||||||
void setIcon(const QIcon &icon);
|
|
||||||
void setAction(const std::function<void(void)> &action);
|
|
||||||
void setToolTip(const QString &toolTip);
|
|
||||||
void setCount(const int count);
|
|
||||||
void setEnabled(bool enable);
|
|
||||||
void setBackground(const int r, const int g, const int b);
|
|
||||||
|
|
||||||
const QString &tooltip() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
LtsNotificationController *m_controller;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotCtlDestroyed(QObject *obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsNotification
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_notification_ctl.h"
|
|
||||||
|
|
||||||
#include <QtGui/QColor>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
#include <QtGui/QIcon>
|
|
||||||
#include <QtGui/QImage>
|
|
||||||
#include <QtGui/QPainter>
|
|
||||||
#include <QtWidgets/QToolButton>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
namespace LtsNotification
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsNotificationController::LtsNotificationController(const QString &identifier)
|
|
||||||
: QObject()
|
|
||||||
, m_count(0)
|
|
||||||
, m_identifier(QStringLiteral("LtsNotification%1").arg(identifier))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsNotificationController::~LtsNotificationController()
|
|
||||||
{
|
|
||||||
qDeleteAll(m_notiList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setIcon(const QIcon &icon)
|
|
||||||
{
|
|
||||||
m_icon = icon;
|
|
||||||
|
|
||||||
setAllIcons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setCount(const int count)
|
|
||||||
{
|
|
||||||
m_count = count;
|
|
||||||
|
|
||||||
setAllIcons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setBackground(const int r, const int g, const int b)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (QToolButton *tb : std::as_const(m_notiList))
|
|
||||||
{
|
|
||||||
|
|
||||||
QString stylesheet;
|
|
||||||
|
|
||||||
if (r == -1 && g == -1 && b == -1)
|
|
||||||
stylesheet = QStringLiteral("");
|
|
||||||
else
|
|
||||||
stylesheet = QStringLiteral("QToolButton {background-color: rgb(") + QString::number(r) + QStringLiteral(",") + QString::number(g) + QStringLiteral(",") +
|
|
||||||
QString::number(b) + QStringLiteral(");}");
|
|
||||||
|
|
||||||
tb->setStyleSheet(stylesheet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setEnabled(bool enable)
|
|
||||||
{
|
|
||||||
m_enable = enable;
|
|
||||||
|
|
||||||
setAllIcons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setAction(const std::function<void(void)> &action)
|
|
||||||
{
|
|
||||||
m_action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setToolTip(const QString &toolTip)
|
|
||||||
{
|
|
||||||
m_toolTip = toolTip;
|
|
||||||
|
|
||||||
for (QToolButton *tb : std::as_const(m_notiList))
|
|
||||||
{
|
|
||||||
tb->setToolTip(toolTip);
|
|
||||||
tb->setIconSize(QSize(30, 30));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::setAllIcons()
|
|
||||||
{
|
|
||||||
if (m_icon.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QIcon icon = modifyIcon(m_icon);
|
|
||||||
|
|
||||||
for (QToolButton *tb : std::as_const(m_notiList))
|
|
||||||
{
|
|
||||||
tb->setIcon(icon);
|
|
||||||
tb->setIconSize(QSize(30, 30));
|
|
||||||
tb->setEnabled(m_enable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SIZE 40
|
|
||||||
|
|
||||||
QIcon LtsNotificationController::modifyIcon(const QIcon &icon)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (m_count < 1)
|
|
||||||
return icon;
|
|
||||||
|
|
||||||
QPixmap iconImage(icon.pixmap(SIZE * 8 / 10, SIZE * 8 / 10));
|
|
||||||
QPainter painter(&iconImage);
|
|
||||||
|
|
||||||
painter.save();
|
|
||||||
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
|
||||||
|
|
||||||
QFont f;
|
|
||||||
f.setFamily(QStringLiteral("Monospace"));
|
|
||||||
f.setPointSize(16);
|
|
||||||
f.setBold(true);
|
|
||||||
painter.setFont(f);
|
|
||||||
|
|
||||||
QColor color(Qt::red);
|
|
||||||
painter.setBrush(color);
|
|
||||||
painter.setPen(QPen(color, 3.1));
|
|
||||||
painter.drawText(QRect(0, 0, 30, 30), QString::number(m_count));
|
|
||||||
painter.restore();
|
|
||||||
|
|
||||||
return iconImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolButton *LtsNotificationController::createWidget()
|
|
||||||
{
|
|
||||||
QToolButton *b = new QToolButton();
|
|
||||||
b->setToolButtonStyle(Qt::ToolButtonIconOnly);
|
|
||||||
b->setObjectName(m_identifier);
|
|
||||||
|
|
||||||
b->setMinimumSize(SIZE, SIZE);
|
|
||||||
b->setMaximumSize(SIZE, SIZE);
|
|
||||||
|
|
||||||
connect(b, &QToolButton::destroyed, this, &LtsNotificationController::slotNotiWidgetDestroyed);
|
|
||||||
connect(b,
|
|
||||||
&QToolButton::clicked,
|
|
||||||
this,
|
|
||||||
[this]()
|
|
||||||
{
|
|
||||||
if (m_action)
|
|
||||||
m_action();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!m_icon.isNull())
|
|
||||||
b->setIcon(modifyIcon(m_icon));
|
|
||||||
|
|
||||||
b->setToolTip(m_toolTip);
|
|
||||||
|
|
||||||
m_notiList.append(b);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsNotificationController::slotNotiWidgetDestroyed(QObject *obj)
|
|
||||||
{
|
|
||||||
m_notiList.removeAll(static_cast<QToolButton *>(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsNotification
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "lts_notification_export.h"
|
|
||||||
|
|
||||||
#include <QtGui/QIcon>
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
class QToolButton;
|
|
||||||
|
|
||||||
namespace LtsSession
|
|
||||||
{
|
|
||||||
class LtsSession;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsNotification
|
|
||||||
{
|
|
||||||
class LtsNotificationWidget;
|
|
||||||
|
|
||||||
class LTSNOTIFICATION_EXPORT LtsNotificationController : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit LtsNotificationController(const QString &identifier);
|
|
||||||
~LtsNotificationController();
|
|
||||||
|
|
||||||
QToolButton *createWidget();
|
|
||||||
|
|
||||||
void setIcon(const QIcon &icon);
|
|
||||||
void setAction(const std::function<void(void)> &action);
|
|
||||||
void setToolTip(const QString &toolTip);
|
|
||||||
void setCount(const int count);
|
|
||||||
void setBackground(const int r, const int g, const int b);
|
|
||||||
|
|
||||||
const QString &identifier() const { return m_identifier; }
|
|
||||||
|
|
||||||
const QString &tooltip() const { return m_toolTip; }
|
|
||||||
|
|
||||||
void setEnabled(bool enable);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<QToolButton *> m_notiList;
|
|
||||||
|
|
||||||
QIcon m_icon;
|
|
||||||
std::function<void(void)> m_action;
|
|
||||||
QString m_toolTip;
|
|
||||||
int m_count;
|
|
||||||
bool m_enable{true};
|
|
||||||
QString m_identifier;
|
|
||||||
|
|
||||||
void setAllIcons();
|
|
||||||
QIcon modifyIcon(const QIcon &icon);
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotNotiWidgetDestroyed(QObject *obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsNotification
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
|
|
||||||
#ifndef LTSNOTIFICATION_EXPORT
|
|
||||||
#ifdef BUILD_STATIC_LIBRARIES
|
|
||||||
#define LTSNOTIFICATION_EXPORT
|
|
||||||
#else
|
|
||||||
#if defined(MAKE_LTSNOTIFICATION_LIB)
|
|
||||||
#define LTSNOTIFICATION_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
#define LTSNOTIFICATION_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
#
|
|
||||||
# Lightweight REST Client Framework
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Hannes Fritsche, ESZS, 2026-08-21
|
|
||||||
|
|
||||||
#
|
|
||||||
# --- Library LtsRestClient --------------------------------------------------------------------------------
|
|
||||||
#
|
|
||||||
SET(LtsRestClient_SRCS
|
|
||||||
lts_rest_client.cpp
|
|
||||||
lts_rest_client.h
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(ALL LtsRestClient SHARED ${LtsRestClient_SRCS})
|
|
||||||
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsRestClient
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsRestClient
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Network
|
|
||||||
)
|
|
||||||
@@ -1,175 +0,0 @@
|
|||||||
/**
|
|
||||||
* Lightweight REST Client Framework
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Hannes Fritsche, ESZS, 2026-08-21
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lts_rest_client.h"
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QtNetwork/QNetworkAccessManager>
|
|
||||||
#include <QtNetwork/QNetworkReply>
|
|
||||||
#include <QtNetwork/QNetworkRequest>
|
|
||||||
|
|
||||||
namespace LtsCommon
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsRestClient::LtsRestClient(const QString &baseUrl, QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_baseUrl(baseUrl)
|
|
||||||
, 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)
|
|
||||||
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())
|
|
||||||
reply->abort(); // Triggers finished() with OperationCanceledError
|
|
||||||
});
|
|
||||||
|
|
||||||
// 3. Connect the finished signal to handle the response
|
|
||||||
connect(reply,
|
|
||||||
&QNetworkReply::finished,
|
|
||||||
this,
|
|
||||||
[reply, timeoutTimer, onSuccess, onError]()
|
|
||||||
{
|
|
||||||
timeoutTimer->stop();
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
if (reply->error() != QNetworkReply::NoError)
|
|
||||||
{
|
|
||||||
if (onError)
|
|
||||||
{
|
|
||||||
if (reply->error() == QNetworkReply::OperationCanceledError)
|
|
||||||
onError(QStringLiteral("Ping timed out."));
|
|
||||||
else
|
|
||||||
onError(reply->errorString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
|
|
||||||
if (onSuccess)
|
|
||||||
onSuccess(statusCode);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 4. Start the timer only after all connections are successfully established
|
|
||||||
timeoutTimer->start(timeoutMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsRestClient::get(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError)
|
|
||||||
{
|
|
||||||
sendRequest(QStringLiteral("GET"), endpoint, QByteArray(), onSuccess, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsRestClient::post(const QString &endpoint, const QJsonDocument &json, SuccessCallback onSuccess, ErrorCallback onError)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
onError(QStringLiteral("Failed to initiate request."));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(reply,
|
|
||||||
&QNetworkReply::finished,
|
|
||||||
this,
|
|
||||||
[reply, onSuccess, onError]()
|
|
||||||
{
|
|
||||||
reply->deleteLater();
|
|
||||||
|
|
||||||
// Handle network errors
|
|
||||||
if (reply->error() != QNetworkReply::NoError)
|
|
||||||
{
|
|
||||||
if (onError)
|
|
||||||
onError(reply->errorString());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle HTTP errors
|
|
||||||
const int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
|
||||||
if (statusCode >= 400)
|
|
||||||
{
|
|
||||||
if (onError)
|
|
||||||
onError(QStringLiteral("HTTP Error %1").arg(statusCode));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse JSON safely
|
|
||||||
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
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
/**
|
|
||||||
* Lightweight REST Client Framework
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Hannes Fritsche, ESZS, 2026-08-21
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Short documentation on how to use it can be found at https://confluence-classified.rh-int.de/spaces/LEG/pages/207915647/HOWTO+LtsRestClient
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QString>
|
|
||||||
#include <functional>
|
|
||||||
#include <LtsRestClient/ltsrestclient_export.h>
|
|
||||||
|
|
||||||
class QNetworkAccessManager;
|
|
||||||
|
|
||||||
namespace LtsCommon
|
|
||||||
{
|
|
||||||
|
|
||||||
class LTSRESTCLIENT_EXPORT LtsRestClient : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit LtsRestClient(const QString &baseUrl, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
// type aliases
|
|
||||||
using PingSuccessCallback = std::function<void(int statusCode)>;
|
|
||||||
using SuccessCallback = std::function<void(const QJsonDocument &)>;
|
|
||||||
using ErrorCallback = std::function<void(const QString &)>;
|
|
||||||
|
|
||||||
// HTTP Header Ping to m_baseUrl to check server availability
|
|
||||||
void ping(PingSuccessCallback onSuccess, ErrorCallback onError = nullptr, int timeoutMs = 3000);
|
|
||||||
|
|
||||||
// HTTP Methods
|
|
||||||
void get(const QString &endpoint, 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 del(const QString &endpoint, SuccessCallback onSuccess, ErrorCallback onError = nullptr);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void sendRequest(const QString &method, const QString &endpoint, const QByteArray &data, SuccessCallback onSuccess, ErrorCallback onError);
|
|
||||||
|
|
||||||
QString m_baseUrl;
|
|
||||||
QNetworkAccessManager *m_manager;
|
|
||||||
}; // class RestClient
|
|
||||||
} // namespace LtsCommon
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Lts SerialPortQuerry library
|
|
||||||
#
|
|
||||||
|
|
||||||
SET(ltsspq_SRCS
|
|
||||||
lts_serial_port_querry.h
|
|
||||||
lts_serial_port_querry.cpp
|
|
||||||
logger.h
|
|
||||||
logger.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(AAR SV LtsSerialPortQuerry SHARED ${ltsspq_SRCS} )
|
|
||||||
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsSerialPortQuerry
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsSerialPortQuerry
|
|
||||||
PRIVATE
|
|
||||||
PUBLIC
|
|
||||||
NGLLogger
|
|
||||||
$<IF:$<TARGET_EXISTS:Qt6::SerialPort>,Qt6::SerialPort,>
|
|
||||||
)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
|
||||||
{
|
|
||||||
|
|
||||||
LOGGER_T getLogger(const char *name)
|
|
||||||
{
|
|
||||||
static const char ns[] = "SPQ.";
|
|
||||||
std::string loggerName;
|
|
||||||
const size_t len = strlen(name);
|
|
||||||
loggerName.reserve(sizeof(ns) + len);
|
|
||||||
loggerName.append(ns, sizeof(ns) - 1);
|
|
||||||
loggerName.append(name, len);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName);
|
|
||||||
}
|
|
||||||
catch (const std::exception &ex)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsSerialPortQuerry
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
|
||||||
{
|
|
||||||
typedef NGL::INGLLogger &LOGGER_T;
|
|
||||||
|
|
||||||
LOGGER_T getLogger(const char *name);
|
|
||||||
|
|
||||||
inline LOGGER_T getLogger(const QString &loggerName)
|
|
||||||
{
|
|
||||||
return getLogger(loggerName.toUtf8().constData());
|
|
||||||
}
|
|
||||||
} // namespace LtsSerialPortQuerry
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "lts_seri"
|
|
||||||
#include "ltsserialportquerry_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtSerialPort/QSerialPortInfo>
|
|
||||||
#include <QtSerialPort/QtSerialPort>
|
|
||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
|
||||||
{
|
|
||||||
class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit LtsSerialPortQuerry(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
void setSerialPortSettings(const QSerialPort::BaudRate &baudRate,
|
|
||||||
const QSerialPort::OpenModeFlag &openModeFlag,
|
|
||||||
const QSerialPort::DataBits &dataBits,
|
|
||||||
const QSerialPort::FlowControl &flowControll,
|
|
||||||
const QSerialPort::Parity &parity,
|
|
||||||
const QSerialPort::StopBits &stopBits);
|
|
||||||
void continueQuerry();
|
|
||||||
void restartQuerry();
|
|
||||||
QSerialPort *currentSerialPort();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void connectionEstablished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void querrySerialPort(const QSerialPortInfo &info);
|
|
||||||
void closeAndDeleteCurrentPort();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void onSerialPortError(QSerialPort::SerialPortError serialPortError);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<QSerialPortInfo> m_serialPortInfos;
|
|
||||||
int m_currentQuerry;
|
|
||||||
QSerialPort::BaudRate m_baudRate;
|
|
||||||
QSerialPort::OpenModeFlag m_openModeFlag;
|
|
||||||
QSerialPort::DataBits m_dataBits;
|
|
||||||
QSerialPort::FlowControl m_flowControll;
|
|
||||||
QSerialPort::Parity m_parity;
|
|
||||||
QSerialPort::StopBits m_stopBits;
|
|
||||||
QSerialPort *m_currentSerialPort;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsSerialPortQuerry
|
|
||||||
-147
@@ -1,147 +0,0 @@
|
|||||||
#include "lts_serial_port_querry.h"
|
|
||||||
|
|
||||||
#include <QtSerialPort/QSerialPortInfo>
|
|
||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsSerialPortQuerry::LtsSerialPortQuerry(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_logger(getLogger("LtsSerialPortQuerry"))
|
|
||||||
, m_currentQuerry(0)
|
|
||||||
, 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,
|
|
||||||
const QIODevice::OpenModeFlag &openModeFlag,
|
|
||||||
const QSerialPort::DataBits &dataBits,
|
|
||||||
const QSerialPort::FlowControl &flowControll,
|
|
||||||
const QSerialPort::Parity &parity,
|
|
||||||
const QSerialPort::StopBits &stopBits)
|
|
||||||
{
|
|
||||||
m_baudRate = baudRate;
|
|
||||||
m_openModeFlag = openModeFlag;
|
|
||||||
m_dataBits = dataBits;
|
|
||||||
m_flowControll = flowControll;
|
|
||||||
m_parity = parity;
|
|
||||||
m_stopBits = stopBits;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsSerialPortQuerry::continueQuerry()
|
|
||||||
{
|
|
||||||
m_currentQuerry++;
|
|
||||||
if (m_currentQuerry >= m_serialPortInfos.size())
|
|
||||||
{
|
|
||||||
|
|
||||||
restartQuerry();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
querrySerialPort(m_serialPortInfos.at(m_currentQuerry));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsSerialPortQuerry::restartQuerry()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "restart querry ";
|
|
||||||
m_serialPortInfos = QSerialPortInfo::availablePorts();
|
|
||||||
m_currentQuerry = 0;
|
|
||||||
if (m_serialPortInfos.size())
|
|
||||||
querrySerialPort(m_serialPortInfos.at(m_currentQuerry));
|
|
||||||
else
|
|
||||||
QTimer::singleShot(1000, this, &LtsSerialPortQuerry::restartQuerry);
|
|
||||||
}
|
|
||||||
|
|
||||||
QSerialPort *LtsSerialPortQuerry::currentSerialPort()
|
|
||||||
{
|
|
||||||
return m_currentSerialPort;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsSerialPortQuerry::querrySerialPort(const QSerialPortInfo &info)
|
|
||||||
{
|
|
||||||
closeAndDeleteCurrentPort();
|
|
||||||
m_currentSerialPort = new QSerialPort(info, this);
|
|
||||||
m_currentSerialPort->setBaudRate(m_baudRate);
|
|
||||||
m_currentSerialPort->setDataBits(m_dataBits);
|
|
||||||
m_currentSerialPort->setParity(m_parity);
|
|
||||||
m_currentSerialPort->setStopBits(m_stopBits);
|
|
||||||
m_currentSerialPort->setFlowControl(m_flowControll);
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Try opening Comport:" << m_currentSerialPort->portName() << " index is: " << m_currentQuerry;
|
|
||||||
|
|
||||||
if (!m_currentSerialPort->open(QSerialPort::ReadWrite))
|
|
||||||
{
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Oppening failed query next";
|
|
||||||
|
|
||||||
continueQuerry();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connect(m_currentSerialPort, &QSerialPort::errorOccurred, this, &LtsSerialPortQuerry::onSerialPortError, Qt::UniqueConnection);
|
|
||||||
DEBUG_LOG(m_logger) << "Oppened comport" << m_currentSerialPort->portName();
|
|
||||||
emit connectionEstablished();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsSerialPortQuerry::closeAndDeleteCurrentPort()
|
|
||||||
{
|
|
||||||
if (m_currentSerialPort)
|
|
||||||
{
|
|
||||||
m_currentSerialPort->disconnect();
|
|
||||||
if (m_currentSerialPort->isOpen())
|
|
||||||
m_currentSerialPort->close();
|
|
||||||
m_currentSerialPort->deleteLater();
|
|
||||||
|
|
||||||
m_currentSerialPort = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsSerialPortQuerry::onSerialPortError(QSerialPort::SerialPortError serialPortError)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!m_currentSerialPort)
|
|
||||||
return;
|
|
||||||
DEBUG_LOG(m_logger) << "Spontaneous error " << serialPortError << " doesn't have to be an error ...";
|
|
||||||
|
|
||||||
const QString errStr(QStringLiteral("QSerialPort::SerialPortError ") + QString::number(serialPortError) + QStringLiteral(" from serial port ") +
|
|
||||||
m_currentSerialPort->portName() + QStringLiteral(" error: ") + m_currentSerialPort->errorString());
|
|
||||||
|
|
||||||
switch (serialPortError)
|
|
||||||
{
|
|
||||||
case QSerialPort::SerialPortError::NoError:
|
|
||||||
{
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QSerialPort::SerialPortError::DeviceNotFoundError:
|
|
||||||
case QSerialPort::SerialPortError::PermissionError:
|
|
||||||
case QSerialPort::SerialPortError::OpenError:
|
|
||||||
case QSerialPort::SerialPortError::NotOpenError:
|
|
||||||
case QSerialPort::SerialPortError::UnknownError:
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Closing port and try to reopen it. " << m_currentSerialPort->portName();
|
|
||||||
continueQuerry();
|
|
||||||
|
|
||||||
Q_FALLTHROUGH();
|
|
||||||
}
|
|
||||||
case QSerialPort::SerialPortError::UnsupportedOperationError:
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << errStr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Got an Error> " << errStr << "restarting";
|
|
||||||
continueQuerry();
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace LtsSerialPortQuerry
|
|
||||||
-50
@@ -1,50 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "ltsserialportquerry_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtSerialPort/QSerialPortInfo>
|
|
||||||
#include <QtSerialPort/QtSerialPort>
|
|
||||||
|
|
||||||
namespace LtsSerialPortQuerry
|
|
||||||
{
|
|
||||||
class LTSSERIALPORTQUERRY_EXPORT LtsSerialPortQuerry : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit LtsSerialPortQuerry(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
void setSerialPortSettings(const QSerialPort::BaudRate &baudRate,
|
|
||||||
const QSerialPort::OpenModeFlag &openModeFlag,
|
|
||||||
const QSerialPort::DataBits &dataBits,
|
|
||||||
const QSerialPort::FlowControl &flowControll,
|
|
||||||
const QSerialPort::Parity &parity,
|
|
||||||
const QSerialPort::StopBits &stopBits);
|
|
||||||
|
|
||||||
void restartQuerry();
|
|
||||||
QSerialPort *currentSerialPort();
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void continueQuerry();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void connectionEstablished();
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGL::INGLLogger &m_logger;
|
|
||||||
void querrySerialPort(const QSerialPortInfo &info);
|
|
||||||
void closeAndDeleteCurrentPort();
|
|
||||||
void onSerialPortError(QSerialPort::SerialPortError serialPortError);
|
|
||||||
QList<QSerialPortInfo> m_serialPortInfos;
|
|
||||||
int m_currentQuerry;
|
|
||||||
QSerialPort::BaudRate m_baudRate;
|
|
||||||
QSerialPort::OpenModeFlag m_openModeFlag;
|
|
||||||
QSerialPort::DataBits m_dataBits;
|
|
||||||
QSerialPort::FlowControl m_flowControll;
|
|
||||||
QSerialPort::Parity m_parity;
|
|
||||||
QSerialPort::StopBits m_stopBits;
|
|
||||||
QSerialPort *m_currentSerialPort;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsSerialPortQuerry
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
# Created by Mike Wille, SLSE, 2016-09-19
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(LtsUtilsCore)
|
|
||||||
ADD_SUBDIRECTORY(LtsUtilsSettings)
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
SET(SRCS_hdr_only
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/data_modification_enum.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/dds_bitarray.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/dds_vector.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/connection.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/json_object.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/json.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/outdated_position.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/qbytearray_byteaccess.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/qpoint3d.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/await.h
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/lts_translatable_identifier.h
|
|
||||||
)
|
|
||||||
ADD_LIBRARY(LtsUtilsCoreHeaderOnly INTERFACE)
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(LtsUtilsCoreHeaderOnly
|
|
||||||
INTERFACE
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
|
||||||
)
|
|
||||||
TARGET_SOURCES(LtsUtilsCoreHeaderOnly INTERFACE ${SRCS_hdr_only})
|
|
||||||
|
|
||||||
SET(SRCS
|
|
||||||
pgarray.cpp
|
|
||||||
qplane3d.cpp
|
|
||||||
qpoint3d.cpp
|
|
||||||
scoped_connection.cpp
|
|
||||||
sfm_bytemessage_converter.cpp
|
|
||||||
promise.cpp
|
|
||||||
lts_translatable_identifier.cpp
|
|
||||||
lts_portrange.cpp
|
|
||||||
#variant_operators.h
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(ALL LtsUtilsCore SHARED ${SRCS})
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsUtilsCore
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
|
||||||
)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsUtilsCore
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
LtsUtilsCoreHeaderOnly
|
|
||||||
)
|
|
||||||
-1149
File diff suppressed because it is too large.
Load diff
-55
@@ -1,55 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
class LtsUtilsTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private Q_SLOTS:
|
|
||||||
|
|
||||||
void test_toIntArray();
|
|
||||||
void test_fromIntArray();
|
|
||||||
void test_toBigintArray();
|
|
||||||
void test_fromBigintArray();
|
|
||||||
void test_toIntArray2D();
|
|
||||||
void test_fromIntArray2D();
|
|
||||||
void test_toBigintArray2D();
|
|
||||||
void test_fromBigintArray2D();
|
|
||||||
|
|
||||||
void test_QPoint3D();
|
|
||||||
|
|
||||||
void test_bitArray();
|
|
||||||
|
|
||||||
void test_convert();
|
|
||||||
|
|
||||||
void test_connection();
|
|
||||||
void test_queuedConnection();
|
|
||||||
void test_signalSignalConnection();
|
|
||||||
void test_danglingConnection1();
|
|
||||||
void test_danglingConnection2();
|
|
||||||
void test_danglingConnection3();
|
|
||||||
|
|
||||||
void test_jsonObject_fromJson();
|
|
||||||
void test_jsonObject_contains();
|
|
||||||
void test_jsonObject_value();
|
|
||||||
void test_jsonObject_valueWithError();
|
|
||||||
void test_jsonObject_valueOr();
|
|
||||||
void test_jsonObject_integers();
|
|
||||||
void test_jsonObject_nullValues();
|
|
||||||
void test_jsonArray_fromJson();
|
|
||||||
void test_jsonArray();
|
|
||||||
void test_jsonArray_nullArray();
|
|
||||||
|
|
||||||
void test_byteStreamFromSfmMessage();
|
|
||||||
void test_byteStreamFromSfmMessage2();
|
|
||||||
void test_byteStreamToSfmMessage();
|
|
||||||
|
|
||||||
void test_promise();
|
|
||||||
void test_promise_example1();
|
|
||||||
void test_promise_example2();
|
|
||||||
void test_promise_example3();
|
|
||||||
|
|
||||||
void byteAccess();
|
|
||||||
};
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
template <typename Func> void addConnect(QEventLoop &x, bool &success, const typename QtPrivate::FunctionPointer<Func>::Object *sender, Func signal, bool isSuccess)
|
|
||||||
{
|
|
||||||
if (isSuccess)
|
|
||||||
{
|
|
||||||
QObject::connect(sender, signal, &x, [&success]() { success = true; });
|
|
||||||
}
|
|
||||||
|
|
||||||
QObject::connect(sender, signal, &x, &QEventLoop::quit, Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Func, typename... Connect>
|
|
||||||
void addConnect(QEventLoop &x, bool &success, const typename QtPrivate::FunctionPointer<Func>::Object *sender, Func signal, bool isSuccess, Connect... connects)
|
|
||||||
{
|
|
||||||
addConnect(x, success, sender, signal, isSuccess);
|
|
||||||
addConnect(x, success, connects...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Connect> void await(Connect... connects) noexcept(false)
|
|
||||||
{
|
|
||||||
QEventLoop x;
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
addConnect(x, success, connects...);
|
|
||||||
|
|
||||||
x.exec();
|
|
||||||
|
|
||||||
if (!success)
|
|
||||||
{
|
|
||||||
|
|
||||||
throw std::runtime_error("Failed.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename... Connect> void awaitTimeout(const int timeoutMs, Connect... connects) noexcept(false)
|
|
||||||
{
|
|
||||||
std::unique_ptr<QTimer> t(new QTimer);
|
|
||||||
bool timeout = false;
|
|
||||||
|
|
||||||
if (timeoutMs > -1)
|
|
||||||
{
|
|
||||||
t->setInterval(timeoutMs);
|
|
||||||
t->setSingleShot(true);
|
|
||||||
QObject::connect(t.get(),
|
|
||||||
&QTimer::timeout,
|
|
||||||
t.get(),
|
|
||||||
[&timeout]()
|
|
||||||
{
|
|
||||||
fprintf(stderr, "awaitTimeout: timed out!\n");
|
|
||||||
timeout = true;
|
|
||||||
});
|
|
||||||
t->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
await(t.get(), &QTimer::timeout, false, connects...);
|
|
||||||
|
|
||||||
if (timeout)
|
|
||||||
{
|
|
||||||
|
|
||||||
throw std::runtime_error("Timeout.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Func1, typename Func2>
|
|
||||||
void awaitWithCancelationSignal(const typename QtPrivate::FunctionPointer<Func1>::Object *sender1,
|
|
||||||
Func1 signal1,
|
|
||||||
const typename QtPrivate::FunctionPointer<Func2>::Object *sender2,
|
|
||||||
Func2 signal2,
|
|
||||||
const int timeoutMs = 0) noexcept(false)
|
|
||||||
{
|
|
||||||
if (timeoutMs > 0)
|
|
||||||
{
|
|
||||||
awaitTimeout(timeoutMs, sender1, signal1, true, sender2, signal2, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await(sender1, signal1, true, sender2, signal2, false);
|
|
||||||
}
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QMetaObject>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QPointer>
|
|
||||||
#include <QtGlobal>
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class IConnection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~IConnection() = default;
|
|
||||||
virtual void connect(Qt::ConnectionType = Qt::AutoConnection) = 0;
|
|
||||||
virtual void disconnect() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DummyConnection : public IConnection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void connect(Qt::ConnectionType = Qt::AutoConnection) override {}
|
|
||||||
|
|
||||||
void disconnect() override {}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template <class T> struct ExtractClass;
|
|
||||||
|
|
||||||
template <class T, class Member> struct ExtractClass<Member T::*>
|
|
||||||
{
|
|
||||||
using type = T;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
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<Slot>, "Must be a pointer to method");
|
|
||||||
|
|
||||||
using Emitter = typename detail::ExtractClass<Signal>::type;
|
|
||||||
using Target = typename detail::ExtractClass<Slot>::type;
|
|
||||||
|
|
||||||
static_assert(std::is_base_of_v<QObject, Emitter>, "Must be derived from QObject");
|
|
||||||
static_assert(std::is_base_of_v<QObject, Target>, "Must be derived from QObject");
|
|
||||||
|
|
||||||
public:
|
|
||||||
Connection(Emitter *emitter, Signal signal, Target *target, Slot slot)
|
|
||||||
: m_emitter(emitter)
|
|
||||||
, m_signal(signal)
|
|
||||||
, m_target(target)
|
|
||||||
, m_slot(slot)
|
|
||||||
{
|
|
||||||
Q_ASSERT(emitter);
|
|
||||||
Q_ASSERT(signal);
|
|
||||||
Q_ASSERT(target);
|
|
||||||
Q_ASSERT(slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
void connect(Qt::ConnectionType connectionType = Qt::AutoConnection) override
|
|
||||||
{
|
|
||||||
Q_ASSERT(!m_connected);
|
|
||||||
|
|
||||||
m_connected = true;
|
|
||||||
|
|
||||||
if (!m_emitter || !m_target)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_conn = QObject::connect(m_emitter.data(), m_signal, m_target.data(), m_slot, connectionType);
|
|
||||||
Q_ASSERT(m_conn);
|
|
||||||
}
|
|
||||||
|
|
||||||
void disconnect() override
|
|
||||||
{
|
|
||||||
Q_ASSERT(m_connected);
|
|
||||||
|
|
||||||
if (m_conn)
|
|
||||||
QObject::disconnect(m_conn);
|
|
||||||
|
|
||||||
m_connected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_connected{false};
|
|
||||||
QPointer<Emitter> m_emitter;
|
|
||||||
Signal m_signal;
|
|
||||||
QPointer<Target> m_target;
|
|
||||||
Slot m_slot;
|
|
||||||
QMetaObject::Connection m_conn;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Signal, class Slot>
|
|
||||||
Connection<Signal, Slot> *createConnection(typename detail::ExtractClass<Signal>::type *emitter,
|
|
||||||
Signal signal,
|
|
||||||
typename detail::ExtractClass<Slot>::type *target,
|
|
||||||
Slot slot)
|
|
||||||
{
|
|
||||||
return new Connection<Signal, Slot>(emitter, signal, target, slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
enum class DataModification
|
|
||||||
{
|
|
||||||
eAdded,
|
|
||||||
eModified,
|
|
||||||
eRemoved
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &str, DataModification mod)
|
|
||||||
{
|
|
||||||
switch (mod)
|
|
||||||
{
|
|
||||||
case DataModification::eAdded:
|
|
||||||
str << "DataModification::eAdded";
|
|
||||||
break;
|
|
||||||
case DataModification::eModified:
|
|
||||||
str << "DataModification::eModified";
|
|
||||||
break;
|
|
||||||
case DataModification::eRemoved:
|
|
||||||
str << "DataModification::eRemoved";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef SUPPORT_QBITARRAY
|
|
||||||
#include <QtCore/QBitArray>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace BitArray
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
*oob = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (oob)
|
|
||||||
*oob = false;
|
|
||||||
|
|
||||||
const typename T::value_type mask = 1 << bitNumber(position);
|
|
||||||
return ((bitField.at(byteNum) & mask) == mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline bool setBit(T &bitField, int position, bool set = true)
|
|
||||||
{
|
|
||||||
const size_t byteNum = position / 8;
|
|
||||||
if (byteNum >= bitField.size())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const typename T::value_type mask = 1 << bitNumber(position);
|
|
||||||
if (set)
|
|
||||||
bitField[byteNum] |= mask;
|
|
||||||
else
|
|
||||||
bitField[byteNum] &= ~mask;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline bool clearBit(T &bitField, int position)
|
|
||||||
{
|
|
||||||
return setBit(bitField, position, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SUPPORT_QBITARRAY
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
const size_t byteNum = i / 8;
|
|
||||||
const typename T::value_type mask = (1 << bitNumber(i));
|
|
||||||
if (bitArray[i])
|
|
||||||
ret[byteNum] |= mask;
|
|
||||||
else
|
|
||||||
ret[byteNum] &= ~mask;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline QBitArray convert(T &bitField, int realSize)
|
|
||||||
{
|
|
||||||
QBitArray ba(realSize);
|
|
||||||
for (int32_t i = 0; i < realSize; ++i)
|
|
||||||
{
|
|
||||||
const size_t byteNum = i / 8;
|
|
||||||
const typename T::value_type mask = (1 << bitNumber(i));
|
|
||||||
bool bit = ((bitField[byteNum] & mask) == mask);
|
|
||||||
ba[i] = bit;
|
|
||||||
}
|
|
||||||
return ba;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace BitArray
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
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");
|
|
||||||
out.reserve(static_cast<int>(in.size()));
|
|
||||||
std::copy(in.begin(), in.end(), std::back_inserter(out));
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
T out;
|
|
||||||
convert(in, out);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline QByteArray toQByteArray(const T &in)
|
|
||||||
{
|
|
||||||
return convert<QByteArray>(in);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename V = typename T::value_type> bool isInVector(const T &vec, const V &valueToSearch)
|
|
||||||
{
|
|
||||||
const auto end = vec.end();
|
|
||||||
return std::find(vec.begin(), end, valueToSearch) != end;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class QByteArray;
|
|
||||||
class QPixmap;
|
|
||||||
class QImage;
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QPixmap getPixmap(const std::vector<uint8_t> &data);
|
|
||||||
LTSUTILSCORE_EXPORT QPixmap getPixmap(const QByteArray &data);
|
|
||||||
LTSUTILSCORE_EXPORT QImage getImage(const std::vector<uint8_t> &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> fromImage(const QImage &image, bool *bIsPng = nullptr);
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#include <LtsUtilsCore/json_object.h>
|
|
||||||
@@ -1,579 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QJsonArray>
|
|
||||||
#include <QtCore/QJsonDocument>
|
|
||||||
#include <QtCore/QJsonObject>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QtCore/QJsonValue>
|
|
||||||
#include <QtCore/QMap>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <exception>
|
|
||||||
#include <limits>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class JsonParseError : public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
JsonParseError(const QJsonParseError &err)
|
|
||||||
: std::runtime_error("json parse error: " + err.errorString().toStdString() + " - at offset " + std::to_string(err.offset))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonError : public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using std::runtime_error::runtime_error;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonKeyError : public JsonError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using JsonError::JsonError;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonRangeError : public JsonError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using JsonError::JsonError;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonTypeError : public JsonError
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using JsonError::JsonError;
|
|
||||||
};
|
|
||||||
|
|
||||||
class JsonObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class Key;
|
|
||||||
|
|
||||||
JsonObject() = default;
|
|
||||||
|
|
||||||
explicit JsonObject(const QJsonObject &json)
|
|
||||||
: m_json(json)
|
|
||||||
, m_jsonIsSet(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit JsonObject(QJsonObject &&json)
|
|
||||||
: m_json(std::move(json))
|
|
||||||
, m_jsonIsSet(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline JsonObject fromJson(const char *json, int len = -1);
|
|
||||||
|
|
||||||
static inline JsonObject fromJson(const QByteArray &json) { return fromJson(json.data(), json.size()); }
|
|
||||||
|
|
||||||
static inline JsonObject fromJson(const std::string &json) { return fromJson(json.c_str(), json.size()); }
|
|
||||||
|
|
||||||
static inline JsonObject fromJsonSafe(const char *json, int len = -1) noexcept(false);
|
|
||||||
|
|
||||||
static inline JsonObject fromJsonSafe(const QByteArray &json) noexcept(false) { return fromJsonSafe(json.data(), json.size()); }
|
|
||||||
|
|
||||||
static inline JsonObject fromJsonSafe(const std::string &json) noexcept(false) { return fromJsonSafe(json.c_str(), json.size()); }
|
|
||||||
|
|
||||||
template <class T> [[nodiscard]] bool contains(const Key &key) const;
|
|
||||||
|
|
||||||
[[nodiscard]] bool isNull(const Key &key) const { return contains<void>(key); }
|
|
||||||
|
|
||||||
[[nodiscard]] bool isEmpty() const { return m_json.isEmpty(); }
|
|
||||||
|
|
||||||
[[nodiscard]] bool isValid() const { return m_jsonIsSet; }
|
|
||||||
|
|
||||||
template <class T> T value(const Key &key) const noexcept(false);
|
|
||||||
|
|
||||||
template <class T> T valueOr(const Key &key, const T &defaultValue) const noexcept(false);
|
|
||||||
|
|
||||||
template <class T> [[nodiscard]] bool isMap() const;
|
|
||||||
|
|
||||||
template <class T> QMap<QString, T> toMap() const noexcept(false);
|
|
||||||
|
|
||||||
template <class T> std::map<std::string, T> toStdMap() const;
|
|
||||||
|
|
||||||
bool operator==(const JsonObject &other) const { return m_json == other.m_json; }
|
|
||||||
|
|
||||||
bool operator!=(const JsonObject &other) const { return !(*this == other); }
|
|
||||||
|
|
||||||
class Key
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Key(QString s)
|
|
||||||
: m_s(std::move(s))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Key(const std::string &s)
|
|
||||||
: m_s(QString::fromStdString(s))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Key(const char *s)
|
|
||||||
: m_s(QString::fromUtf8(s))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
operator const QString &() const { return m_s; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString m_s;
|
|
||||||
};
|
|
||||||
|
|
||||||
operator const QJsonObject &() const { return m_json; }
|
|
||||||
|
|
||||||
[[nodiscard]] const QJsonObject &object() const { return m_json; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
[[nodiscard]] bool containsAny(const QString &key) const { return m_json.contains(key); }
|
|
||||||
|
|
||||||
QJsonObject m_json;
|
|
||||||
bool m_jsonIsSet = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
JsonObject JsonObject::fromJson(const char *json, int len)
|
|
||||||
{
|
|
||||||
if (len < 0)
|
|
||||||
len = strlen(json);
|
|
||||||
QJsonParseError error;
|
|
||||||
const auto doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
|
|
||||||
if (error.error != QJsonParseError::NoError)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (!doc.isObject())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
return JsonObject(doc.object());
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonObject JsonObject::fromJsonSafe(const char *json, int len) noexcept(false)
|
|
||||||
{
|
|
||||||
if (len < 0)
|
|
||||||
len = strlen(json);
|
|
||||||
QJsonParseError error;
|
|
||||||
const auto doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
|
|
||||||
if (error.error != QJsonParseError::NoError)
|
|
||||||
throw JsonParseError(error);
|
|
||||||
|
|
||||||
if (!doc.isObject())
|
|
||||||
throw JsonTypeError("JSON root is not an object");
|
|
||||||
|
|
||||||
return JsonObject(doc.object());
|
|
||||||
}
|
|
||||||
|
|
||||||
class JsonArray
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
JsonArray() = default;
|
|
||||||
|
|
||||||
explicit JsonArray(const QJsonArray &json)
|
|
||||||
: m_json(json)
|
|
||||||
, m_jsonIsSet(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit JsonArray(QJsonArray &&json)
|
|
||||||
: m_json(std::move(json))
|
|
||||||
, m_jsonIsSet(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline JsonArray fromJson(const char *json, int len = -1);
|
|
||||||
|
|
||||||
static inline JsonArray fromJson(const QByteArray &json) { return fromJson(json.data(), json.size()); }
|
|
||||||
|
|
||||||
static inline JsonArray fromJson(const std::string &json) { return fromJson(json.c_str(), json.size()); }
|
|
||||||
|
|
||||||
static inline JsonArray fromJsonSafe(const char *json, int len = -1) noexcept(false);
|
|
||||||
|
|
||||||
static inline JsonArray fromJsonSafe(const QByteArray &json) noexcept(false) { return fromJson(json.data(), json.size()); }
|
|
||||||
|
|
||||||
static inline JsonArray fromJsonSafe(const std::string &json) noexcept(false) { return fromJson(json.c_str(), json.size()); }
|
|
||||||
|
|
||||||
[[nodiscard]] int size() const { return m_json.size(); }
|
|
||||||
|
|
||||||
[[nodiscard]] bool isEmpty() const { return m_json.isEmpty(); }
|
|
||||||
|
|
||||||
[[nodiscard]] bool isValid() const { return m_jsonIsSet; }
|
|
||||||
|
|
||||||
template <class T> [[nodiscard]] bool contains(int index) const noexcept(false);
|
|
||||||
|
|
||||||
[[nodiscard]] bool isNull(int index) const noexcept(false) { return contains<void>(index); }
|
|
||||||
|
|
||||||
template <class T> T at(int index) const noexcept(false);
|
|
||||||
|
|
||||||
template <class T> [[nodiscard]] bool isVector() const;
|
|
||||||
|
|
||||||
template <class T> QVector<T> toVector() const noexcept(false);
|
|
||||||
|
|
||||||
template <class T> std::vector<T> toStdVector() const;
|
|
||||||
|
|
||||||
bool operator==(const JsonArray &other) const { return m_json == other.m_json; }
|
|
||||||
|
|
||||||
bool operator!=(const JsonArray &other) const { return !(*this == other); }
|
|
||||||
|
|
||||||
const QJsonArray &operator()() const { return m_json; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QJsonArray m_json;
|
|
||||||
bool m_jsonIsSet = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
JsonArray JsonArray::fromJson(const char *json, int len)
|
|
||||||
{
|
|
||||||
if (len < 0)
|
|
||||||
len = strlen(json);
|
|
||||||
QJsonParseError error;
|
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
|
|
||||||
if (error.error != QJsonParseError::NoError)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (!doc.isArray())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
return JsonArray(doc.array());
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonArray JsonArray::fromJsonSafe(const char *json, int len) noexcept(false)
|
|
||||||
{
|
|
||||||
if (len < 0)
|
|
||||||
len = strlen(json);
|
|
||||||
QJsonParseError error;
|
|
||||||
const auto doc = QJsonDocument::fromJson(QByteArray::fromRawData(json, len), &error);
|
|
||||||
if (error.error != QJsonParseError::NoError)
|
|
||||||
throw JsonParseError(error);
|
|
||||||
|
|
||||||
if (!doc.isArray())
|
|
||||||
throw JsonTypeError("JSON root is not an array");
|
|
||||||
|
|
||||||
return JsonArray(doc.array());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> struct JsonValue;
|
|
||||||
|
|
||||||
template <class Int> struct JsonLimits
|
|
||||||
{
|
|
||||||
static constexpr Int lowest() { return std::numeric_limits<Int>::lowest(); }
|
|
||||||
|
|
||||||
static constexpr Int max() { return std::numeric_limits<Int>::max(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonLimits<int64_t>
|
|
||||||
{
|
|
||||||
static constexpr int64_t lowest() { return -(static_cast<int64_t>(1) << 53) + 1; }
|
|
||||||
|
|
||||||
static constexpr int64_t max() { return (static_cast<int64_t>(1) << 53) - 1; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonLimits<uint64_t>
|
|
||||||
{
|
|
||||||
static constexpr uint64_t lowest() { return 0; }
|
|
||||||
|
|
||||||
static constexpr uint64_t max() { return JsonLimits<int64_t>::max(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class Int> struct JsonIntValue
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
if (!value.isDouble())
|
|
||||||
return false;
|
|
||||||
double val = value.toDouble();
|
|
||||||
|
|
||||||
if (val < JsonLimits<Int>::lowest())
|
|
||||||
return false;
|
|
||||||
if (val > JsonLimits<Int>::max())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
double wholeInt = static_cast<Int>(val);
|
|
||||||
return val == wholeInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Int value(const QJsonValue &value) noexcept(false)
|
|
||||||
{
|
|
||||||
if (!matchesType(value))
|
|
||||||
throw JsonTypeError("JSON value not of type Int");
|
|
||||||
return static_cast<Int>(value.toDouble());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<int16_t> : JsonIntValue<int16_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<uint16_t> : JsonIntValue<uint16_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<int32_t> : JsonIntValue<int32_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<uint32_t> : JsonIntValue<uint32_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<int64_t> : JsonIntValue<int64_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<uint64_t> : JsonIntValue<uint64_t>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<double>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isDouble(); }
|
|
||||||
|
|
||||||
static double value(const QJsonValue &value) noexcept(false)
|
|
||||||
{
|
|
||||||
if (!matchesType(value))
|
|
||||||
throw JsonTypeError("JSON value not of type Double");
|
|
||||||
return value.toDouble();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<bool>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isBool(); }
|
|
||||||
|
|
||||||
static bool value(const QJsonValue &value) noexcept(false)
|
|
||||||
{
|
|
||||||
if (!matchesType(value))
|
|
||||||
throw JsonTypeError("JSON value not of type Bool");
|
|
||||||
return value.toBool();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<QString>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isString(); }
|
|
||||||
|
|
||||||
static QString value(const QJsonValue &value) noexcept(false)
|
|
||||||
{
|
|
||||||
if (!matchesType(value))
|
|
||||||
throw JsonTypeError("JSON value not of type String");
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<std::string>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isString(); }
|
|
||||||
|
|
||||||
static std::string value(const QJsonValue &value) { return JsonValue<QString>::value(value).toStdString(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<QJsonObject>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isObject(); }
|
|
||||||
|
|
||||||
static QJsonObject value(const QJsonValue &value) noexcept(false)
|
|
||||||
{
|
|
||||||
if (!matchesType(value))
|
|
||||||
throw JsonTypeError("JSON value not of type Object");
|
|
||||||
return value.toObject();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<JsonObject>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isObject(); }
|
|
||||||
|
|
||||||
static JsonObject value(const QJsonValue &value) { return JsonObject(JsonValue<QJsonObject>::value(value)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<void>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isNull(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<QJsonArray>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isArray(); }
|
|
||||||
|
|
||||||
static QJsonArray value(const QJsonValue &value) noexcept(false)
|
|
||||||
{
|
|
||||||
if (!matchesType(value))
|
|
||||||
throw JsonTypeError("JSON value not of type Array");
|
|
||||||
return value.toArray();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <> struct JsonValue<JsonArray>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return value.isArray(); }
|
|
||||||
|
|
||||||
static JsonArray value(const QJsonValue &value) { return JsonArray(JsonValue<QJsonArray>::value(value)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T> struct JsonValue<QVector<T>>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
if (!value.isArray())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const JsonArray array(value.toArray());
|
|
||||||
return array.isVector<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
static QVector<T> value(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
const JsonArray array(JsonValue<QJsonArray>::value(value));
|
|
||||||
return array.toVector<T>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T> struct JsonValue<std::vector<T>>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return JsonValue<QVector<T>>::matchesType(value); }
|
|
||||||
|
|
||||||
static std::vector<T> value(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
const JsonArray array(JsonValue<QJsonArray>::value(value));
|
|
||||||
return array.toStdVector<T>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T> struct JsonValue<QMap<QString, T>>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
if (!value.isObject())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const JsonObject obj(JsonValue<QJsonObject>::value(value));
|
|
||||||
return obj.isMap<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
static QMap<QString, T> value(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
const JsonObject obj(JsonValue<QJsonObject>::value(value));
|
|
||||||
return obj.toMap<T>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T> struct JsonValue<std::map<std::string, T>>
|
|
||||||
{
|
|
||||||
static bool matchesType(const QJsonValue &value) { return JsonValue<QMap<QString, T>>::matchesType(value); }
|
|
||||||
|
|
||||||
static std::map<std::string, T> value(const QJsonValue &value)
|
|
||||||
{
|
|
||||||
const JsonObject obj(JsonValue<QJsonObject>::value(value));
|
|
||||||
return obj.toStdMap<T>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class T> bool JsonObject::contains(const Key &key) const
|
|
||||||
{
|
|
||||||
if (!m_json.contains(key))
|
|
||||||
return false;
|
|
||||||
return JsonValue<T>::matchesType(m_json.value(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> T JsonObject::value(const Key &key) const noexcept(false)
|
|
||||||
{
|
|
||||||
if (!containsAny(key))
|
|
||||||
throw JsonKeyError("no element with key: " + static_cast<const QString &>(key).toStdString());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return JsonValue<T>::value(m_json.value(key));
|
|
||||||
}
|
|
||||||
catch (const JsonTypeError &typeError)
|
|
||||||
{
|
|
||||||
throw JsonTypeError(std::string(typeError.what()) + " - key: " + static_cast<const QString &>(key).toStdString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> T JsonObject::valueOr(const Key &key, const T &defaultValue) const
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return value<T>(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (const JsonKeyError &)
|
|
||||||
{
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> bool JsonObject::isMap() const
|
|
||||||
{
|
|
||||||
const QStringList keys = m_json.keys();
|
|
||||||
for (const auto &key : keys)
|
|
||||||
if (!JsonValue<T>::matchesType(m_json.value(key)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> QMap<QString, T> JsonObject::toMap() const
|
|
||||||
{
|
|
||||||
QMap<QString, T> result;
|
|
||||||
for (auto current = m_json.begin(); current != m_json.end(); ++current)
|
|
||||||
result.insert(current.key(), JsonValue<T>::value(current.value()));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> std::map<std::string, T> JsonObject::toStdMap() const
|
|
||||||
{
|
|
||||||
std::map<std::string, T> result;
|
|
||||||
for (auto current = m_json.begin(); current != m_json.end(); ++current)
|
|
||||||
result.insert({current.key().toStdString(), JsonValue<T>::value(current.value())});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> bool JsonArray::contains(int index) const noexcept(false)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= m_json.size())
|
|
||||||
throw JsonRangeError("index out of range: " + std::to_string(index));
|
|
||||||
return JsonValue<T>::matchesType(m_json.at(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> T JsonArray::at(int index) const noexcept(false)
|
|
||||||
{
|
|
||||||
if (index < 0 || index >= m_json.size())
|
|
||||||
throw JsonRangeError("index out of range: " + std::to_string(index));
|
|
||||||
return JsonValue<T>::value(m_json.at(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> bool JsonArray::isVector() const
|
|
||||||
{
|
|
||||||
for (const QJsonValue &value : m_json)
|
|
||||||
if (!JsonValue<T>::matchesType(value))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> QVector<T> JsonArray::toVector() const
|
|
||||||
{
|
|
||||||
QVector<T> result;
|
|
||||||
result.reserve(m_json.size());
|
|
||||||
for (const QJsonValue &value : m_json)
|
|
||||||
result.push_back(JsonValue<T>::value(value));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T> std::vector<T> JsonArray::toStdVector() const
|
|
||||||
{
|
|
||||||
std::vector<T> result;
|
|
||||||
result.reserve(m_json.size());
|
|
||||||
for (const QJsonValue &value : m_json)
|
|
||||||
result.push_back(JsonValue<T>::value(value));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#include "lts_portrange.h"
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsUtils::LtsPortRange fromQPoint(const QPoint &point)
|
|
||||||
{
|
|
||||||
if (point.x() < 1025 || point.y() > 65535 || point.x() > point.y())
|
|
||||||
return {};
|
|
||||||
|
|
||||||
return {static_cast<quint16>(point.x()), static_cast<quint16>(point.y())};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QPair>
|
|
||||||
#include <QtCore/QPoint>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
typedef QPair<quint16, quint16> LtsPortRange;
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT LtsPortRange fromQPoint(const QPoint &point);
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_translatable_identifier.h"
|
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
LtsTranslatableIdentifier::LtsTranslatableIdentifier(const QString &identifier, const QObject *context, const char *translatableText)
|
|
||||||
: m_identifier(identifier)
|
|
||||||
, m_translationContext(context->metaObject()->className())
|
|
||||||
, m_translatableText(translatableText)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString LtsTranslatableIdentifier::translatedText(const char *disambiguation, int n) const
|
|
||||||
{
|
|
||||||
if (m_identifier.isEmpty() || m_translationContext == nullptr || m_translatableText == nullptr)
|
|
||||||
return {};
|
|
||||||
return QCoreApplication::translate(m_translationContext, m_translatableText, disambiguation, n);
|
|
||||||
}
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
class LTSUTILSCORE_EXPORT LtsTranslatableIdentifier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
LtsTranslatableIdentifier()
|
|
||||||
: m_translationContext(nullptr)
|
|
||||||
, m_translatableText("")
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsTranslatableIdentifier(const QString &identifier, const QObject *context, const char *translatableText);
|
|
||||||
|
|
||||||
const QString &identifier() const { return m_identifier; }
|
|
||||||
|
|
||||||
const QString translatedText(const char *disambiguation = nullptr, int n = -1) const;
|
|
||||||
|
|
||||||
const QString _context() const { return QString::fromUtf8(m_translationContext); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_identifier;
|
|
||||||
const char *m_translationContext;
|
|
||||||
|
|
||||||
const char *m_translatableText;
|
|
||||||
};
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Export definitions for LtsUtilsCore
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
|
|
||||||
#ifndef LTSUTILSCORE_EXPORT
|
|
||||||
#ifdef BUILD_STATIC_LIBRARIES
|
|
||||||
#define LTSUTILSCORE_EXPORT
|
|
||||||
#else
|
|
||||||
#if defined(MAKE_LTSUTILSCORE_LIB)
|
|
||||||
#define LTSUTILSCORE_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
#define LTSUTILSCORE_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <qglobal.h>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
inline bool isPositionTimeOutdated(qint64 curTime, qint64 posTime)
|
|
||||||
{
|
|
||||||
|
|
||||||
return curTime > posTime + 11 * 60 * 1000;
|
|
||||||
}
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "pgarray.h"
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
#include <QStringView>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <functional>
|
|
||||||
#include <ltsutilscore_export.h>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename T> static inline QString convertToPgString(const std::vector<T> &data)
|
|
||||||
{
|
|
||||||
if (data.size() == 0)
|
|
||||||
return QLatin1String("{}");
|
|
||||||
QString ret(QLatin1Char('{'));
|
|
||||||
for (T i : data)
|
|
||||||
ret += QString::number(i) + QLatin1Char(',');
|
|
||||||
ret.chop(1);
|
|
||||||
ret += QLatin1Char('}');
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString IntArray::toPgString() const
|
|
||||||
{
|
|
||||||
return convertToPgString(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString BigintArray::toPgString() const
|
|
||||||
{
|
|
||||||
return convertToPgString(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> static inline T convertFromPgString(const QString &str, const std::function<typename T::Type(QStringView val, bool *bOk)> &convertFunc)
|
|
||||||
{
|
|
||||||
typename T::ContainerType result;
|
|
||||||
|
|
||||||
int idxStart = str.indexOf(QLatin1Char('{'));
|
|
||||||
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
|
||||||
if (idxEnd < idxStart)
|
|
||||||
return T(result);
|
|
||||||
if (idxStart < 0 && idxEnd < 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
idxStart = -1;
|
|
||||||
idxEnd = str.length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QStringView strRef = QStringView(str).mid(idxStart + 1, idxEnd - idxStart - 1);
|
|
||||||
const QVector<QStringView> vec = strRef.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
|
||||||
result.reserve(vec.size());
|
|
||||||
for (const QStringView &s : vec)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
const typename T::Type i = convertFunc(s, &ok);
|
|
||||||
if (ok)
|
|
||||||
result.push_back(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return T(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT IntArray IntArray::fromPgString(const QString &str)
|
|
||||||
{
|
|
||||||
return convertFromPgString<IntArray>(str, [](QStringView val, bool *bOk) { return val.toString().toInt(bOk); });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT BigintArray BigintArray::fromPgString(const QString &str)
|
|
||||||
{
|
|
||||||
return convertFromPgString<BigintArray>(str, [](QStringView val, bool *bOk) { return val.toString().toLongLong(bOk); });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> static inline QString convertToPgString(const std::map<T, T> &data)
|
|
||||||
{
|
|
||||||
if (data.size() == 0)
|
|
||||||
return QLatin1String("{}");
|
|
||||||
QString ret(QLatin1Char('{'));
|
|
||||||
for (const auto &it : data)
|
|
||||||
{
|
|
||||||
ret += QLatin1Char('{') + QString::number(it.first) + QLatin1Char(',') + QString::number(it.second) + QLatin1String("},");
|
|
||||||
}
|
|
||||||
ret.chop(1);
|
|
||||||
ret += QLatin1Char('}');
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString IntArray2D::toPgString() const
|
|
||||||
{
|
|
||||||
return convertToPgString<IntArray2D::Type>(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT QString BigintArray2D::toPgString() const
|
|
||||||
{
|
|
||||||
return convertToPgString<BigintArray2D::Type>(m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> static inline T convertFromPgString2D(const QString &str, const std::function<typename T::Type(QStringView val)> &convertFunc)
|
|
||||||
{
|
|
||||||
typename T::ContainerType ret;
|
|
||||||
int idxStart = str.indexOf(QLatin1Char('{'));
|
|
||||||
int idxEnd = str.lastIndexOf(QLatin1Char('}'));
|
|
||||||
if (idxEnd < idxStart)
|
|
||||||
return T(ret);
|
|
||||||
if (idxStart < 0 && idxEnd < 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
idxStart = -1;
|
|
||||||
idxEnd = str.length() + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QStringView strRef = QStringView(str).mid(idxStart + 1, idxEnd - idxStart - 1);
|
|
||||||
idxStart = strRef.indexOf(QLatin1Char('{'));
|
|
||||||
while (idxStart >= 0)
|
|
||||||
{
|
|
||||||
idxEnd = strRef.indexOf(QLatin1Char('}'), idxStart);
|
|
||||||
if (idxEnd < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
const QStringView keyValueStr = strRef.mid(idxStart + 1, idxEnd - idxStart - 1);
|
|
||||||
const QVector<QStringView> keyValuePair = keyValueStr.split(QLatin1Char(','), Qt::SkipEmptyParts);
|
|
||||||
if (keyValuePair.size() != 2)
|
|
||||||
break;
|
|
||||||
const typename T::Type key = convertFunc(keyValuePair.at(0).trimmed());
|
|
||||||
const typename T::Type value = convertFunc(keyValuePair.at(1).trimmed());
|
|
||||||
ret.insert(std::make_pair(key, value));
|
|
||||||
|
|
||||||
idxStart = strRef.indexOf(QLatin1Char('{'), idxEnd + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return T(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT IntArray2D IntArray2D::fromPgString(const QString &str)
|
|
||||||
{
|
|
||||||
return convertFromPgString2D<IntArray2D>(str, [](QStringView val) { return val.toString().toInt(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> LTSUTILSCORE_EXPORT BigintArray2D BigintArray2D::fromPgString(const QString &str)
|
|
||||||
{
|
|
||||||
return convertFromPgString2D<BigintArray2D>(str, [](QStringView val) { return val.toString().toLongLong(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename T, typename C> class PgArray
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using Type = T;
|
|
||||||
using ContainerType = C;
|
|
||||||
|
|
||||||
PgArray() = default;
|
|
||||||
|
|
||||||
Q_DECL_CONSTEXPR explicit PgArray(const C &data)
|
|
||||||
: m_data(data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_CONSTEXPR C operator()() const { return m_data; }
|
|
||||||
|
|
||||||
[[nodiscard]] QString toPgString() const;
|
|
||||||
static PgArray fromPgString(const QString &str);
|
|
||||||
|
|
||||||
private:
|
|
||||||
C m_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
using IntArray = PgArray<int, std::vector<int>>;
|
|
||||||
using BigintArray = PgArray<int64_t, std::vector<int64_t>>;
|
|
||||||
|
|
||||||
using IntArray2D = PgArray<int, std::map<int, int>>;
|
|
||||||
using BigintArray2D = PgArray<int64_t, std::map<int64_t, int64_t>>;
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "promise.h"
|
|
||||||
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
m_timeout->setSingleShot(true);
|
|
||||||
connect(m_timeout, &QTimer::timeout, this, &Promise::slotTimeout);
|
|
||||||
setFunction(function);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Promise::setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function)
|
|
||||||
{
|
|
||||||
if (!function || m_functionAlreadySet)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_functionAlreadySet = true;
|
|
||||||
|
|
||||||
if (m_timeoutSet)
|
|
||||||
m_timeout->start();
|
|
||||||
|
|
||||||
QTimer::singleShot(0, this, [this, function]() { function([this](const QVariant &value) { resolve(value); }, [this](const QVariant &value) { reject(value); }); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void Promise::setTimeout(int interval)
|
|
||||||
{
|
|
||||||
m_timeout->stop();
|
|
||||||
m_timeout->setInterval(interval);
|
|
||||||
m_timeoutSet = (interval != 0);
|
|
||||||
|
|
||||||
if (interval != 0 && m_functionAlreadySet)
|
|
||||||
m_timeout->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Promise::slotTimeout()
|
|
||||||
{
|
|
||||||
reject(QStringLiteral("timeout"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Promise::resolve(const QVariant &value)
|
|
||||||
{
|
|
||||||
if (m_resultSet)
|
|
||||||
return;
|
|
||||||
m_resultSet = true;
|
|
||||||
|
|
||||||
m_timeout->stop();
|
|
||||||
m_resolveFn(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Promise::reject(const QVariant &value)
|
|
||||||
{
|
|
||||||
if (m_resultSet)
|
|
||||||
return;
|
|
||||||
m_resultSet = true;
|
|
||||||
|
|
||||||
m_timeout->stop();
|
|
||||||
m_rejectFn(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise &Promise::resolved(ResultFunction resolveFn)
|
|
||||||
{
|
|
||||||
m_resolveFn = resolveFn;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Promise &Promise::rejected(ResultFunction rejectFn)
|
|
||||||
{
|
|
||||||
m_rejectFn = rejectFn;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QVariant>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
typedef std::function<void(const QVariant &value)> RawResultFunction;
|
|
||||||
typedef const RawResultFunction &ResultFunction;
|
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT Promise : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
Promise(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function, QObject *parent = nullptr);
|
|
||||||
|
|
||||||
void setFunction(const std::function<void(ResultFunction resolve, ResultFunction reject)> &function);
|
|
||||||
|
|
||||||
void resolve(const QVariant &value = QVariant());
|
|
||||||
|
|
||||||
void reject(const QVariant &value = QVariant());
|
|
||||||
|
|
||||||
void setTimeout(int interval);
|
|
||||||
|
|
||||||
Promise &resolved(ResultFunction resolveFn);
|
|
||||||
|
|
||||||
Promise &rejected(ResultFunction rejectFn);
|
|
||||||
|
|
||||||
private:
|
|
||||||
RawResultFunction m_resolveFn;
|
|
||||||
RawResultFunction m_rejectFn;
|
|
||||||
bool m_functionAlreadySet;
|
|
||||||
QTimer *m_timeout;
|
|
||||||
bool m_resultSet;
|
|
||||||
bool m_timeoutSet;
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotTimeout();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
#include "promise_examples.h"
|
|
||||||
|
|
||||||
#include "promise.h"
|
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
#include <QtTest/QTest>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
void PromiseExample1_Class::doSomethingAsync1()
|
|
||||||
{
|
|
||||||
QTimer::singleShot(200, this, [this]() { emit signalDone1(true); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void PromiseExample1_Class::doSomethingAsync2()
|
|
||||||
{
|
|
||||||
QTimer::singleShot(450, this, [this]() { emit signalDone2(true, 1234); });
|
|
||||||
}
|
|
||||||
|
|
||||||
PromiseExample1::PromiseExample1(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_success(false)
|
|
||||||
{
|
|
||||||
|
|
||||||
auto func = [this](ResultFunction resolve, ResultFunction reject)
|
|
||||||
{
|
|
||||||
PromiseExample1_Class *c = new PromiseExample1_Class(this);
|
|
||||||
|
|
||||||
connect(c,
|
|
||||||
&PromiseExample1_Class::signalDone1,
|
|
||||||
this,
|
|
||||||
[this, c, resolve, reject](bool didThisWork)
|
|
||||||
{
|
|
||||||
if (!didThisWork)
|
|
||||||
{
|
|
||||||
|
|
||||||
reject(QStringLiteral("First Action did not succeed"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
connect(c,
|
|
||||||
&PromiseExample1_Class::signalDone2,
|
|
||||||
this,
|
|
||||||
[resolve, reject](bool didThisWork, int someNumberThatReturns)
|
|
||||||
{
|
|
||||||
if (didThisWork)
|
|
||||||
resolve(someNumberThatReturns);
|
|
||||||
else
|
|
||||||
reject(QStringLiteral("Second Action did not succeed"));
|
|
||||||
});
|
|
||||||
|
|
||||||
c->doSomethingAsync2();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
c->doSomethingAsync1();
|
|
||||||
};
|
|
||||||
Promise *p = new Promise(func, this);
|
|
||||||
|
|
||||||
p->resolved(
|
|
||||||
[this](const QVariant &value)
|
|
||||||
{
|
|
||||||
qDebug() << "example1 promise succeeded! 'someNumberThatReturns' was" << value;
|
|
||||||
|
|
||||||
m_success = true;
|
|
||||||
})
|
|
||||||
.rejected([](const QVariant &value) { qDebug() << "example1 promise failed.." << value; });
|
|
||||||
}
|
|
||||||
|
|
||||||
PromiseExample2::PromiseExample2(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_success(false)
|
|
||||||
{
|
|
||||||
|
|
||||||
Promise* p = new Promise(
|
|
||||||
[](ResultFunction, ResultFunction) {
|
|
||||||
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
|
|
||||||
p->setTimeout(1000);
|
|
||||||
|
|
||||||
p->resolved([](const QVariant &) { QFAIL("This test case's promise should never resolve"); });
|
|
||||||
|
|
||||||
p->rejected(
|
|
||||||
[this](const QVariant &val)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
|
|
||||||
Promise *p = new Promise([](ResultFunction, ResultFunction reject) { reject(QString()); }, this);
|
|
||||||
|
|
||||||
p->setTimeout(1000);
|
|
||||||
|
|
||||||
p->resolved([](const QVariant &) { QFAIL("This test case's promise should never resolve"); });
|
|
||||||
|
|
||||||
p->rejected(
|
|
||||||
[this](const QVariant &val)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
qDebug() << "Promise rejected as expected";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class PromiseExample1_Class : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
using QObject::QObject;
|
|
||||||
|
|
||||||
void doSomethingAsync1();
|
|
||||||
void doSomethingAsync2();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void signalDone1(bool didThisWork);
|
|
||||||
void signalDone2(bool didThisWork, int someNumberThatReturns);
|
|
||||||
};
|
|
||||||
|
|
||||||
class PromiseExample1 : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PromiseExample1(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
[[nodiscard]] bool isSuccess() const { return m_success; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_success;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PromiseExample2 : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PromiseExample2(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
[[nodiscard]] bool isSuccess() const { return m_success; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_success;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PromiseExample3 : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PromiseExample3(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
[[nodiscard]] bool isSuccess() const { return m_success; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_success;
|
|
||||||
bool m_alreadyRejected;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-243
@@ -1,243 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
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");
|
|
||||||
out += (in & 0xFF00000000000000UL) >> 56;
|
|
||||||
out += (in & 0x00FF000000000000UL) >> 48;
|
|
||||||
out += (in & 0x0000FF0000000000UL) >> 40;
|
|
||||||
out += (in & 0x000000FF00000000UL) >> 32;
|
|
||||||
out += (in & 0x00000000FF000000UL) >> 24;
|
|
||||||
out += (in & 0x0000000000FF0000UL) >> 16;
|
|
||||||
out += (in & 0x000000000000FF00UL) >> 8;
|
|
||||||
out += (in & 0x00000000000000FFUL);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> void inline set8Byte(const double in, QByteArray &out)
|
|
||||||
{
|
|
||||||
union hack
|
|
||||||
{
|
|
||||||
double d;
|
|
||||||
int64_t i;
|
|
||||||
} h;
|
|
||||||
|
|
||||||
h.d = in;
|
|
||||||
set8Byte(h.i, 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(sizeof(T) >= 8, "sizeof(out) is smaller than 8 bytes - will not fit");
|
|
||||||
out = T();
|
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 8)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char *data = baData.data() + pos;
|
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
|
||||||
out |= static_cast<signed long long>(data[0]) << 56;
|
|
||||||
else
|
|
||||||
out |= (data[0] & 0xFFULL) << 56;
|
|
||||||
out |= (data[1] & 0xFFULL) << 48;
|
|
||||||
out |= (data[2] & 0xFFULL) << 40;
|
|
||||||
out |= (data[3] & 0xFFULL) << 32;
|
|
||||||
out |= (data[4] & 0xFFULL) << 24;
|
|
||||||
out |= (data[5] & 0xFFULL) << 16;
|
|
||||||
out |= (data[6] & 0xFFULL) << 8;
|
|
||||||
out |= (data[7] & 0xFFULL);
|
|
||||||
|
|
||||||
pos += 8;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> bool inline get8Byte(const QByteArray &baData, size_t &pos, double &out)
|
|
||||||
{
|
|
||||||
out = 0.;
|
|
||||||
|
|
||||||
union hack
|
|
||||||
{
|
|
||||||
double d;
|
|
||||||
int64_t i;
|
|
||||||
} h;
|
|
||||||
|
|
||||||
if (!get8Byte(baData, pos, h.i))
|
|
||||||
return false;
|
|
||||||
out = h.d;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool inline get8Byte(const QByteArray &data, T &out)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
return get8Byte(data, pos, 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");
|
|
||||||
out += (in & 0xFF000000) >> 24;
|
|
||||||
out += (in & 0x00FF0000) >> 16;
|
|
||||||
out += (in & 0x0000FF00) >> 8;
|
|
||||||
out += (in & 0x000000FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> void inline set4Byte(const double in, QByteArray &out)
|
|
||||||
{
|
|
||||||
int tmp = qRound(in);
|
|
||||||
return set4Byte(tmp, 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(sizeof(T) >= 4, "sizeof(out) is smaller than 4 bytes - will not fit");
|
|
||||||
out = T();
|
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 4)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char *data = baData.data() + pos;
|
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
|
||||||
out |= data[0] << 24;
|
|
||||||
else
|
|
||||||
out |= (data[0] & 0xFFU) << 24;
|
|
||||||
out |= (data[1] & 0xFFU) << 16;
|
|
||||||
out |= (data[2] & 0xFFU) << 8;
|
|
||||||
out |= (data[3] & 0xFFU);
|
|
||||||
|
|
||||||
pos += 4;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> bool inline get4Byte(const QByteArray &baData, size_t &pos, double &out)
|
|
||||||
{
|
|
||||||
out = 0.;
|
|
||||||
int tmp;
|
|
||||||
if (!get4Byte(baData, pos, tmp))
|
|
||||||
return false;
|
|
||||||
out = tmp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool inline get4Byte(const QByteArray &data, T &out)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
return get4Byte(data, pos, 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");
|
|
||||||
out += (in & 0x00FF0000) >> 16;
|
|
||||||
out += (in & 0x0000FF00) >> 8;
|
|
||||||
out += (in & 0x000000FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(sizeof(T) >= 3, "sizeof(out) is smaller than 3 bytes - will not fit");
|
|
||||||
out = T();
|
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char *data = baData.data() + pos;
|
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
|
||||||
out |= data[0] << 16;
|
|
||||||
else
|
|
||||||
out |= (data[0] & 0xFFU) << 16;
|
|
||||||
out |= (data[1] & 0xFFU) << 8;
|
|
||||||
out |= (data[2] & 0xFFU);
|
|
||||||
|
|
||||||
pos += 3;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool inline get3Byte(const QByteArray &data, T &out)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
return get3Byte(data, pos, 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");
|
|
||||||
out += (in & 0x0000FF00) >> 8;
|
|
||||||
out += (in & 0x000000FF);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(sizeof(T) >= 2, "sizeof(out) is smaller than 2 bytes - will not fit");
|
|
||||||
out = T();
|
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const char *data = baData.data() + pos;
|
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
|
||||||
out |= data[0] << 8;
|
|
||||||
else
|
|
||||||
out |= (data[0] & 0xFFU) << 8;
|
|
||||||
out |= data[1] & 0xFFU;
|
|
||||||
|
|
||||||
pos += 2;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool inline get2Byte(const QByteArray &data, T &out)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
return get2Byte(data, pos, 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");
|
|
||||||
unsigned char c = static_cast<unsigned char>(in);
|
|
||||||
out += c;
|
|
||||||
}
|
|
||||||
|
|
||||||
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");
|
|
||||||
out = T();
|
|
||||||
|
|
||||||
if (size_t(baData.size()) < pos + 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (std::numeric_limits<T>::is_signed)
|
|
||||||
out = (T)(baData.at(pos));
|
|
||||||
else
|
|
||||||
out = (T)(baData.at(pos) & 0xFF);
|
|
||||||
|
|
||||||
pos += 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> bool inline get1Byte(const QByteArray &data, T &out)
|
|
||||||
{
|
|
||||||
size_t pos = 0;
|
|
||||||
return get1Byte(data, pos, out);
|
|
||||||
}
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
#include "qplane3d.h"
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
QPlane3D::QPlane3D(const QPoint3D &pos, const QPoint3D &vec1, const QPoint3D &vec2)
|
|
||||||
: m_pos(pos)
|
|
||||||
, m_vec1(vec1)
|
|
||||||
, m_vec2(vec2)
|
|
||||||
{
|
|
||||||
m_normal = QPoint3D::crossProduct(m_vec1, m_vec2);
|
|
||||||
m_planeC = QPoint3D::dotProduct(m_pos, m_normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPoint3D QPlane3D::intersection(const QPoint3D &point, const QPoint3D &direction) const
|
|
||||||
{
|
|
||||||
const double dotProduct = QPoint3D::dotProduct(direction, m_normal);
|
|
||||||
if (qFuzzyIsNull(dotProduct))
|
|
||||||
return inPlane(point) ? point : QPoint3D();
|
|
||||||
const double distance = distanceTo(point) / std::abs(dotProduct);
|
|
||||||
return point + distance * direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QPlane3D::intersects(const QPoint3D &direction) const
|
|
||||||
{
|
|
||||||
return !isParallel(direction);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QPlane3D::isParallel(const QPoint3D &direction) const
|
|
||||||
{
|
|
||||||
return qFuzzyIsNull(QPoint3D::dotProduct(m_normal, direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QPlane3D::inPlane(const QPoint3D &point) const
|
|
||||||
{
|
|
||||||
if (point == m_pos)
|
|
||||||
return true;
|
|
||||||
return qFuzzyIsNull(QPoint3D::dotProduct(m_normal, point - m_pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
double QPlane3D::distanceTo(const QPoint3D &point) const
|
|
||||||
{
|
|
||||||
return QPoint3D::dotProduct(point - m_pos, m_normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
QPolygon3D::QPolygon3D(const QVector<QPoint3D> &vertices)
|
|
||||||
: QPlane3D(vertices[0], vertices[1], vertices[2])
|
|
||||||
, m_vertices(vertices)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QPolygon3D::containsPoint(const QPoint3D &point) const
|
|
||||||
{
|
|
||||||
if (!inPlane(point))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (contains(point))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
double angleSum = 0.;
|
|
||||||
double cosTheta = 0.;
|
|
||||||
const int numberOfVertices = m_vertices.size();
|
|
||||||
for (int i = 0; i < m_vertices.size(); ++i)
|
|
||||||
{
|
|
||||||
const QPoint3D &first = m_vertices[i % numberOfVertices] - point;
|
|
||||||
const QPoint3D &second = m_vertices[(i + 1) % numberOfVertices] - point;
|
|
||||||
|
|
||||||
cosTheta = QPoint3D::dotProduct(first, second) / (first.length() * second.length());
|
|
||||||
angleSum += acos(cosTheta);
|
|
||||||
}
|
|
||||||
return qFuzzyIsNull(M_2_PI - angleSum);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
#include "qpoint3d.h"
|
|
||||||
|
|
||||||
#include <QtCore/QPointF>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT QPlane3D
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
QPlane3D(const QPoint3D &pos, const QPoint3D &vec1, const QPoint3D &vec2);
|
|
||||||
|
|
||||||
QPoint3D intersection(const QPoint3D &point, const QPoint3D &direction) const;
|
|
||||||
bool intersects(const QPoint3D &direction) const;
|
|
||||||
bool isParallel(const QPoint3D &direction) const;
|
|
||||||
bool inPlane(const QPoint3D &point) const;
|
|
||||||
double distanceTo(const QPoint3D &point) const;
|
|
||||||
|
|
||||||
const QPoint3D &pos() const { return m_pos; }
|
|
||||||
|
|
||||||
const QPoint3D &vec1() const { return m_vec1; }
|
|
||||||
|
|
||||||
const QPoint3D &vec2() const { return m_vec2; }
|
|
||||||
|
|
||||||
const QPoint3D &normal() const { return m_normal; }
|
|
||||||
|
|
||||||
double planeC() const { return m_planeC; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
QPoint3D m_pos;
|
|
||||||
QPoint3D m_vec1;
|
|
||||||
QPoint3D m_vec2;
|
|
||||||
QPoint3D m_normal;
|
|
||||||
double m_planeC;
|
|
||||||
};
|
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT QPolygon3D : public QPlane3D
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
QPolygon3D(const QVector<QPoint3D> &vertices);
|
|
||||||
|
|
||||||
bool contains(const QPoint3D &point) const { return m_vertices.contains(point); }
|
|
||||||
|
|
||||||
bool containsPoint(const QPoint3D &point) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVector<QPoint3D> m_vertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "qpoint3d.h"
|
|
||||||
|
|
||||||
#include <QtCore/QDataStream>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
QDataStream &operator<<(QDataStream &s, const QPoint3D &p)
|
|
||||||
{
|
|
||||||
s << p.x() << p.y() << p.z();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
QDataStream &operator>>(QDataStream &s, QPoint3D &p)
|
|
||||||
{
|
|
||||||
double x, y, z;
|
|
||||||
s >> x;
|
|
||||||
p.rx() = x;
|
|
||||||
s >> y;
|
|
||||||
p.ry() = y;
|
|
||||||
s >> z;
|
|
||||||
p.rz() = z;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,287 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
#include <QtCore/qpoint.h>
|
|
||||||
#include <QtCore/qdatastream.h>
|
|
||||||
#include <cmath>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class QPoint3D
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
enum class Axis
|
|
||||||
{
|
|
||||||
X,
|
|
||||||
Y,
|
|
||||||
Z
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr QPoint3D() = default;
|
|
||||||
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())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isNull() const;
|
|
||||||
|
|
||||||
constexpr inline double x() const;
|
|
||||||
constexpr inline double y() const;
|
|
||||||
constexpr inline double z() const;
|
|
||||||
constexpr inline void setX(double xpos);
|
|
||||||
constexpr inline void setY(double ypos);
|
|
||||||
constexpr inline void setZ(double zpos);
|
|
||||||
|
|
||||||
constexpr inline double &rx();
|
|
||||||
constexpr inline double &ry();
|
|
||||||
constexpr inline double &rz();
|
|
||||||
|
|
||||||
constexpr inline QPointF toPointF() const;
|
|
||||||
|
|
||||||
static QPoint3D fromQPointF(const QPointF &p) { return QPoint3D(p.x(), p.y(), .0); }
|
|
||||||
|
|
||||||
inline double lengthSquared() const { return (xp * xp) + (yp * yp) + (zp * zp); }
|
|
||||||
|
|
||||||
inline double length() const { return std::sqrt(lengthSquared()); }
|
|
||||||
|
|
||||||
inline void normalize()
|
|
||||||
{
|
|
||||||
double len = xp * xp + yp * yp + zp * zp;
|
|
||||||
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
|
|
||||||
return;
|
|
||||||
|
|
||||||
len = std::sqrt(len);
|
|
||||||
|
|
||||||
xp /= len;
|
|
||||||
yp /= len;
|
|
||||||
zp /= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QPoint3D normalized() const
|
|
||||||
{
|
|
||||||
double len = xp * xp + yp * yp + zp * zp;
|
|
||||||
if (qFuzzyIsNull(len - 1.0f))
|
|
||||||
return *this;
|
|
||||||
else if (!qFuzzyIsNull(len))
|
|
||||||
return *this / std::sqrt(len);
|
|
||||||
else
|
|
||||||
return QPoint3D(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void rotate(const double &phi, const Axis &axis)
|
|
||||||
{
|
|
||||||
const double sin = std::sin(phi);
|
|
||||||
const double cos = std::cos(phi);
|
|
||||||
switch (axis)
|
|
||||||
{
|
|
||||||
case Axis::X:
|
|
||||||
{
|
|
||||||
const double _yp = (cos * yp) - (sin * zp);
|
|
||||||
const double _zp = (sin * yp) + (cos * zp);
|
|
||||||
yp = _yp;
|
|
||||||
zp = _zp;
|
|
||||||
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
|
|
||||||
{
|
|
||||||
QPoint3D p(*this);
|
|
||||||
p.rotate(phi, axis);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 { 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline QPoint3D &operator-=(const QPoint3D &o)
|
|
||||||
{
|
|
||||||
xp -= o.xp;
|
|
||||||
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:
|
|
||||||
double xp = 0;
|
|
||||||
double yp = 0;
|
|
||||||
double zp = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// QDataStream& operator<<(QDataStream& s, const QPoint3D& p);
|
|
||||||
// QDataStream& operator>>(QDataStream& s, QPoint3D& p);
|
|
||||||
|
|
||||||
constexpr inline QPoint3D::QPoint3D(double xpos, double ypos, double zpos)
|
|
||||||
: xp(xpos)
|
|
||||||
, yp(ypos)
|
|
||||||
, zp(zpos)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool QPoint3D::isNull() const
|
|
||||||
{
|
|
||||||
return qIsNull(xp) && qIsNull(yp) && qIsNull(zp);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double QPoint3D::x() const
|
|
||||||
{
|
|
||||||
return xp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double QPoint3D::y() const
|
|
||||||
{
|
|
||||||
return yp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double QPoint3D::z() const
|
|
||||||
{
|
|
||||||
return zp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline void QPoint3D::setX(double xpos)
|
|
||||||
{
|
|
||||||
xp = xpos;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline void QPoint3D::setY(double ypos)
|
|
||||||
{
|
|
||||||
yp = ypos;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline void QPoint3D::setZ(double zpos)
|
|
||||||
{
|
|
||||||
zp = zpos;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double &QPoint3D::rx()
|
|
||||||
{
|
|
||||||
return xp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double &QPoint3D::ry()
|
|
||||||
{
|
|
||||||
return yp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline double &QPoint3D::rz()
|
|
||||||
{
|
|
||||||
return zp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline QPointF QPoint3D::toPointF() const
|
|
||||||
{
|
|
||||||
return QPointF(xp, yp);
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline bool operator==(const QPoint3D &p1, const QPoint3D &p2)
|
|
||||||
{
|
|
||||||
return p1.xp == p2.xp && p1.yp == p2.yp && p1.zp == p2.zp;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr inline bool operator!=(const QPoint3D &p1, const QPoint3D &p2)
|
|
||||||
{
|
|
||||||
return p1.xp != p2.xp || p1.yp != p2.yp || p1.zp != p2.zp;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &stream, const QPoint3D &pos)
|
|
||||||
{
|
|
||||||
stream << "(" << pos.x() << "," << pos.y() << "," << pos.z() << ")";
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
|
|
||||||
// Q_DECLARE_METATYPE(LtsUtils::QPoint3D)
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "scoped_connection.h"
|
|
||||||
|
|
||||||
#include "connection.h"
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
ScopedConnection::ScopedConnection(IConnection *connection, Qt::ConnectionType connType)
|
|
||||||
: m_conn(connection)
|
|
||||||
{
|
|
||||||
Q_ASSERT(connection);
|
|
||||||
m_conn->connect(connType);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedConnection::~ScopedConnection()
|
|
||||||
{
|
|
||||||
m_conn->disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <Qt>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class IConnection;
|
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT ScopedConnection
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit ScopedConnection(IConnection *connection, Qt::ConnectionType = Qt::AutoConnection);
|
|
||||||
~ScopedConnection();
|
|
||||||
|
|
||||||
private:
|
|
||||||
IConnection *m_conn;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-283
@@ -1,283 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "sfm_bytemessage_converter.h"
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
static constexpr unsigned char XON = 0x11;
|
|
||||||
static constexpr unsigned char XOFF = 0x13;
|
|
||||||
static constexpr unsigned char STX = 0x02;
|
|
||||||
static constexpr unsigned char ETX = 0x03;
|
|
||||||
static constexpr unsigned char SUBST = 0x80;
|
|
||||||
|
|
||||||
static constexpr unsigned char SUB_XON = 0x91;
|
|
||||||
static constexpr unsigned char SUB_XOFF = 0x93;
|
|
||||||
static constexpr unsigned char SUB_STX = 0x82;
|
|
||||||
static constexpr unsigned char SUB_ETX = 0x83;
|
|
||||||
static constexpr unsigned char SUB_SUBST = 0x00;
|
|
||||||
|
|
||||||
static constexpr int HEADER_SIZE = 3;
|
|
||||||
static constexpr int CHECKSUM_SIZE = 1;
|
|
||||||
static constexpr int MINIMUM_BYTE_SIZE = 1 + HEADER_SIZE + CHECKSUM_SIZE + 1;
|
|
||||||
|
|
||||||
static SfmMessage getSfmMessage(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
|
|
||||||
unsigned short id = 0;
|
|
||||||
id |= (((unsigned short)p_data[0]) & 0x7F) << 8;
|
|
||||||
id |= (((unsigned short)p_data[1]) & 0xFF) << 0;
|
|
||||||
|
|
||||||
SfmMessage msg;
|
|
||||||
msg.setId(id);
|
|
||||||
msg.setRtr(p_data[0] & 0x80);
|
|
||||||
msg.setPayload(p_data.right(p_data.size() - HEADER_SIZE));
|
|
||||||
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray getHeader(const SfmMessage &p_msg)
|
|
||||||
{
|
|
||||||
QByteArray header(2, Qt::Uninitialized);
|
|
||||||
|
|
||||||
header[0] = ((p_msg.id() >> 8) & 0x7f) | (p_msg.rtr() << 7);
|
|
||||||
|
|
||||||
header[1] = (p_msg.id() >> 0) & 0xff;
|
|
||||||
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char getChecksum(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
char sum = 0;
|
|
||||||
|
|
||||||
for (const char c : p_data)
|
|
||||||
sum += c;
|
|
||||||
|
|
||||||
return sum ^ 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray removeChecksum(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
QByteArray withoutChecksum(p_data);
|
|
||||||
ConversionError error("Checksum error");
|
|
||||||
|
|
||||||
if (p_data.size() >= CHECKSUM_SIZE)
|
|
||||||
{
|
|
||||||
withoutChecksum.chop(1);
|
|
||||||
|
|
||||||
if (p_data.at(p_data.size() - 1) != getChecksum(withoutChecksum))
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw error;
|
|
||||||
|
|
||||||
return withoutChecksum;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray maskData(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
QByteArray maskData;
|
|
||||||
maskData.reserve(p_data.size() * 8 / 6);
|
|
||||||
|
|
||||||
for (const unsigned char byte : p_data)
|
|
||||||
{
|
|
||||||
switch (byte)
|
|
||||||
{
|
|
||||||
case XON:
|
|
||||||
maskData.append(SUBST);
|
|
||||||
maskData.append(SUB_XON);
|
|
||||||
break;
|
|
||||||
case XOFF:
|
|
||||||
maskData.append(SUBST);
|
|
||||||
maskData.append(SUB_XOFF);
|
|
||||||
break;
|
|
||||||
case STX:
|
|
||||||
maskData.append(SUBST);
|
|
||||||
maskData.append(SUB_STX);
|
|
||||||
break;
|
|
||||||
case ETX:
|
|
||||||
maskData.append(SUBST);
|
|
||||||
maskData.append(SUB_ETX);
|
|
||||||
break;
|
|
||||||
case SUBST:
|
|
||||||
maskData.append(SUBST);
|
|
||||||
maskData.append(static_cast<char>(SUB_SUBST));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
maskData.append(byte);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maskData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool mustBeMasked(const unsigned char byte)
|
|
||||||
{
|
|
||||||
switch (byte)
|
|
||||||
{
|
|
||||||
case XON:
|
|
||||||
case XOFF:
|
|
||||||
case STX:
|
|
||||||
case ETX:
|
|
||||||
case SUBST:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lenMaskedData(const QByteArray &data)
|
|
||||||
{
|
|
||||||
int ret = data.length();
|
|
||||||
const unsigned char upperLen = ((data.length() & 0xff00) >> 8);
|
|
||||||
const unsigned char lowerLen = ((data.length() & 0x00ff) >> 0);
|
|
||||||
if (mustBeMasked(upperLen))
|
|
||||||
++ret;
|
|
||||||
if (mustBeMasked(lowerLen))
|
|
||||||
++ret;
|
|
||||||
for (const unsigned char byte : data)
|
|
||||||
{
|
|
||||||
if (mustBeMasked(byte))
|
|
||||||
++ret;
|
|
||||||
}
|
|
||||||
if (mustBeMasked(getChecksum(data)))
|
|
||||||
++ret;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray unmaskData(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
QByteArray unmaskData;
|
|
||||||
unmaskData.reserve(p_data.size());
|
|
||||||
|
|
||||||
for (int position = 0; position < p_data.size(); ++position)
|
|
||||||
{
|
|
||||||
unsigned char byte = p_data.at(position);
|
|
||||||
if (byte == SUBST)
|
|
||||||
{
|
|
||||||
++position;
|
|
||||||
byte = p_data.at(position);
|
|
||||||
|
|
||||||
switch (byte)
|
|
||||||
{
|
|
||||||
case SUB_XON:
|
|
||||||
unmaskData.append(XON);
|
|
||||||
break;
|
|
||||||
case SUB_XOFF:
|
|
||||||
unmaskData.append(XOFF);
|
|
||||||
break;
|
|
||||||
case SUB_STX:
|
|
||||||
unmaskData.append(STX);
|
|
||||||
break;
|
|
||||||
case SUB_ETX:
|
|
||||||
unmaskData.append(ETX);
|
|
||||||
break;
|
|
||||||
case SUB_SUBST:
|
|
||||||
unmaskData.append(SUBST);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
unmaskData.append(byte);
|
|
||||||
}
|
|
||||||
return unmaskData;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray addFrame(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
QByteArray ret;
|
|
||||||
ret.reserve(2 + p_data.size());
|
|
||||||
ret.append(STX);
|
|
||||||
ret.append(p_data);
|
|
||||||
ret.append(ETX);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QByteArray removeFrame(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (p_data[0] == STX && p_data[p_data.size() - 1] == ETX)
|
|
||||||
{
|
|
||||||
|
|
||||||
return p_data.mid(1, p_data.size() - 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
throw ConversionError("Framing Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void checkLength(const QByteArray &p_data)
|
|
||||||
{
|
|
||||||
if (p_data.size() < HEADER_SIZE)
|
|
||||||
throw ConversionError("Telegram too short");
|
|
||||||
|
|
||||||
unsigned char length = p_data[HEADER_SIZE - 1];
|
|
||||||
if (length != p_data.size() - HEADER_SIZE)
|
|
||||||
throw ConversionError("Telegram length does not match");
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray byteStreamFromSfmMessage(const SfmMessage &message)
|
|
||||||
{
|
|
||||||
QByteArray byteData(getHeader(message));
|
|
||||||
|
|
||||||
byteData.append(message.payload().size());
|
|
||||||
byteData.append(message.payload());
|
|
||||||
byteData.append(getChecksum(byteData));
|
|
||||||
|
|
||||||
return addFrame(maskData(byteData));
|
|
||||||
}
|
|
||||||
|
|
||||||
SfmMessage byteStreamToSfmMessage(const QByteArray &datastream)
|
|
||||||
{
|
|
||||||
if (datastream.size() < MINIMUM_BYTE_SIZE)
|
|
||||||
throw ConversionError("Can't convert an QByteArray that hasn't the minimum size!");
|
|
||||||
|
|
||||||
QByteArray checkMsg;
|
|
||||||
|
|
||||||
checkMsg = removeFrame(datastream);
|
|
||||||
checkMsg = unmaskData(checkMsg);
|
|
||||||
|
|
||||||
checkMsg = removeChecksum(checkMsg);
|
|
||||||
|
|
||||||
checkLength(checkMsg);
|
|
||||||
|
|
||||||
return getSfmMessage(checkMsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray byteStreamFromEscMessage(const QByteArray &message)
|
|
||||||
{
|
|
||||||
QByteArray byteData = message;
|
|
||||||
if (message.size() == 1)
|
|
||||||
{
|
|
||||||
|
|
||||||
byteData.append(message);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
byteData.append(getChecksum(byteData));
|
|
||||||
|
|
||||||
byteData = maskData(byteData);
|
|
||||||
byteData = addFrame(byteData);
|
|
||||||
|
|
||||||
return byteData;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray byteStreamToEscMessage(const QByteArray &datastream)
|
|
||||||
{
|
|
||||||
if (datastream.size() < 2)
|
|
||||||
return QByteArray("ERROR");
|
|
||||||
|
|
||||||
QByteArray checkMsg;
|
|
||||||
|
|
||||||
checkMsg = removeFrame(datastream);
|
|
||||||
checkMsg = unmaskData(checkMsg);
|
|
||||||
|
|
||||||
checkMsg.chop(1);
|
|
||||||
return checkMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
-51
@@ -1,51 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "ltsutilscore_export.h"
|
|
||||||
|
|
||||||
#include <QtCore/QByteArray>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
class LTSUTILSCORE_EXPORT SfmMessage
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
unsigned int id() const { return m_id; }
|
|
||||||
|
|
||||||
void setId(unsigned int id) { m_id = id; }
|
|
||||||
|
|
||||||
bool rtr() const { return m_rtr; }
|
|
||||||
|
|
||||||
void setRtr(bool rtr) { m_rtr = rtr; }
|
|
||||||
|
|
||||||
QByteArray payload() const { return m_payload; }
|
|
||||||
|
|
||||||
void setPayload(const QByteArray &payload) { m_payload = payload; }
|
|
||||||
|
|
||||||
bool operator==(const SfmMessage &msg) const { return (m_id == msg.id() && m_rtr == msg.rtr() && m_payload == msg.payload()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
unsigned int m_id = 0;
|
|
||||||
bool m_rtr = false;
|
|
||||||
QByteArray m_payload;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConversionError : public std::runtime_error
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using std::runtime_error::runtime_error;
|
|
||||||
};
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QByteArray byteStreamFromSfmMessage(const SfmMessage &message);
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT SfmMessage byteStreamToSfmMessage(const QByteArray &datastream);
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QByteArray byteStreamFromEscMessage(const QByteArray &message);
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT QByteArray byteStreamToEscMessage(const QByteArray &datastream);
|
|
||||||
|
|
||||||
LTSUTILSCORE_EXPORT int lenMaskedData(const QByteArray &data);
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtCore/QDateTime>
|
|
||||||
#include <QtCore/QVariant>
|
|
||||||
#include <ngltools/ngltools_dtg.h>
|
|
||||||
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
|
|
||||||
inline bool lessThan(const QVariant &var1, const QVariant &var2)
|
|
||||||
{
|
|
||||||
if (var1.canConvert<QString>() && var2.canConvert<QString>())
|
|
||||||
{
|
|
||||||
QString str1(var1.toString());
|
|
||||||
QString str2(var2.toString());
|
|
||||||
|
|
||||||
bool k1 = false;
|
|
||||||
double d1 = str1.toDouble(&k1);
|
|
||||||
|
|
||||||
if (!k1)
|
|
||||||
return str1 < str2;
|
|
||||||
|
|
||||||
bool k2 = false;
|
|
||||||
double d2 = str2.toDouble(&k2);
|
|
||||||
|
|
||||||
if (!k2)
|
|
||||||
return str1 < str2;
|
|
||||||
|
|
||||||
return d1 < d2;
|
|
||||||
}
|
|
||||||
else if (var1.canConvert<double>() && var2.canConvert<double>())
|
|
||||||
return var1.toDouble() < var2.toDouble();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsUtils
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
# Created by Mike Wille, SLSE, 2016-09-19
|
|
||||||
#
|
|
||||||
|
|
||||||
# LtsUtilsGuiDds is needed by LtsMultiMonitor regardless of BUILD_RTI
|
|
||||||
# Exclude from release scope - requires DDS headers, only used by LtsMultiMonitor
|
|
||||||
if(NOT RELEASE_BUILD)
|
|
||||||
ADD_SUBDIRECTORY(LtsUtilsGuiDds)
|
|
||||||
endif()
|
|
||||||
ADD_SUBDIRECTORY(ConnectDialog)
|
|
||||||
ADD_SUBDIRECTORY(StyleManager)
|
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Mike Wille, SLSE, 2016-05-12
|
|
||||||
#
|
|
||||||
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
SET(srcs
|
|
||||||
connect_dialog.h
|
|
||||||
connect_dialog.cpp
|
|
||||||
connect_dialog_nt.h
|
|
||||||
connect_dialog_nt.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_WRAP_UI(srcs
|
|
||||||
connect_dialog.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(WS LtsUtilsGuiConnectDialog SHARED ${srcs})
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsUtilsGuiConnectDialog
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
|
||||||
)
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsUtilsGuiConnectDialog
|
|
||||||
${Qt6_Widgets}
|
|
||||||
LtsWidgets
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
Loaded 100 of 1364 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user