Adds q2 repos to migrate
No files matched your search
@@ -0,0 +1,289 @@
|
||||
#
|
||||
# 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.5.0)
|
||||
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}")
|
||||
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)
|
||||
SET(CMAKE_CXX_STANDARD 14)
|
||||
SET(CMAKE_CXX_STANDARD_REQUIRED 14)
|
||||
SET(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
|
||||
SET(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
||||
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()
|
||||
|
||||
IF(WIN32)
|
||||
SET(EXTERNAL_LIBRARY_DIR "C:/Development/Projekte/SituationMap/ExtFw" CACHE STRING "Library dir with all external dependencies")
|
||||
LIST(APPEND CMAKE_PREFIX_PATH "${EXTERNAL_LIBRARY_DIR}")
|
||||
LIST(APPEND CMAKE_PROGRAM_PATH "${EXTERNAL_LIBRARY_DIR}/bin;${EXTERNAL_LIBRARY_DIR}/dev-utils/bin")
|
||||
ENDIF()
|
||||
|
||||
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)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/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(QT_USE_IMPORTED_TARGETS TRUE)
|
||||
FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Concurrent Core Gui Location LinguistTools
|
||||
Network OpenGL PrintSupport Sensors Multimedia
|
||||
Sql Svg SerialPort Test UiTools WebSockets
|
||||
WebEngineCore WebEngineWidgets Widgets
|
||||
Xml XmlPatterns
|
||||
REQUIRED)
|
||||
|
||||
MESSAGE(STATUS "Qt version is ${Qt5Core_VERSION}")
|
||||
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(ETS_MODE "Build for ETS (No B-Contamination etc)" OFF)
|
||||
IF(ETS_MODE)
|
||||
ADD_DEFINITIONS(-DETS_MODE)
|
||||
ENDIF()
|
||||
OPTION(TABLET_MODE "Build for TABLET " OFF)
|
||||
IF(TABLET_MODE)
|
||||
ADD_DEFINITIONS(-DTABLET_MODE)
|
||||
ENDIF()
|
||||
|
||||
OPTION(GUEZ_MODE "Build for GUEZ " ON)
|
||||
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)
|
||||
|
||||
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()
|
||||
|
||||
|
||||
#
|
||||
# DDS benoetigt zwingend RTI
|
||||
#
|
||||
FIND_PACKAGE(RTI REQUIRED)
|
||||
|
||||
ADD_SUBDIRECTORY(TetraIF)
|
||||
ADD_SUBDIRECTORY(Z/src)
|
||||
ADD_SUBDIRECTORY(Lts)
|
||||
# at last, to make sure we get all targets in NGL_TS_TARGETS property
|
||||
ADD_SUBDIRECTORY(translations)
|
||||
#-----------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
OPTION(BUILD_QAV "Build script for local QAV analysis" OFF)
|
||||
IF (BUILD_QAV)
|
||||
ADD_SUBDIRECTORY(qav)
|
||||
ENDIF()
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(CoPrtCnv)
|
||||
ADD_SUBDIRECTORY(LogView)
|
||||
ADD_SUBDIRECTORY(PrtCnv)
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(my_SRCS
|
||||
tetra_telegram_ids.h
|
||||
CoPrtCnvCentralTelegram.cpp
|
||||
CoPrtCnvCentralTelegram.hpp
|
||||
CoPrtCnvHexDumpHelper.cpp
|
||||
CoPrtCnvHexDumpHelper.hpp
|
||||
CoPrtCnvInjectionHeader.hpp
|
||||
CoPrtCnvLogHeader.hpp
|
||||
CoPrtCnvRadioTelegram.cpp
|
||||
CoPrtCnvRadioTelegram.hpp
|
||||
CoPrtCnvTelegramConverter.hpp
|
||||
CoPrtCnvTelegramConverterNewIcd.cpp
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(AAR SV CoPrtCnv SHARED ${my_SRCS} ${my_HDRS})
|
||||
NGL_TARGET_LINK_LIBRARIES(CoPrtCnv
|
||||
PUBLIC
|
||||
NGLLogger
|
||||
tabTelegrams
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(CoPrtCnv
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
@@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
|
||||
#include "CoPrtCnvCentralTelegram.hpp"
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
|
||||
void CoPrtCnvCentralTelegram::setData(const QByteArray &data)
|
||||
{
|
||||
m_data = data;
|
||||
m_json = QJsonObject();
|
||||
}
|
||||
|
||||
QByteArray CoPrtCnvCentralTelegram::data()
|
||||
{
|
||||
ensureByteArray();
|
||||
return m_data;
|
||||
}
|
||||
|
||||
QJsonObject CoPrtCnvCentralTelegram::json()
|
||||
{
|
||||
ensureJson();
|
||||
return m_json;
|
||||
}
|
||||
|
||||
QJsonObject CoPrtCnvCentralTelegram::jsonData()
|
||||
{
|
||||
return json()[QStringLiteral("data")].toObject();
|
||||
}
|
||||
|
||||
TrainingAreaBase::TetraIcd::TelegramId CoPrtCnvCentralTelegram::telegramId()
|
||||
{
|
||||
if (m_telegramId != TrainingAreaBase::TetraIcd::UNKNOWN)
|
||||
return m_telegramId;
|
||||
|
||||
ensureJson();
|
||||
m_telegramId = static_cast<TrainingAreaBase::TetraIcd::TelegramId>(m_json[QStringLiteral("typeId")].toInt());
|
||||
return m_telegramId;
|
||||
}
|
||||
|
||||
void CoPrtCnvCentralTelegram::setCounter(qint32 counter)
|
||||
{
|
||||
if (m_json.isEmpty())
|
||||
m_json = QJsonDocument::fromJson(m_data).object();
|
||||
m_json[QStringLiteral("counter")] = counter;
|
||||
m_data.clear();
|
||||
}
|
||||
|
||||
qint32 CoPrtCnvCentralTelegram::counter()
|
||||
{
|
||||
ensureJson();
|
||||
const QString key(QStringLiteral("counter"));
|
||||
const QJsonValue sendCounter(m_json[key]);
|
||||
if (!sendCounter.isDouble())
|
||||
throw TrainingAreaBase::TetraIcd::JsonException(m_json, key);
|
||||
return sendCounter.toInt(-1);
|
||||
}
|
||||
|
||||
void CoPrtCnvCentralTelegram::ensureJson()
|
||||
{
|
||||
if (m_json.isEmpty())
|
||||
{
|
||||
if (m_data.isEmpty())
|
||||
return;
|
||||
m_json = QJsonDocument::fromJson(m_data).object();
|
||||
}
|
||||
}
|
||||
|
||||
void CoPrtCnvCentralTelegram::ensureByteArray()
|
||||
{
|
||||
if (m_data.isEmpty())
|
||||
{
|
||||
if (m_json.isEmpty())
|
||||
return;
|
||||
m_data = QJsonDocument(m_json).toJson(QJsonDocument::Compact);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QByteArray>
|
||||
#include <CoPrtCnv/coprtcnv_export.h>
|
||||
#include <TrainingAreaBase/training_area_telegrams.h>
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
|
||||
|
||||
class COPRTCNV_EXPORT CoPrtCnvCentralTelegram final
|
||||
{
|
||||
public:
|
||||
explicit CoPrtCnvCentralTelegram(TrainingAreaBase::TetraIcd::TelegramId telegramId)
|
||||
: m_telegramId(telegramId)
|
||||
{}
|
||||
explicit CoPrtCnvCentralTelegram(const QByteArray &data)
|
||||
: m_data(data)
|
||||
, m_telegramId(TrainingAreaBase::TetraIcd::UNKNOWN)
|
||||
{}
|
||||
CoPrtCnvCentralTelegram(const QByteArray &data, TrainingAreaBase::TetraIcd::TelegramId telegramId)
|
||||
: m_data(data)
|
||||
, m_telegramId(telegramId)
|
||||
{}
|
||||
CoPrtCnvCentralTelegram(const QByteArray &data, const QJsonObject &json, TrainingAreaBase::TetraIcd::TelegramId telegramId)
|
||||
: m_data(data)
|
||||
, m_json(json)
|
||||
, m_telegramId(telegramId)
|
||||
{}
|
||||
|
||||
explicit CoPrtCnvCentralTelegram(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram &tele)
|
||||
: m_telegramId(tele.id())
|
||||
{
|
||||
m_json[QStringLiteral("type")] = tele.type();
|
||||
m_json[QStringLiteral("typeId")] = tele.id();
|
||||
m_json[QStringLiteral("data")] = tele.toJson();
|
||||
}
|
||||
|
||||
void setData(const QByteArray &data);
|
||||
QByteArray data();
|
||||
QJsonObject json();
|
||||
QJsonObject jsonData();
|
||||
TrainingAreaBase::TetraIcd::TelegramId telegramId();
|
||||
void setCounter(qint32 counter);
|
||||
qint32 counter();
|
||||
|
||||
private:
|
||||
void ensureJson();
|
||||
void ensureByteArray();
|
||||
private:
|
||||
QByteArray m_data;
|
||||
QJsonObject m_json;
|
||||
TrainingAreaBase::TetraIcd::TelegramId m_telegramId;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "CoPrtCnvHexDumpHelper.hpp"
|
||||
#include "CoPrtCnvRadioTelegram.hpp"
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
static std::string dumpSammeldeaktivierung(const N_CoPrtCnv::CoPrtCnvRadioTelegram* sammelTelegram)
|
||||
{
|
||||
const int ANZAHL_POS = 5;
|
||||
const int SIZE_POS = sammelTelegram->getTelID() == GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN ? 2 : 1;
|
||||
|
||||
std::stringstream sstream;
|
||||
unsigned int cnt = sammelTelegram->getPayloadDataUInt32(ANZAHL_POS, SIZE_POS);
|
||||
for (unsigned int i = 0; i < cnt; ++i) {
|
||||
uint16_t telId = sammelTelegram->getPayloadDataUInt32(ANZAHL_POS + SIZE_POS + 2 * i, 2);
|
||||
sstream << telId << " ";
|
||||
}
|
||||
return sstream.str();
|
||||
}
|
||||
|
||||
QByteArray telegramId2String(gef_telegramm_id_et telId)
|
||||
{
|
||||
const char *str = nullptr;
|
||||
switch (telId)
|
||||
{
|
||||
case GEF_BESTAETIGUNG: str = "GEF_BESTAETIGUNG"; break;
|
||||
case GEF_INIT: str = "GEF_INIT"; break;
|
||||
case GEF_MANIPULATIONSMELDUNG: str = "GEF_MANIPULATIONSMELDUNG"; break;
|
||||
case GEF_UMGEBUNGS_MELDUNG2: str = "GEF_UMGEBUNGS_MELDUNG2"; break;
|
||||
case GEF_AUFFORDERUNG_BITE_MELDUNG: str = "GEF_AUFFORDERUNG_BITE_MELDUNG"; break;
|
||||
case GEF_BITE_MELDUNG2: str = "GEF_BITE_MELDUNG2"; break;
|
||||
case GEF_LIZENSIERUNG_TNE: str = "GEF_LIZENSIERUNG_TNE"; break;
|
||||
case GEF_BETRIEBSZUSTAND_AUSSTATTUNG: str = "GEF_BETRIEBSZUSTAND_AUSSTATTUNG"; break;
|
||||
case GEF_KONFIGURATION_WIRKMODELL: str = "GEF_KONFIGURATION_WIRKMODELL"; break;
|
||||
case GEF_ANFORDERUNG_KONFIGURATIONSDATEN: str = "GEF_ANFORDERUNG_KONFIGURATIONSDATEN"; break;
|
||||
case GEF_KONFIGURATIONSMELDUNG: str = "GEF_KONFIGURATIONSMELDUNG"; break;
|
||||
case GEF_FEHLERMELDUNG_GFD: str = "GEF_FEHLERMELDUNG_GFD"; break;
|
||||
case GEF_WIEDERHERSTELLUNG_FUNKBEREITSCHAFT: str = "GEF_WIEDERHERSTELLUNG_FUNKBEREITSCHAFT"; break;
|
||||
case GEF_POSITIONS_MELDUNG: str = "GEF_POSITIONS_MELDUNG"; break;
|
||||
case GEF_POSITIONS_MELDUNG_MIT_TEILNEHMER: str = "GEF_POSITIONS_MELDUNG_MIT_TEILNEHMER"; break;
|
||||
case GEF_POSITIONS_MELDUNG_LFZ: str = "GEF_POSITIONS_MELDUNG_LFZ"; break;
|
||||
case GEF_IPS_POSITIONSDATEN: str = "GEF_IPS_POSITIONSDATEN"; break;
|
||||
case GEF_SCHIEDSRICHTERKOMMANDO: str = "GEF_SCHIEDSRICHTERKOMMANDO"; break;
|
||||
case GEF_WIRKFELD_EINZELGESCHOSS: str = "GEF_WIRKFELD_EINZELGESCHOSS"; break;
|
||||
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER: str = "GEF_WIRKFELD_FLAECHENDECKENDES_FEUER"; break;
|
||||
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP: str = "GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP"; break;
|
||||
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN: str = "GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN"; break;
|
||||
case GEF_WIRKFELD_MINENSPERRE: str = "GEF_WIRKFELD_MINENSPERRE"; break;
|
||||
case GEF_WIRKFELD_STATUS_MINENSPERRE: str = "GEF_WIRKFELD_STATUS_MINENSPERRE"; break;
|
||||
case GEF_WIRKFELD_A_KAMPFMITTEL: str = "GEF_WIRKFELD_A_KAMPFMITTEL"; break;
|
||||
case GEF_WIRKFELD_C_KAMPFMITTEL: str = "GEF_WIRKFELD_C_KAMPFMITTEL"; break;
|
||||
case GEF_DEAKTIVIERUNG_WIRKFELD: str = "GEF_DEAKTIVIERUNG_WIRKFELD"; break;
|
||||
case GEF_WIRKFELD_AENDERUNG_BEZEICHNER: str = "GEF_WIRKFELD_AENDERUNG_BEZEICHNER"; break;
|
||||
case GEF_DEAKTIVIERUNG_EINZELMINE: str = "GEF_DEAKTIVIERUNG_EINZELMINE"; break;
|
||||
case GEF_REAKTIVIERUNG_DUS_MINE: str = "GEF_REAKTIVIERUNG_DUS_MINE"; break;
|
||||
case GEF_DEFINITION_IED: str = "GEF_DEFINITION_IED"; break;
|
||||
case GEF_ZUSTAND_IED: str = "GEF_ZUSTAND_IED"; break;
|
||||
case GEF_STATUS_EINZELMINENSIMULATOR: str = "GEF_STATUS_EINZELMINENSIMULATOR"; break;
|
||||
case GEF_WIRKFELD_EINZELMINENSIMULATOR: str = "GEF_WIRKFELD_EINZELMINENSIMULATOR"; break;
|
||||
case GEF_TREFFER_EREIGNIS_DUS: str = "GEF_TREFFER_EREIGNIS_DUS"; break;
|
||||
case GEF_TREFFER_EREIGNIS_WIRKSIMULATION: str = "GEF_TREFFER_EREIGNIS_WIRKSIMULATION"; break;
|
||||
case GEF_TREFFER_AUSLOESUNG: str = "GEF_TREFFER_AUSLOESUNG"; break;
|
||||
case GEF_SCHIEDSRICHTEREINGRIFF: str = "GEF_SCHIEDSRICHTEREINGRIFF"; break;
|
||||
case GEF_SELEKTIVE_AUFMUNITIONIERUNG: str = "GEF_SELEKTIVE_AUFMUNITIONIERUNG"; break;
|
||||
case GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG: str = "GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG"; break;
|
||||
case GEF_TREFFER_EREIGNIS_DUS_IPS: str = "GEF_TREFFER_EREIGNIS_DUS_IPS"; break;
|
||||
case GEF_TREFFER_EREIGNIS_WIRKSIMULATION_IPS: str = "GEF_TREFFER_EREIGNIS_WIRKSIMULATION_IPS"; break;
|
||||
case GEF_TAKTISCHER_STATUS: str = "GEF_TAKTISCHER_STATUS"; break;
|
||||
case GEF_FUNKTIONSRAUM: str = "GEF_FUNKTIONSRAUM"; break;
|
||||
case GEF_EINTRETEN_FUNKTIONSRAUM: str = "GEF_EINTRETEN_FUNKTIONSRAUM"; break;
|
||||
case GEF_DEAKTIVIEREN_FUNKTIONSRAUM: str = "GEF_DEAKTIVIEREN_FUNKTIONSRAUM"; break;
|
||||
case GEF_DATENVERKEHR_SRT_TDS: str = "GEF_DATENVERKEHR_SRT_TDS"; break;
|
||||
case GEF_DATENVERKEHR_TDS_SRT: str = "GEF_DATENVERKEHR_TDS_SRT"; break;
|
||||
case GEF_DATENVERKEHR_DMF_TDS: str = "GEF_DATENVERKEHR_DMF_TDS"; break;
|
||||
case GEF_DATENVERKEHR_TDS_DMF: str = "GEF_DATENVERKEHR_TDS_DMF"; break;
|
||||
case GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME: str = "GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME"; break;
|
||||
case GEF_NOP: str = "GEF_NOP"; break;
|
||||
case GEF_SONDERSENSORIK_BETRIEBSZUSTAND: str = "GEF_SONDERSENSORIK_BETRIEBSZUSTAND"; break;
|
||||
case GEF_SONDERSENSORIK_FAHRSPUR: str = "GEF_SONDERSENSORIK_FAHRSPUR"; break;
|
||||
case GEF_SONDERSENSORIK_DATEN: str = "GEF_SONDERSENSORIK_DATEN"; break;
|
||||
case GEF_SONDERSENSORIK_MIVANH_VERLEGEDATEN: str = "GEF_SONDERSENSORIK_MIVANH_VERLEGEDATEN"; break;
|
||||
case GEF_SONDERSENSORIK_WMIV_VERLEGEDATEN: str = "GEF_SONDERSENSORIK_WMIV_VERLEGEDATEN"; break;
|
||||
case GEF_SONDERSENSORIK_MIVANH_VERLEGEPOSITION: str = "GEF_SONDERSENSORIK_MIVANH_VERLEGEPOSITION"; break;
|
||||
case GEF_SPRACHAUSWAHL: str = "GEF_SPRACHAUSWAHL"; break;
|
||||
case GEF_ALLGEMEINE_NACHRICHT: str = "GEF_ALLGEMEINE_NACHRICHT"; break;
|
||||
case GEF_ECHO_ON_OFF: str = "GEF_ECHO_ON_OFF"; break;
|
||||
case GEF_ESW_MELDUNG: str = "GEF_ESW_MELDUNG"; break;
|
||||
case GEF_WF_SAMMELDEAKTIVIERUNG: str = "GEF_WF_SAMMELDEAKTIVIERUNG"; break;
|
||||
case GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN: str = "GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN"; break;
|
||||
case GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM: str = "GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM"; break;
|
||||
case GEF_DATENVERKEHR_GEOP_TDS: str = "GEF_DATENVERKEHR_GEOP_TDS"; break;
|
||||
case GEF_DATENVERKEHR_TDS_GEOP: str = "GEF_DATENVERKEHR_TDS_GEOP"; break;
|
||||
case GEF_DATENVERKEHR_TGTC_TDS: str = "GEF_DATENVERKEHR_TGTC_TDS"; break;
|
||||
case GEF_DATENVERKEHR_TDS_TGTC: str = "GEF_DATENVERKEHR_TDS_TGTC"; break;
|
||||
case GEF_GERAETEEREIGNIS: str = "GEF_GERAETEEREIGNIS"; break;
|
||||
case GEF_WAFFENZUORDNUNG: str = "GEF_WAFFENZUORDNUNG"; break;
|
||||
case GEF_MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE: str = "GEF_MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE"; break;
|
||||
case GEF_FEUEREREIGNIS_MIT_WAFFENZUORDNUNG: str = "GEF_FEUEREREIGNIS_MIT_WAFFENZUORDNUNG"; break;
|
||||
case GEF_AUSLOESUNG_DUS_TREFFER: str = "GEF_AUSLOESUNG_DUS_TREFFER"; break;
|
||||
case GEF_ANFORDERUNG_SW_VERSION: str = "GEF_ANFORDERUNG_SW_VERSION"; break;
|
||||
case GEF_SW_VERSIONSMELDUNG: str = "GEF_SW_VERSIONSMELDUNG"; break;
|
||||
case GEF_TECHNIK_FUNKTIONSRAUM: str = "GEF_TECHNIK_FUNKTIONSRAUM"; break;
|
||||
case GEF_TEILNEHMERMODE_SETZEN: str = "GEF_TEILNEHMERMODE_SETZEN"; break;
|
||||
case GEF_TEILNEHMERMODE_MELDUNG: str = "GEF_TEILNEHMERMODE_MELDUNG"; break;
|
||||
case GEF_TEILNEHMERMODE_ANFORDERN: str = "GEF_TEILNEHMERMODE_ANFORDERN"; break;
|
||||
case GEF_TEILNEHMER_KONFIG_ANTWORT: str = "GEF_TEILNEHMER_KONFIG_ANTWORT"; break;
|
||||
case GEF_TEILNEHMER_KONFIG_SETZEN: str = "GEF_TEILNEHMER_KONFIG_SETZEN"; break;
|
||||
case GEF_TEILNEHMER_KONFIG_ANFORDERN: str = "GEF_TEILNEHMER_KONFIG_ANFORDERN"; break;
|
||||
case GEF_SANITAETSDIENST_INSTANDSETZUNG: str = "GEF_SANITAETSDIENST_INSTANDSETZUNG"; break;
|
||||
case GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN: str = "GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN"; break;
|
||||
case GEF_BESTANDSMELDUNG_SANITAETSMATERIAL: str = "GEF_BESTANDSMELDUNG_SANITAETSMATERIAL"; break;
|
||||
case GEF_GEFECHTSFELDTELEGRAMM: str = "GEF_GEFECHTSFELDTELEGRAMM"; break;
|
||||
}
|
||||
|
||||
Q_ASSERT(str);
|
||||
if (!str)
|
||||
str = "Unknown";
|
||||
return str + QByteArray(" (") + QByteArray::number(int(telId)) + ")";
|
||||
}
|
||||
|
||||
QString wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType wirkfeldTyp)
|
||||
{
|
||||
switch(wirkfeldTyp)
|
||||
{
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::MineArea:
|
||||
return QLatin1String("MINENSPERRE");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::ExplosionArea:
|
||||
return QLatin1String("FLAECHENFEUER");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::ExplosionSingle:
|
||||
return QLatin1String("EINZELFEUER");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::NContamination:
|
||||
return QLatin1String("A_KAMPF");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::CContamination:
|
||||
return QLatin1String("C_KAMPF");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::FunctionalArea:
|
||||
return QLatin1String("FUNKTIONS_RAUM");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::TechnicalArea:
|
||||
return QLatin1String("FUNKTIONS_RAUM_TECHNIK");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::GasPipeDetonation:
|
||||
return QLatin1String("GAS_PIPE_DETONATION");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::SpecialArea:
|
||||
return QLatin1String("SPECIAL_AREA");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::Unknown:
|
||||
return QLatin1String("DUS");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::DusSingleMineSimulator:
|
||||
return QLatin1String("DUS_SINGLE_MINE_SIMULATOR");
|
||||
case TrainingAreaBase::TetraIcd::AreaEffectSimulationType::BeStillWarning:
|
||||
return QLatin1String("BE_STILL_WARNING");
|
||||
}
|
||||
return QStringLiteral("Unknown Wirkfeldtyp <%1>").arg(static_cast<int>(wirkfeldTyp));
|
||||
}
|
||||
|
||||
static inline QString wirkfeldTyp2Str(int typ)
|
||||
{
|
||||
return wirkfeldTyp2Str(static_cast<TrainingAreaBase::TetraIcd::AreaEffectSimulationType>(typ));
|
||||
}
|
||||
|
||||
void dumpTelegram(NGL::INGLLogger &m_logger, int id, N_CoPrtCnv::CoPrtCnvRadioTelegram *a_radioTelegram, const char *prefix)
|
||||
{
|
||||
if(!m_logger.isDebugEnabled())
|
||||
return;
|
||||
|
||||
if (!prefix)
|
||||
prefix = "";
|
||||
const QByteArray commonLog(prefix + QByteArray("BC: ") + QByteArray::number(id) +
|
||||
", " + telegramId2String(a_radioTelegram->getTelID()));
|
||||
switch (a_radioTelegram->getTelID())
|
||||
{
|
||||
case GEF_DEAKTIVIERUNG_WIRKFELD:
|
||||
case GEF_WIRKFELD_AENDERUNG_BEZEICHNER:
|
||||
{
|
||||
uint8_t wirkfeldTyp = a_radioTelegram->getPayloadDataUInt32(5, 1);
|
||||
uint16_t wirkfeldKennung = a_radioTelegram->getPayloadDataUInt32(6, 2);
|
||||
DEBUG_LOG(m_logger) << commonLog
|
||||
<< ", type: " << wirkfeldTyp2Str(wirkfeldTyp) << ", kennung: "
|
||||
<< wirkfeldKennung;
|
||||
break;
|
||||
}
|
||||
case GEF_DEAKTIVIERUNG_EINZELMINE: {
|
||||
uint32_t wirkfeldKennung = a_radioTelegram->getPayloadDataUInt32(9, 2);
|
||||
uint32_t minenKennung = a_radioTelegram->getPayloadDataUInt32(11, 2);
|
||||
DEBUG_LOG(m_logger) << commonLog
|
||||
<< ", kennung: " << wirkfeldKennung << ", mineId: " << minenKennung;
|
||||
break;
|
||||
}
|
||||
case GEF_WIRKFELD_STATUS_MINENSPERRE:
|
||||
case GEF_WIRKFELD_A_KAMPFMITTEL:
|
||||
case GEF_WIRKFELD_MINENSPERRE:
|
||||
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER:
|
||||
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP:
|
||||
case GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN:
|
||||
case GEF_FUNKTIONSRAUM:
|
||||
case GEF_DEAKTIVIEREN_FUNKTIONSRAUM:
|
||||
{
|
||||
uint16_t wirkfeldKennung = a_radioTelegram->getPayloadDataUInt32(5, 2);
|
||||
DEBUG_LOG(m_logger) << commonLog << ", kennung: " << wirkfeldKennung;
|
||||
break;
|
||||
}
|
||||
case GEF_TECHNIK_FUNKTIONSRAUM:
|
||||
{
|
||||
uint16_t funktionsraumkennung = a_radioTelegram->getPayloadDataUInt32(5, 2);
|
||||
uint8_t funktionsraumtyp = a_radioTelegram->getPayloadDataUInt32(7, 1);
|
||||
DEBUG_LOG(m_logger) << commonLog
|
||||
<< ", kennung: " << funktionsraumkennung
|
||||
<< " type: " << int(funktionsraumtyp);
|
||||
break;
|
||||
}
|
||||
case GEF_WF_SAMMELDEAKTIVIERUNG:
|
||||
case GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN:
|
||||
case GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM:
|
||||
DEBUG_LOG(m_logger) << commonLog << ", Ids: " << dumpSammeldeaktivierung(a_radioTelegram);
|
||||
break;
|
||||
case GEF_NOP:
|
||||
{
|
||||
uint16_t bcFrom = a_radioTelegram->getPayloadDataUInt32(3, 2);
|
||||
uint16_t bcTo = a_radioTelegram->getPayloadDataUInt32(5, 2);
|
||||
DEBUG_LOG(m_logger) << prefix
|
||||
<< commonLog
|
||||
<< ", from BC " << bcFrom << " to " << bcTo;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DEBUG_LOG(m_logger) << commonLog;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <TrainingAreaBase/training_area_telegrams.h>
|
||||
#include <CoPrtCnv/coprtcnv_export.h>
|
||||
#include "tetra_telegram_ids.h"
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
class CoPrtCnvRadioTelegram;
|
||||
}
|
||||
|
||||
COPRTCNV_EXPORT QByteArray telegramId2String(gef_telegramm_id_et telId);
|
||||
COPRTCNV_EXPORT void dumpTelegram(NGL::INGLLogger &m_logger,
|
||||
int id,
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram *a_radioTelegram,
|
||||
const char *prefix = nullptr);
|
||||
COPRTCNV_EXPORT QString wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType wirkfeldTyp);
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
|
||||
|
||||
struct CoPrtCnvInjectionHeader
|
||||
{
|
||||
|
||||
|
||||
uint32_t m_Id1;
|
||||
|
||||
|
||||
uint32_t m_Id2;
|
||||
|
||||
|
||||
enum Destination
|
||||
{
|
||||
eUnknown = 0,
|
||||
eCentral = 1,
|
||||
eRadio = 2
|
||||
} m_Kind;
|
||||
|
||||
|
||||
uint16_t m_Size;
|
||||
|
||||
CoPrtCnvInjectionHeader()
|
||||
: m_Id1(0x12345678),
|
||||
m_Id2(0x78236239),
|
||||
m_Kind(eUnknown),
|
||||
m_Size(0)
|
||||
{}
|
||||
|
||||
bool isIdCorrect() const { return (m_Id1 == 0x12345678 && m_Id2 == 0x78236239); }
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
|
||||
|
||||
struct CoPrtCnvLogHeader
|
||||
{
|
||||
|
||||
|
||||
enum E_CoPrtCnvProtocol
|
||||
{
|
||||
e_DestProtocolCentral = 0,
|
||||
e_DestProtocolWls = 1,
|
||||
e_DestProtocolTetra = 5,
|
||||
e_DestProtocolMax = 6,
|
||||
e_DestProtocolMask = 0x0000000F,
|
||||
e_DestDirectionMask = 0xC0000000,
|
||||
e_DestReceive = 0x40000000,
|
||||
e_DestSend = 0xC0000000
|
||||
};
|
||||
|
||||
|
||||
short m_Length = 0;
|
||||
short m_Version = 0;
|
||||
int m_Priority = 0;
|
||||
|
||||
|
||||
int m_Protocol = 0;
|
||||
|
||||
|
||||
int m_Reserved = 0;
|
||||
|
||||
|
||||
uint64_t m_Time = 0;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,604 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <QByteArray>
|
||||
#include <CoPrtCnv/coprtcnv_export.h>
|
||||
#include "tetra_telegram_ids.h"
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
|
||||
|
||||
enum class E_LicensingKind
|
||||
{
|
||||
|
||||
|
||||
Success = 0,
|
||||
|
||||
|
||||
Rejected = 1,
|
||||
|
||||
|
||||
Unlicense = 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class E_LicensingErrorCode
|
||||
{
|
||||
Ok = 0,
|
||||
Selftest = 1,
|
||||
Battery = 2,
|
||||
Configuration = 3,
|
||||
Unlicense = 4,
|
||||
IdentityDenied = 5
|
||||
};
|
||||
|
||||
|
||||
|
||||
class COPRTCNV_EXPORT CoPrtCnvRadioTelegram
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
enum E_Flags
|
||||
{
|
||||
e_FlagsNone = 0x00,
|
||||
e_StorageAllowed = 0x10,
|
||||
e_GroupServiceOrOnlyStandardReportAllowed = 0x20,
|
||||
e_ReceivedConfirmationRequested = 0x40,
|
||||
e_ConsumedConfirmationRequested = 0x80
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_ProtocolIdentifier
|
||||
{
|
||||
e_SimpleTextMessagingWithoutSDS_TL = 0x02,
|
||||
e_SimpleGPS_WithoutSDS_TL = 0x03,
|
||||
e_TDSMessageWithoutSDS_TL = 0x50,
|
||||
e_UsingSDS_TL = 0x80,
|
||||
e_SimpleTextMessagingUsingSDS_TL = 0x82,
|
||||
e_SimpleGPS_UsingSDS_TL = 0x83,
|
||||
e_LoginTest = 0x1D
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_FragmentStatus
|
||||
{
|
||||
e_NotFragmented = 0x00,
|
||||
e_FirstFragment = 0x40,
|
||||
e_MiddleFragment = 0xC0,
|
||||
e_LastFragment = 0x80,
|
||||
e_FragmentStatusMask = 0xC0,
|
||||
e_Checksum = 0x20,
|
||||
e_CounterMask = 0x0F,
|
||||
e_NormalTelegram = 0x00,
|
||||
e_LoginTelegram = 0x02,
|
||||
e_DgpsTelegram = 0x03
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PrtCnvRadioGwHeader
|
||||
{
|
||||
|
||||
|
||||
uint8_t m_MagicNumber;
|
||||
|
||||
|
||||
uint8_t m_Counter;
|
||||
|
||||
|
||||
uint16_t m_Length;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_PDU_Type
|
||||
{
|
||||
e_RegisterInd = 0,
|
||||
e_RegisterRsp = 1,
|
||||
e_DataIndReq = 2,
|
||||
e_ReportIndReq = 3,
|
||||
e_StatusIndReq = 4,
|
||||
e_GroupMonitorReq = 6,
|
||||
e_AirInterfaceLoadReq = 8,
|
||||
e_AirLoadHyterra = 19
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_RegistrationStatus
|
||||
{
|
||||
e_IssiSuccessfulRegistered = 0,
|
||||
e_DuplicateISSI = 1,
|
||||
e_InvalidISSI = 2,
|
||||
e_InvalidIpAddress = 3
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_DeliveryStatusForTL_Report
|
||||
{
|
||||
e_SDS_ReceiptAcknowledgedByDestination = 0x00,
|
||||
e_SDS_ConsumedByDestination = 0x02,
|
||||
e_SourceIsNotAuthorizedForSDS = 0x43,
|
||||
e_DestinationIsNotAuthorizedForSDS = 0x44,
|
||||
e_UnknownDestinationAddress = 0x45,
|
||||
e_DeliveryFailed = 0x4A,
|
||||
e_DestinationNotRegisteredOnSystem = 0x4B,
|
||||
e_DestinationQueueFull = 0x4C,
|
||||
e_MessageTooLong = 0x4D,
|
||||
e_DestinationHostPC_NotConnected = 0x4F,
|
||||
e_ProtocolNotSupported = 0x50,
|
||||
e_DataCodingSchemeNotSupported = 0x51,
|
||||
e_DestinationNotReachable = 0x5A
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_LoginStatus
|
||||
{
|
||||
e_LoginRequest = 0x40,
|
||||
e_LoginAccept = 0x80,
|
||||
e_LoginReject = 0xC0,
|
||||
e_LoginStatusMask = 0xC0,
|
||||
e_LoginMastering = 0x20,
|
||||
|
||||
|
||||
e_LoginNoExerciseAssignment = 0x00,
|
||||
e_LoginOtherEqId = 0x02,
|
||||
e_LoginOtherISSI = 0x04,
|
||||
e_LoginOtherExercise = 0x06,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static constexpr uint8_t MAGIC_NUMBER = 0xA5;
|
||||
|
||||
|
||||
static constexpr uint16_t DATA_IND_REQ_WITH_TL_HEADER_LENGTH = 22;
|
||||
|
||||
|
||||
static constexpr uint16_t DATA_IND_REQ_HEADER_LENGTH = 27;
|
||||
|
||||
|
||||
static constexpr uint16_t DATA_IND_REQ_HEADER_LENGTH_WITHOUT_PAYLOAD_HEADER = DATA_IND_REQ_HEADER_LENGTH -1;
|
||||
|
||||
|
||||
static constexpr uint16_t DATA_IND_REQ_NO_TL_HEADER_LENGTH = 14;
|
||||
|
||||
|
||||
static constexpr uint16_t MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH = 249;
|
||||
|
||||
|
||||
static constexpr uint16_t PAYLOAD_STATUS_LENGTH = 1;
|
||||
|
||||
|
||||
static constexpr uint8_t MAX_NBR_OF_FRAGMENTS = 16;
|
||||
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI);
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI, const std::set<uint32_t> &groups);
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const uint32_t a_sourceISSI, const E_DeliveryStatusForTL_Report a_delivery);
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const QByteArray &a_data);
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const gef_telegramm_id_et a_telegramId, const uint16_t a_payloadSize, const uint16_t a_identity);
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const E_LoginStatus a_loginTelegramStatus, const uint16_t a_identity, uint32_t a_issi);
|
||||
|
||||
void setLoginIssis(int hostIssi, int groupIssi1, int groupIssi2);
|
||||
|
||||
|
||||
|
||||
explicit CoPrtCnvRadioTelegram(const std::shared_ptr<CoPrtCnvRadioTelegram> &a_bigTelegram,
|
||||
const uint8_t a_fragmentIndex, bool &a_error);
|
||||
|
||||
|
||||
virtual ~CoPrtCnvRadioTelegram();
|
||||
|
||||
|
||||
|
||||
void fixupTelegramIdForEts(bool convertToEtsId);
|
||||
static void setEtsMode(bool bIsEtsMode);
|
||||
|
||||
|
||||
|
||||
void setPayload1Byte(uint8_t a_value);
|
||||
void setPayload2Byte(uint16_t a_value);
|
||||
void setPayload3Byte(uint32_t a_value);
|
||||
void setPayload4Byte(uint32_t a_value);
|
||||
void setPayloadData(uint32_t a_value, const uint8_t a_size);
|
||||
|
||||
|
||||
|
||||
void setPayloadData(const uint8_t a_value) { return setPayload1Byte(a_value); }
|
||||
|
||||
|
||||
|
||||
void setPayloadData(const uint8_t *a_data, const uint16_t a_size);
|
||||
|
||||
|
||||
|
||||
const char *getData() const { return m_data.data(); }
|
||||
char *getData() { return m_data.data(); }
|
||||
QByteArray data() const { return m_data; }
|
||||
|
||||
|
||||
|
||||
int getSize() const { return m_data.size(); }
|
||||
|
||||
|
||||
|
||||
gef_telegramm_id_et getTelID() const;
|
||||
|
||||
|
||||
|
||||
uint8_t zaehler() const;
|
||||
|
||||
|
||||
|
||||
void setZaehler(const uint8_t a_counter);
|
||||
|
||||
|
||||
|
||||
uint32_t getPayloadDataUInt32(size_t a_offset, uint16_t a_size) const;
|
||||
|
||||
|
||||
|
||||
uint8_t getPayloadDataUInt8(size_t a_offset) const;
|
||||
|
||||
|
||||
|
||||
uint32_t getDestISSI() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getIdentity() const;
|
||||
|
||||
|
||||
|
||||
void setSrcISSI(const uint32_t a_ISSI);
|
||||
|
||||
|
||||
|
||||
bool mustBroadcastBeSet() const;
|
||||
|
||||
|
||||
|
||||
void setBroadcastIndex(const uint16_t a_broadcastIndex);
|
||||
|
||||
|
||||
|
||||
void setDestISSI(const uint32_t a_ISSI);
|
||||
|
||||
|
||||
|
||||
CoPrtCnvRadioTelegram::E_PDU_Type getPDU_Type() const;
|
||||
|
||||
|
||||
|
||||
CoPrtCnvRadioTelegram::E_FragmentStatus getFragmentStatus() const;
|
||||
|
||||
|
||||
|
||||
uint8_t getFragmentCounter() const;
|
||||
|
||||
|
||||
|
||||
bool isCrcOk() const;
|
||||
|
||||
|
||||
|
||||
uint32_t getSrcISSI() const;
|
||||
|
||||
|
||||
|
||||
bool isLoginTelegram() const;
|
||||
|
||||
|
||||
|
||||
bool mustBeFragmented() const;
|
||||
|
||||
|
||||
|
||||
const uint8_t *getPayloadDataPtr(uint16_t a_offset) const;
|
||||
uint8_t *getPayloadDataPtr(uint16_t a_offset);
|
||||
|
||||
|
||||
|
||||
virtual uint16_t getPayloadSize() const;
|
||||
|
||||
|
||||
|
||||
static QByteArray getUnfragmentedData(const std::multimap<uint16_t, CoPrtCnvRadioTelegram *> &a_fragTelegramList);
|
||||
|
||||
|
||||
|
||||
static bool isTelegramLengthOk(const uint16_t a_lengthWithoutFrame);
|
||||
|
||||
|
||||
|
||||
bool isNormalTelegram() const;
|
||||
|
||||
|
||||
|
||||
uint8_t getPriority() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getBroadcastIndex() const;
|
||||
|
||||
|
||||
|
||||
void setPayloadDataWithIndex(const uint16_t a_index, const uint32_t a_value, const uint16_t a_size);
|
||||
|
||||
|
||||
|
||||
void setPayloadDataComplete(const QByteArray &payload);
|
||||
|
||||
|
||||
|
||||
void resetPayloadSize(const uint16_t a_newPayloadSize);
|
||||
|
||||
|
||||
|
||||
void setIdentity(const uint16_t a_identity);
|
||||
|
||||
|
||||
|
||||
void setProtocolIdentifier(const E_ProtocolIdentifier a_ProtocolIdentifier);
|
||||
|
||||
|
||||
|
||||
void setMessageReference(const uint8_t a_MessageReference);
|
||||
|
||||
|
||||
|
||||
bool isSDSTL() const;
|
||||
|
||||
|
||||
|
||||
CoPrtCnvRadioTelegram::E_RegistrationStatus getRegistrationStatus() const;
|
||||
|
||||
|
||||
|
||||
std::string getRegistrationStatusAsText() const;
|
||||
|
||||
|
||||
|
||||
CoPrtCnvRadioTelegram::E_ProtocolIdentifier getProtocolIdentifier() const;
|
||||
|
||||
|
||||
|
||||
std::string getProtocolIdentifierAsText() const;
|
||||
|
||||
|
||||
|
||||
uint8_t getMessageReference() const;
|
||||
|
||||
|
||||
|
||||
uint8_t getAreaSelection() const;
|
||||
|
||||
|
||||
|
||||
uint8_t getValidityPeriod() const;
|
||||
|
||||
|
||||
|
||||
uint32_t getForwardAddress() const;
|
||||
|
||||
|
||||
|
||||
CoPrtCnvRadioTelegram::E_Flags getFlags() const;
|
||||
|
||||
|
||||
|
||||
std::string getFlagsAsText() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getLengthInBits() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getLengthInBytes() const;
|
||||
|
||||
|
||||
|
||||
bool getWithCrc() const;
|
||||
|
||||
|
||||
|
||||
CoPrtCnvRadioTelegram::E_DeliveryStatusForTL_Report getDelivery() const;
|
||||
|
||||
|
||||
|
||||
std::string getDeliveryAsText() const;
|
||||
|
||||
|
||||
|
||||
int32_t getPayloadDataSInt24(uint16_t a_offset) const;
|
||||
|
||||
|
||||
|
||||
bool needsLicensing() const;
|
||||
|
||||
|
||||
|
||||
bool hasExpired() const;
|
||||
|
||||
|
||||
|
||||
uint32_t getExpireTime() const;
|
||||
|
||||
|
||||
|
||||
bool isContentValid();
|
||||
|
||||
|
||||
|
||||
bool mustBeSentAsBroadcast(time_t a_currentTime, bool &a_wasLastBroadcast, const bool a_updateBroadcastCounter = true);
|
||||
|
||||
|
||||
|
||||
static void setBroadcastDelayTimes(int a_2ndDelay, int a_3rdDelay);
|
||||
|
||||
|
||||
|
||||
static void setMaxBroadcastSendCnt(int a_maxSendCnt);
|
||||
|
||||
|
||||
|
||||
bool isMovedToBroadcastList() const;
|
||||
|
||||
|
||||
|
||||
void setBroadcastOnly(const bool a_doSet = true);
|
||||
|
||||
|
||||
|
||||
bool isBroadcastOnly() const;
|
||||
|
||||
|
||||
|
||||
void setBroadcastonlyTelegram(const std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> &a_radioTelegram);
|
||||
|
||||
|
||||
|
||||
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> getBroadcastonlyTelegram() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getBroadcastCounter() const;
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
QByteArray m_data;
|
||||
|
||||
|
||||
|
||||
uint16_t m_PayloadIndex;
|
||||
|
||||
|
||||
uint16_t m_BroadcastCounter;
|
||||
|
||||
|
||||
time_t m_NextSendTime;
|
||||
|
||||
|
||||
static int s_2ndDelay;
|
||||
|
||||
|
||||
static int s_3rdDelay;
|
||||
|
||||
|
||||
static int s_maxBroadcastSendCnt;
|
||||
|
||||
|
||||
bool m_IsBroadcastOnly;
|
||||
|
||||
|
||||
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> m_BroadcastOnlyTelegram;
|
||||
|
||||
|
||||
|
||||
static bool s_etsMode;
|
||||
|
||||
|
||||
|
||||
bool isPayloadLengthOk(uint16_t a_minLength,
|
||||
const uint16_t a_dataAmountOffset,
|
||||
const uint8_t a_variableDataElementSize) const;
|
||||
bool isPayloadLengthOk(uint16_t a_minLength,
|
||||
uint16_t a_maxLength) const;
|
||||
bool isPayloadLengthOk(uint16_t a_length) const;
|
||||
bool isPayloadLengthOk(const std::vector<uint16_t> &a_lengths) const;
|
||||
|
||||
|
||||
|
||||
static void set1Byte(QByteArray &a_data, uint16_t a_offset, uint8_t a_value);
|
||||
|
||||
|
||||
|
||||
static void set2Byte(QByteArray &a_data, uint16_t a_offset, uint16_t a_value);
|
||||
|
||||
|
||||
|
||||
static void set4Byte(QByteArray &a_data, uint16_t a_offset, uint32_t a_value);
|
||||
|
||||
|
||||
uint8_t getUInt8(const uint16_t a_offset) const { return static_cast<uint8_t>(m_data.at(a_offset)); }
|
||||
uint16_t getUInt16(const uint16_t a_offset) const;
|
||||
uint32_t getUInt32(const uint16_t a_offset) const;
|
||||
|
||||
|
||||
|
||||
static void setHeader(QByteArray &data, E_PDU_Type pduType);
|
||||
|
||||
|
||||
|
||||
static void fillDataIndReqHeader(QByteArray &a_data);
|
||||
|
||||
|
||||
|
||||
static void setSrcISSI_Internal(QByteArray &data, const uint32_t issi);
|
||||
|
||||
|
||||
|
||||
static void setDestISSI_Internal(QByteArray &data, const uint32_t issi);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <CoPrtCnv/coprtcnv_export.h>
|
||||
|
||||
namespace TrainingAreaBase
|
||||
{
|
||||
namespace TetraIcd
|
||||
{
|
||||
struct TrainingAreaTelegram;
|
||||
}
|
||||
}
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
class CoPrtCnvRadioTelegram;
|
||||
class CoPrtCnvCentralTelegram;
|
||||
|
||||
|
||||
|
||||
|
||||
namespace CoPrtCnvTelegramConverter
|
||||
{
|
||||
|
||||
|
||||
COPRTCNV_EXPORT CoPrtCnvRadioTelegram *convertToRadio(CoPrtCnvCentralTelegram *a_telegram);
|
||||
COPRTCNV_EXPORT CoPrtCnvRadioTelegram *convertToRadio(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *a_telegram);
|
||||
|
||||
|
||||
|
||||
COPRTCNV_EXPORT CoPrtCnvCentralTelegram *convertToCentral(const CoPrtCnvRadioTelegram *a_radioTelegram);
|
||||
COPRTCNV_EXPORT TrainingAreaBase::TetraIcd::TrainingAreaTelegram *convertToTabTele(const CoPrtCnvRadioTelegram *a_radioTelegram);
|
||||
|
||||
|
||||
|
||||
|
||||
COPRTCNV_EXPORT void setTetraTextCodec(const char *codecName);
|
||||
|
||||
|
||||
|
||||
COPRTCNV_EXPORT void setUse2BytesForSingleFireDiameter(bool bUse);
|
||||
COPRTCNV_EXPORT void setUsePvSan(bool bUse);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
enum gef_telegramm_id_et
|
||||
{
|
||||
GEF_BESTAETIGUNG = 0,
|
||||
|
||||
GEF_INIT = 1,
|
||||
GEF_MANIPULATIONSMELDUNG = 2,
|
||||
GEF_UMGEBUNGS_MELDUNG2 = 203,
|
||||
GEF_AUFFORDERUNG_BITE_MELDUNG = 4,
|
||||
GEF_BITE_MELDUNG2 = 205,
|
||||
|
||||
GEF_LIZENSIERUNG_TNE = 6,
|
||||
GEF_BETRIEBSZUSTAND_AUSSTATTUNG = 7,
|
||||
GEF_KONFIGURATION_WIRKMODELL = 9,
|
||||
GEF_ANFORDERUNG_KONFIGURATIONSDATEN = 10,
|
||||
GEF_KONFIGURATIONSMELDUNG = 11,
|
||||
GEF_FEHLERMELDUNG_GFD = 12,
|
||||
GEF_WIEDERHERSTELLUNG_FUNKBEREITSCHAFT = 13,
|
||||
|
||||
GEF_POSITIONS_MELDUNG = 21,
|
||||
GEF_POSITIONS_MELDUNG_MIT_TEILNEHMER = 22,
|
||||
GEF_POSITIONS_MELDUNG_LFZ = 23,
|
||||
GEF_IPS_POSITIONSDATEN = 201,
|
||||
|
||||
GEF_SCHIEDSRICHTERKOMMANDO = 25,
|
||||
|
||||
GEF_WIRKFELD_EINZELGESCHOSS = 31,
|
||||
GEF_WIRKFELD_FLAECHENDECKENDES_FEUER = 32,
|
||||
GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_STOP = 33,
|
||||
GEF_WIRKFELD_FLAECHENDECKENDES_FEUER_FORTSETZEN = 34,
|
||||
GEF_WIRKFELD_MINENSPERRE = 35,
|
||||
GEF_WIRKFELD_STATUS_MINENSPERRE = 36,
|
||||
GEF_WIRKFELD_A_KAMPFMITTEL = 37,
|
||||
GEF_WIRKFELD_C_KAMPFMITTEL = 38,
|
||||
GEF_DEAKTIVIERUNG_WIRKFELD = 39,
|
||||
GEF_WIRKFELD_AENDERUNG_BEZEICHNER = 40,
|
||||
GEF_DEAKTIVIERUNG_EINZELMINE = 41,
|
||||
GEF_REAKTIVIERUNG_DUS_MINE = 42,
|
||||
GEF_DEFINITION_IED = 43,
|
||||
GEF_ZUSTAND_IED = 44,
|
||||
GEF_STATUS_EINZELMINENSIMULATOR = 45,
|
||||
GEF_WIRKFELD_EINZELMINENSIMULATOR = 46,
|
||||
GEF_SELEKTIVE_AUFMUNITIONIERUNG = 56,
|
||||
|
||||
GEF_TREFFER_EREIGNIS_DUS = 52,
|
||||
GEF_TREFFER_EREIGNIS_WIRKSIMULATION = 53,
|
||||
GEF_TREFFER_AUSLOESUNG = 54,
|
||||
GEF_SCHIEDSRICHTEREINGRIFF = 55,
|
||||
|
||||
GEF_TREFFER_EREIGNIS_SEKUNDAERWIRKUNG = 218,
|
||||
GEF_TREFFER_EREIGNIS_DUS_IPS = 228,
|
||||
GEF_TREFFER_EREIGNIS_WIRKSIMULATION_IPS = 229,
|
||||
|
||||
GEF_TAKTISCHER_STATUS = 61,
|
||||
GEF_FUNKTIONSRAUM = 62,
|
||||
GEF_EINTRETEN_FUNKTIONSRAUM = 63,
|
||||
GEF_DEAKTIVIEREN_FUNKTIONSRAUM = 64,
|
||||
|
||||
GEF_DATENVERKEHR_SRT_TDS = 71,
|
||||
GEF_DATENVERKEHR_TDS_SRT = 72,
|
||||
GEF_DATENVERKEHR_DMF_TDS = 73,
|
||||
GEF_DATENVERKEHR_TDS_DMF = 74,
|
||||
|
||||
GEF_NACHFORDERUNG_BROADCAST_TELEGRAMME = 82,
|
||||
GEF_NOP = 83,
|
||||
|
||||
GEF_SONDERSENSORIK_BETRIEBSZUSTAND = 91,
|
||||
GEF_SONDERSENSORIK_FAHRSPUR = 92,
|
||||
GEF_SONDERSENSORIK_DATEN = 93,
|
||||
GEF_SONDERSENSORIK_MIVANH_VERLEGEDATEN = 95,
|
||||
GEF_SONDERSENSORIK_WMIV_VERLEGEDATEN = 96,
|
||||
GEF_SONDERSENSORIK_MIVANH_VERLEGEPOSITION = 97,
|
||||
|
||||
GEF_SPRACHAUSWAHL = 101,
|
||||
GEF_ALLGEMEINE_NACHRICHT = 102,
|
||||
GEF_ECHO_ON_OFF = 103,
|
||||
GEF_ESW_MELDUNG = 104,
|
||||
|
||||
GEF_WF_SAMMELDEAKTIVIERUNG = 105,
|
||||
GEF_WF_SAMMELDEAKTIVIERUNG_DUS_MINEN = 106,
|
||||
GEF_WF_SAMMELDEAKTIVIERUNG_FUNKTIONSRAUM = 107,
|
||||
|
||||
GEF_DATENVERKEHR_GEOP_TDS = 181,
|
||||
GEF_DATENVERKEHR_TDS_GEOP = 182,
|
||||
|
||||
GEF_DATENVERKEHR_TGTC_TDS = 183,
|
||||
GEF_DATENVERKEHR_TDS_TGTC = 184,
|
||||
GEF_GERAETEEREIGNIS = 185,
|
||||
|
||||
GEF_WAFFENZUORDNUNG = 200,
|
||||
GEF_MUNITIONSVORRAT_EINER_ZUGEORDNETEN_WAFFE = 202,
|
||||
GEF_FEUEREREIGNIS_MIT_WAFFENZUORDNUNG = 210,
|
||||
GEF_AUSLOESUNG_DUS_TREFFER = 211,
|
||||
GEF_ANFORDERUNG_SW_VERSION = 212,
|
||||
GEF_SW_VERSIONSMELDUNG = 213,
|
||||
GEF_TECHNIK_FUNKTIONSRAUM = 219,
|
||||
|
||||
GEF_TEILNEHMERMODE_SETZEN = 230,
|
||||
GEF_TEILNEHMERMODE_MELDUNG = 231,
|
||||
GEF_TEILNEHMERMODE_ANFORDERN = 232,
|
||||
GEF_TEILNEHMER_KONFIG_ANTWORT = 233,
|
||||
GEF_TEILNEHMER_KONFIG_SETZEN = 234,
|
||||
GEF_TEILNEHMER_KONFIG_ANFORDERN = 235,
|
||||
|
||||
GEF_SANITAETSDIENST_INSTANDSETZUNG = 240,
|
||||
GEF_BESTANDSMELDUNG_SANITAETSMATERIAL = 241,
|
||||
GEF_SANITAETSDIENST_INSTANDSETZUNG_PVSAN = 242,
|
||||
|
||||
GEF_LASER_TARGET_DESIGNATOR_UPDATE = 214,
|
||||
|
||||
GEF_GEFECHTSFELDTELEGRAMM = 300
|
||||
};
|
||||
@@ -0,0 +1,104 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
ADD_SUBDIRECTORY(Console)
|
||||
SET(my_SRCS
|
||||
IntegerCalculator.cpp
|
||||
IntegerCalculator.hpp
|
||||
logger.cpp
|
||||
logger.h
|
||||
LogViewBooleanEdit.cpp
|
||||
LogViewBooleanEdit.hpp
|
||||
LogViewDateTimeEdit.cpp
|
||||
LogViewDateTimeEdit.hpp
|
||||
LogViewEnumEdit.cpp
|
||||
LogViewEnumEdit.hpp
|
||||
LogViewField.cpp
|
||||
LogViewField.hpp
|
||||
LogViewGui.cpp
|
||||
LogViewGui.hpp
|
||||
LogViewInjectionThread.cpp
|
||||
LogViewInjectionThread.hpp
|
||||
LogViewMain.cpp
|
||||
LogViewModels.cpp
|
||||
LogViewModels.hpp
|
||||
LogViewOptionDialog.cpp
|
||||
LogViewOptionDialog.hpp
|
||||
LogViewSpinBox.cpp
|
||||
LogViewSpinBox.hpp
|
||||
LogViewTableWidget.cpp
|
||||
LogViewTableWidget.hpp
|
||||
LogViewTabWidget.cpp
|
||||
LogViewTabWidget.hpp
|
||||
LogViewTelegram.cpp
|
||||
LogViewTelegramDialog.cpp
|
||||
LogViewTelegramDialog.hpp
|
||||
LogViewTelegramEdit.cpp
|
||||
LogViewTelegramEdit.hpp
|
||||
LogViewTelegramEditModel.cpp
|
||||
LogViewTelegramEditModel.hpp
|
||||
LogViewTelegram.hpp
|
||||
LogViewTelegramSelectionDialog.cpp
|
||||
LogViewTelegramSelectionDialog.hpp
|
||||
LogViewTetraTelegramsParser.cpp
|
||||
LogViewTetraTelegramsParser.hpp
|
||||
LogViewTextEdit.cpp
|
||||
LogViewTextEdit.hpp
|
||||
LogViewValueEdit.cpp
|
||||
LogViewValueEdit.hpp
|
||||
LogViewWidget.cpp
|
||||
LogViewWidget.hpp
|
||||
LogViewXdrElement.cpp
|
||||
LogViewXdrElement.hpp
|
||||
LogViewXdrParser.cpp
|
||||
LogViewXdrParser.hpp
|
||||
LogViewXdrStandardType.cpp
|
||||
LogViewXdrStandardType.hpp
|
||||
LogViewXdrStruct.cpp
|
||||
LogViewXdrStruct.hpp
|
||||
LogViewXdrType.cpp
|
||||
LogViewXdrType.hpp
|
||||
LogViewXdrValue.cpp
|
||||
LogViewXdrValue.hpp
|
||||
zsksxd_tetraForLogView.x
|
||||
)
|
||||
|
||||
QT5_ADD_RESOURCES(my_SRCS LogViewResources.qrc)
|
||||
NGL_ADD_TOOL_ICON(my_SRCS)
|
||||
NGL_ADD_EXECUTABLE(AAR SV NO_TRANSLATION LogView ${my_SRCS})
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(LogView
|
||||
Qt5::Core
|
||||
Qt5::Gui
|
||||
Qt5::Network
|
||||
CoPrtCnv
|
||||
nglwidgets
|
||||
NGLLogger
|
||||
nglapplication
|
||||
ngltools
|
||||
)
|
||||
NGL_INSTALL_TARGET(LogView)
|
||||
NGL_INSTALL(AAR SV FILES LogView_log4cxx.props DESTINATION bin)
|
||||
|
||||
|
||||
|
||||
# install on RPM build and copy for local builds so that LogView automatically finds the zsksxd_tetraForLogView.x file
|
||||
if (BUILD_RPM)
|
||||
add_custom_target(zsksxd_tetraForLogView.x_bin) # empty target so that LogView still builds on RPM build
|
||||
NGL_INSTALL(AAR SV FILES zsksxd_tetraForLogView.x DESTINATION bin)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT ${CMAKE_BINARY_DIR}/bin/zsksxd_tetraForLogView.x
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/zsksxd_tetraForLogView.x ${CMAKE_BINARY_DIR}/bin/zsksxd_tetraForLogView.x
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/zsksxd_tetraForLogView.x
|
||||
COMMENT "[Local build] Copy zsksxd_tetraForLogView.x for LogView into bin/"
|
||||
)
|
||||
add_custom_target(zsksxd_tetraForLogView.x_bin DEPENDS ${CMAKE_BINARY_DIR}/bin/zsksxd_tetraForLogView.x)
|
||||
endif()
|
||||
|
||||
if (TARGET LogView)
|
||||
add_dependencies(LogView zsksxd_tetraForLogView.x_bin training_area_telegrams.h_bin)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(console_SRCS
|
||||
main.cpp
|
||||
)
|
||||
|
||||
NGL_ADD_TOOL_ICON(console_SRCS)
|
||||
NGL_ADD_EXECUTABLE(AAR SV LogView_console ${console_SRCS})
|
||||
NGL_INSTALL_TARGET(LogView_console)
|
||||
NGL_TARGET_LINK_LIBRARIES(LogView_console
|
||||
CoPrtCnv
|
||||
NGLLogger
|
||||
)
|
||||
@@ -0,0 +1,201 @@
|
||||
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QStringList>
|
||||
#include <QFile>
|
||||
#include <QByteArray>
|
||||
#include <QDateTime>
|
||||
#include <QBuffer>
|
||||
#include <QSet>
|
||||
|
||||
#include <CoPrtCnv/CoPrtCnvLogHeader.hpp>
|
||||
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
|
||||
#include <CoPrtCnv/CoPrtCnvTelegramConverter.hpp>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <TrainingAreaBase/training_area_telegrams.h>
|
||||
|
||||
static QSet<int> s_eqIds;
|
||||
template <typename T>
|
||||
bool validEqId(const T &tele)
|
||||
{
|
||||
if (!s_eqIds.isEmpty() && !s_eqIds.contains(tele.header.equipmentNumber))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
QByteArray formatTime(quint64 t)
|
||||
{
|
||||
const quint64 secs = t >> 32;
|
||||
const quint64 usecs = t & 0xFFFFFFFF;
|
||||
const quint64 msecs = usecs / 1000;
|
||||
return QDateTime::fromMSecsSinceEpoch(secs * 1000 + msecs).toString(QLatin1String("yy-MM-dd hh:mm:ss.zzz")).toUtf8();
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
using namespace TrainingAreaBase::TetraIcd;
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
|
||||
|
||||
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx_tetra.props", false);
|
||||
|
||||
NGL::INGLLogger &logger(NGL::NGLLoggerBootstrap::getNGLRootLogger());
|
||||
|
||||
if (app.arguments().count() < 3)
|
||||
{
|
||||
ERROR_LOG(logger) << "Usage: " << app.arguments().at(0)
|
||||
<< " <logfile> <telId> <equipId>";
|
||||
return 1;
|
||||
}
|
||||
|
||||
QFile telegramFile(app.arguments().at(1));
|
||||
if (!telegramFile.open(QIODevice::ReadOnly))
|
||||
{
|
||||
ERROR_LOG(logger) << "Error opening " << telegramFile.fileName()
|
||||
<< " for reading: " << telegramFile.errorString();
|
||||
return 2;
|
||||
}
|
||||
bool bOk;
|
||||
int telIdToSearch = app.arguments().at(2).toUShort(&bOk);
|
||||
if (!bOk)
|
||||
{
|
||||
ERROR_LOG(logger) << "Error reading telId - not a (valid) number: "
|
||||
<< app.arguments().at(2);
|
||||
return 3;
|
||||
}
|
||||
s_eqIds.clear();
|
||||
for (int i = 3; i < app.arguments().size(); ++i)
|
||||
{
|
||||
int eqId = app.arguments().at(i).toUShort(&bOk);
|
||||
if (!bOk)
|
||||
{
|
||||
ERROR_LOG(logger) << "Error reading equipId - not a (valid) number: "
|
||||
<< app.arguments().at(i);
|
||||
return 4;
|
||||
}
|
||||
s_eqIds += eqId;
|
||||
}
|
||||
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader lh;
|
||||
if (sizeof(lh) == telegramFile.read((char *)&lh, sizeof(lh)))
|
||||
{
|
||||
if (lh.m_Version == 3)
|
||||
{
|
||||
|
||||
qint64 telegramLength = lh.m_Length - sizeof(lh);
|
||||
QByteArray telegramData(telegramLength, Qt::Uninitialized);
|
||||
if (telegramLength == telegramFile.read(telegramData.data(), telegramLength))
|
||||
{
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol dest = (N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol)
|
||||
(lh.m_Protocol & N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolMask);
|
||||
|
||||
switch (dest)
|
||||
{
|
||||
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral:
|
||||
{
|
||||
const QJsonObject obj = QJsonDocument::fromJson(telegramData).object();
|
||||
int telId = obj.value(QStringLiteral("typeId")).toInt();
|
||||
if (telIdToSearch != telId)
|
||||
continue;
|
||||
|
||||
const QJsonObject objData = obj.value(QStringLiteral("data")).toObject();
|
||||
|
||||
const QByteArray tBA = formatTime(lh.m_Time);
|
||||
const char *timeStr = tBA.constData();
|
||||
|
||||
switch (telId)
|
||||
{
|
||||
case Constraints<CreateFunctionalArea>::id():
|
||||
{
|
||||
const CreateFunctionalArea tele(CreateFunctionalArea::fromJson(objData));
|
||||
if (!validEqId(tele))
|
||||
break;
|
||||
fprintf(stdout, "%s, FUNKTIONSRAUM: '%s', %d, %d\n",
|
||||
timeStr,
|
||||
tele.name.c_str(),
|
||||
tele.aesDdsId,
|
||||
tele.header.equipmentNumber
|
||||
);
|
||||
break;
|
||||
}
|
||||
case Constraints<DeactivateEffectSimulation>::id():
|
||||
{
|
||||
const DeactivateEffectSimulation tele(DeactivateEffectSimulation::fromJson(objData));
|
||||
fprintf(stdout, "%s, DEAKTIVIERUNG_WIRKFELD: typ: %d - kennung: %d\n",
|
||||
timeStr,
|
||||
int(tele.aesType),
|
||||
tele.aesDdsId
|
||||
);
|
||||
break;
|
||||
}
|
||||
case Constraints<PositionReport>::id():
|
||||
{
|
||||
const PositionReport tele(PositionReport::fromJson(objData));
|
||||
if (!validEqId(tele))
|
||||
break;
|
||||
if (tele.opsPosition.opsId == 0)
|
||||
break;
|
||||
fprintf(stdout, "%s, IPS_POSITIONSDATEN: %d - OPS: %d\n",
|
||||
timeStr,
|
||||
tele.header.equipmentNumber,
|
||||
tele.opsPosition.opsId
|
||||
);
|
||||
break;
|
||||
}
|
||||
case BESTAETIGUNG:
|
||||
case UMGEBUNGS_MELDUNG2:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Printing telegram with id %d not implemented\n", telId);
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolTetra:
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram radioTelegram(telegramData);
|
||||
gef_telegramm_id_et telId = radioTelegram.getTelID();
|
||||
if (telId == GEF_UMGEBUNGS_MELDUNG2)
|
||||
{
|
||||
const QByteArray tBA = formatTime(lh.m_Time);
|
||||
const char *timeStr = tBA.constData();
|
||||
static uint16_t bci = 0xFFFF;
|
||||
if (bci != radioTelegram.getBroadcastIndex())
|
||||
{
|
||||
if (bci > radioTelegram.getBroadcastIndex() && bci != 0xFFFF)
|
||||
{
|
||||
fprintf(stdout, "BCI reset in %s at %s!\n",
|
||||
qPrintable(telegramFile.fileName()),
|
||||
timeStr);
|
||||
}
|
||||
fprintf(stdout, "BCI: %d\n", radioTelegram.getBroadcastIndex());
|
||||
bci = radioTelegram.getBroadcastIndex();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(logger) << "Wrong LogHeader version: " << lh.m_Version;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "IntegerCalculator.hpp"
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace N_SST
|
||||
{
|
||||
IntegerCalculator::IntegerCalculator()
|
||||
: m_OperationList({{"*", 6},{"/", 6},{"%", 6},{"+", 5},{"-", 5},{"<<", 4},{">>", 4}})
|
||||
, m_AdditionalErrorText()
|
||||
, m_ParanthesisCount(0)
|
||||
, m_Error(IntegerCalculator::e_Ok)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t IntegerCalculator::calc(const std::string& a_calcText, E_Error& a_error, std::string* a_addErrorText)
|
||||
{
|
||||
std::string calcText = a_calcText;
|
||||
|
||||
for (auto iter = m_OperationList.begin(); iter != m_OperationList.end(); ++iter)
|
||||
replace(calcText, iter->first, " "+iter->first+" ");
|
||||
|
||||
|
||||
replace(calcText, "(", " ( ");
|
||||
replace(calcText, ")", " ) ");
|
||||
|
||||
|
||||
|
||||
m_ParanthesisCount = 0;
|
||||
m_Error = e_Ok;
|
||||
m_AdditionalErrorText = "";
|
||||
size_t pos = 0;
|
||||
bool dummy;
|
||||
int64_t value = calc(calcText, pos, dummy, "", 0, "+");
|
||||
|
||||
|
||||
|
||||
if (m_Error == e_Ok)
|
||||
{
|
||||
if (m_ParanthesisCount > 0)
|
||||
{
|
||||
m_Error = e_MissingRightParanthesis;
|
||||
}
|
||||
else if (m_ParanthesisCount < 0)
|
||||
{
|
||||
m_Error = e_MissingLeftParanthesis;
|
||||
}
|
||||
else if (pos != calcText.length())
|
||||
{
|
||||
m_Error = e_UnknownError;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
a_error = m_Error;
|
||||
if (a_error != e_Ok)
|
||||
{
|
||||
value = 0;
|
||||
if (a_addErrorText)
|
||||
{
|
||||
*a_addErrorText = m_AdditionalErrorText;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void IntegerCalculator::addVariable(const std::string& a_name, const int64_t a_value)
|
||||
{
|
||||
std::map<std::string, int64_t>::iterator iter = m_VariableList.find(a_name);
|
||||
if (iter != m_VariableList.end())
|
||||
removeVariable(a_name);
|
||||
m_VariableList.insert(std::make_pair(a_name, a_value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void IntegerCalculator::removeVariable(const std::string& a_name)
|
||||
{
|
||||
std::map<std::string, int64_t>::iterator iter = m_VariableList.find(a_name);
|
||||
if (iter != m_VariableList.end())
|
||||
m_VariableList.erase(iter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t IntegerCalculator::calc(const std::string& a_calcText, size_t& a_pos, bool& a_IsEndParanthesis,
|
||||
const std::string& a_prevOp, const int64_t a_prevValue,
|
||||
const std::string& a_initOp)
|
||||
{
|
||||
std::string operation = a_initOp;
|
||||
int64_t value1 = a_prevValue;
|
||||
bool isNegative = false;
|
||||
std::string calcText = a_calcText;
|
||||
a_IsEndParanthesis = false;
|
||||
|
||||
while (a_pos < calcText.length())
|
||||
{
|
||||
if (' ' == calcText[a_pos])
|
||||
{
|
||||
a_pos++;
|
||||
}
|
||||
else if ('(' == calcText[a_pos])
|
||||
{
|
||||
m_ParanthesisCount++;
|
||||
bool dummy;
|
||||
int64_t value2 = calcSign(calc(calcText, ++a_pos, dummy), isNegative);
|
||||
value1 = doOperation(value1, operation, value2);
|
||||
|
||||
|
||||
size_t tmpPos = a_pos;
|
||||
std::string nextOp = getToken(a_calcText, tmpPos);
|
||||
if (isOperation(nextOp) && isOperation(a_prevOp) && !isOperationPriorityHigher(nextOp, a_prevOp))
|
||||
{
|
||||
|
||||
return value1;
|
||||
}
|
||||
|
||||
operation = "";
|
||||
}
|
||||
else if (')' == calcText[a_pos])
|
||||
{
|
||||
m_ParanthesisCount--;
|
||||
a_pos++;
|
||||
a_IsEndParanthesis = true;
|
||||
return value1;
|
||||
}
|
||||
else if (isDigit(calcText[a_pos]))
|
||||
{
|
||||
|
||||
|
||||
int64_t value2 = calcSign(convertValue(calcText, a_pos), isNegative);
|
||||
if (calcWithPriority(calcText, a_pos, value1, operation, value2, a_prevOp)) return value1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
std::string oldOperation = operation;
|
||||
operation = getToken(calcText, a_pos);
|
||||
|
||||
|
||||
if (!isOperation(operation))
|
||||
{
|
||||
int64_t value2 = 0;
|
||||
if (getVariableValue(operation, value2))
|
||||
{
|
||||
value2 = calcSign(value2, isNegative);
|
||||
if (calcWithPriority(calcText, a_pos, value1, oldOperation, value2, a_prevOp)) return value1;
|
||||
operation = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
m_Error = e_UnknownOperationOrVariable;
|
||||
m_AdditionalErrorText = operation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (oldOperation != "")
|
||||
{
|
||||
if (operation == "+")
|
||||
{
|
||||
operation = oldOperation;
|
||||
}
|
||||
else if (operation == "-")
|
||||
{
|
||||
isNegative = !isNegative;
|
||||
operation = oldOperation;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Error = e_NoOperandBetweenOperators;
|
||||
m_AdditionalErrorText = oldOperation + " " + operation;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return value1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IntegerCalculator::calcWithPriority(const std::string& a_calcText, size_t& a_pos, int64_t& a_value1, std::string& a_operation, int64_t a_value2, const std::string& a_prevOp)
|
||||
{
|
||||
bool isParaEnd = false;
|
||||
|
||||
size_t tmpPos = a_pos;
|
||||
std::string nextOp = getToken(a_calcText, tmpPos);
|
||||
if (isOperation(a_operation) && isOperation(nextOp) && isOperationPriorityHigher(nextOp, a_operation))
|
||||
{
|
||||
|
||||
a_value2 = calc(a_calcText, a_pos, isParaEnd, a_operation, a_value2);
|
||||
}
|
||||
a_value1 = doOperation(a_value1, a_operation, a_value2);
|
||||
if (isParaEnd || (isOperation(nextOp) && isOperation(a_prevOp) && !isOperationPriorityHigher(nextOp, a_prevOp)))
|
||||
{
|
||||
|
||||
return true;
|
||||
}
|
||||
a_operation = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t IntegerCalculator::calcSign(const int64_t a_value, bool& a_isNegative)
|
||||
{
|
||||
if (a_isNegative)
|
||||
{
|
||||
a_isNegative = false;
|
||||
return -a_value;
|
||||
}
|
||||
return a_value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t IntegerCalculator::convertValue(const std::string &a_valueText, size_t& a_pos)
|
||||
{
|
||||
std::string valueText = a_valueText.substr(a_pos);
|
||||
int base = 10;
|
||||
size_t startpos = 0;
|
||||
|
||||
bool isHex = (0 == valueText.find("0X")) || (0 == valueText.find("0x"));
|
||||
bool isBin = (0 == valueText.find("0B")) || (0 == valueText.find("0b"));
|
||||
if (isHex)
|
||||
{
|
||||
base = 16;
|
||||
startpos = 2;
|
||||
}
|
||||
else if (isBin)
|
||||
{
|
||||
base = 2;
|
||||
startpos = 2;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i=startpos; i<valueText.length(); i++)
|
||||
{
|
||||
if (!isDigit(valueText[i], isHex, isBin))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (valueText.length() > i && valueText[i] != ' ')
|
||||
{
|
||||
m_Error = e_InvalidOperand;
|
||||
int spacePos = valueText.find(' ');
|
||||
m_AdditionalErrorText = valueText.substr(0, spacePos);
|
||||
}
|
||||
a_pos += i;
|
||||
|
||||
int64_t value = 0;
|
||||
std::stringstream stream;
|
||||
stream.str(valueText.substr(startpos, i-startpos));
|
||||
if (2 == base)
|
||||
{
|
||||
|
||||
const std::string binValueAsText = stream.str();
|
||||
for (const char c : binValueAsText)
|
||||
{
|
||||
value = value << 1;
|
||||
if (c == '1')
|
||||
value += 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << std::setbase(base);
|
||||
stream >> value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::string IntegerCalculator::getToken(const std::string &a_calcText, size_t& a_pos)
|
||||
{
|
||||
|
||||
while (a_pos < a_calcText.length())
|
||||
{
|
||||
if (a_calcText[a_pos] == ' ') a_pos++;
|
||||
else break;
|
||||
}
|
||||
|
||||
|
||||
size_t startPos = a_pos;
|
||||
while (a_pos < a_calcText.length())
|
||||
{
|
||||
if (' ' == a_calcText[a_pos]) break;
|
||||
a_pos++;
|
||||
}
|
||||
return a_calcText.substr(startPos, a_pos-startPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IntegerCalculator::isOperation(const std::string& a_operation) const
|
||||
{
|
||||
std::map<std::string, int>::const_iterator iter = m_OperationList.find(a_operation);
|
||||
return (iter != m_OperationList.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t IntegerCalculator::doOperation(const int64_t a_value1, const std::string& a_operation, const int64_t a_value2)
|
||||
{
|
||||
|
||||
if (("+" == a_operation) || a_operation.empty())
|
||||
{
|
||||
return a_value1 + a_value2;
|
||||
}
|
||||
else if ("-" == a_operation)
|
||||
{
|
||||
return a_value1 - a_value2;
|
||||
}
|
||||
else if ("*" == a_operation)
|
||||
{
|
||||
return a_value1 * a_value2;
|
||||
}
|
||||
else if ("/" == a_operation)
|
||||
{
|
||||
if (0 == a_value2)
|
||||
{
|
||||
m_Error = e_DivisionByZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a_value1 / a_value2;
|
||||
}
|
||||
}
|
||||
else if ("%" == a_operation)
|
||||
{
|
||||
if (0 == a_value2)
|
||||
{
|
||||
m_Error = e_DivisionByZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a_value1 % a_value2;
|
||||
}
|
||||
}
|
||||
else if ("<<" == a_operation)
|
||||
{
|
||||
return a_value1 << a_value2;
|
||||
}
|
||||
else if (">>" == a_operation)
|
||||
{
|
||||
return a_value1 >> a_value2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Error = e_UnknownOperationOrVariable;
|
||||
m_AdditionalErrorText = a_operation;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IntegerCalculator::isOperationPriorityHigher(const std::string& a_operation1, const std::string& a_operation2) const
|
||||
{
|
||||
return (getPriority(a_operation1) > getPriority(a_operation2));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IntegerCalculator::getVariableValue(const std::string& a_variableName, int64_t& a_value) const
|
||||
{
|
||||
auto iter = m_VariableList.find(a_variableName);
|
||||
if (iter != m_VariableList.end())
|
||||
{
|
||||
a_value = iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool IntegerCalculator::isDigit(const char a_char, const bool a_isHex, const bool a_isBin)
|
||||
{
|
||||
if (a_isHex)
|
||||
{
|
||||
|
||||
return (a_char >= '0' && a_char <= '9') || (a_char >= 'A' && a_char <= 'F') || (a_char >= 'a' && a_char <= 'f');
|
||||
}
|
||||
else if (a_isBin)
|
||||
{
|
||||
|
||||
return (a_char >= '0' && a_char <= '1');
|
||||
}
|
||||
|
||||
return (a_char >= '0' && a_char <= '9');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int16_t IntegerCalculator::getPriority(const std::string& a_operation) const
|
||||
{
|
||||
std::map<std::string, int>::const_iterator iter = m_OperationList.find(a_operation);
|
||||
if (iter != m_OperationList.end())
|
||||
return iter->second;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void IntegerCalculator::replace(std::string& a_haystack, const std::string &a_searchText, const std::string &a_replaceText)
|
||||
{
|
||||
std::string::size_type searchSize = a_searchText.length();
|
||||
std::string::size_type replaceSize = a_replaceText.length();
|
||||
|
||||
std::string::size_type pos = a_haystack.find(a_searchText, 0);
|
||||
while (std::string::npos != pos)
|
||||
{
|
||||
a_haystack.replace(pos, searchSize, a_replaceText);
|
||||
pos += replaceSize;
|
||||
pos = a_haystack.find(a_searchText, pos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
namespace N_SST
|
||||
{
|
||||
|
||||
|
||||
class IntegerCalculator
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
enum E_Error
|
||||
{
|
||||
|
||||
|
||||
e_Ok,
|
||||
|
||||
|
||||
e_DivisionByZero,
|
||||
|
||||
|
||||
e_UnknownOperationOrVariable,
|
||||
|
||||
|
||||
e_NoOperandBetweenOperators,
|
||||
|
||||
|
||||
e_InvalidOperand,
|
||||
|
||||
|
||||
e_MissingLeftParanthesis,
|
||||
|
||||
|
||||
e_MissingRightParanthesis,
|
||||
|
||||
|
||||
e_UnknownError
|
||||
};
|
||||
|
||||
|
||||
IntegerCalculator();
|
||||
virtual ~IntegerCalculator() = default;
|
||||
|
||||
|
||||
|
||||
int64_t calc(const std::string& a_calcText, E_Error& a_error, std::string* a_addErrorText = nullptr);
|
||||
|
||||
|
||||
|
||||
void addVariable(const std::string& a_name, const int64_t a_value);
|
||||
|
||||
|
||||
|
||||
void removeVariable(const std::string& a_name);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
const std::map<std::string, int> m_OperationList;
|
||||
|
||||
|
||||
std::map<std::string, int64_t> m_VariableList;
|
||||
|
||||
|
||||
std::string m_AdditionalErrorText;
|
||||
|
||||
|
||||
int32_t m_ParanthesisCount;
|
||||
E_Error m_Error;
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t calc(const std::string& a_calcText, size_t& a_pos, bool& a_IsEndParanthesis,
|
||||
const std::string& a_prevOp = std::string(), const int64_t a_prevValue = 0,
|
||||
const std::string& a_initOp = std::string());
|
||||
|
||||
|
||||
|
||||
bool calcWithPriority(const std::string& a_calcText, size_t& a_pos, int64_t& a_value1,
|
||||
std::string& a_operation, int64_t a_value2, const std::string& a_prevOp);
|
||||
|
||||
|
||||
|
||||
static int64_t calcSign(const int64_t a_value, bool& a_isNegative);
|
||||
|
||||
|
||||
|
||||
int64_t convertValue(const std::string& a_valueText, size_t& a_pos);
|
||||
|
||||
|
||||
|
||||
static std::string getToken(const std::string& a_calcText, size_t& a_pos);
|
||||
|
||||
|
||||
|
||||
bool isOperation(const std::string& a_operation) const;
|
||||
|
||||
|
||||
|
||||
int64_t doOperation(const int64_t a_value1, const std::string& a_operation, const int64_t a_value2);
|
||||
|
||||
|
||||
|
||||
bool isOperationPriorityHigher(const std::string& a_operation1, const std::string& a_operation2) const;
|
||||
|
||||
|
||||
|
||||
virtual bool getVariableValue(const std::string& a_variableName, int64_t& a_value) const;
|
||||
|
||||
|
||||
|
||||
static bool isDigit(const char a_char, const bool a_isHex = false, const bool a_isBin = false);
|
||||
|
||||
|
||||
|
||||
int16_t getPriority(const std::string& a_operation) const;
|
||||
|
||||
|
||||
|
||||
static void replace(std::string& a_haystack, const std::string& a_searchText, const std::string& a_replaceText);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
|
||||
#include "LogViewBooleanEdit.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewBooleanEdit::LogViewBooleanEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly)
|
||||
: QCheckBox (a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, a_readonly)
|
||||
{
|
||||
const QString valueText = a_field->value(0);
|
||||
|
||||
setChecked(valueText.toInt() == 1);
|
||||
setEnabled(!a_readonly);
|
||||
}
|
||||
|
||||
|
||||
bool LogViewBooleanEdit::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
if (m_Valid)
|
||||
{
|
||||
if (a_telegram->isJsonTelegram())
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), isChecked());
|
||||
else
|
||||
a_telegram->setUIntX(getSize(), isChecked());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewWidget.hpp"
|
||||
#include <QCheckBox>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewBooleanEdit : public QCheckBox, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LogViewBooleanEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly);
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewDateTimeEdit.hpp"
|
||||
#include <time.h>
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewDateTimeEdit::LogViewDateTimeEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly)
|
||||
: QDateTimeEdit(a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, a_readonly)
|
||||
{
|
||||
if (a_readonly)
|
||||
{
|
||||
setReadOnly(true);
|
||||
setAlignment(a_field->isRightAligned() ? Qt::AlignRight : Qt::AlignLeft);
|
||||
}
|
||||
|
||||
|
||||
qint64 unixTime = 0;
|
||||
if (a_field->hasContent())
|
||||
{
|
||||
if (a_field->isMSecsField())
|
||||
unixTime = a_field->value(0, true).toLongLong();
|
||||
else
|
||||
unixTime = a_field->value(0, true).toInt() * 1000LL;
|
||||
}
|
||||
|
||||
if (0 == unixTime && !a_readonly)
|
||||
unixTime = ::time(nullptr) * 1000LL;
|
||||
|
||||
|
||||
setDateTime(QDateTime::fromMSecsSinceEpoch(unixTime));
|
||||
setDisplayFormat(QLatin1String("dd MMM yyyy hh:mm:ss"));
|
||||
setCalendarPopup(true);
|
||||
updateToolTip(QString::number(unixTime));
|
||||
|
||||
|
||||
|
||||
connect(this, &LogViewDateTimeEdit::editingFinished,
|
||||
this, &LogViewDateTimeEdit::checkAndOvertakeContent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewDateTimeEdit::checkAndOvertakeContent()
|
||||
{
|
||||
updateToolTip(QString::number(dateTime().toMSecsSinceEpoch() / 1000));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewDateTimeEdit::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
if (a_telegram->isJsonTelegram())
|
||||
{
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), dateTime().toMSecsSinceEpoch());
|
||||
}
|
||||
else
|
||||
{
|
||||
a_telegram->setNextFieldAsGpsTimeField();
|
||||
a_telegram->setUIntX(getSize(), dateTime().toMSecsSinceEpoch() / 1000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewWidget.hpp"
|
||||
#include <QDateTimeEdit>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewDateTimeEdit : public QDateTimeEdit, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
LogViewDateTimeEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly);
|
||||
|
||||
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
|
||||
public slots:
|
||||
void checkAndOvertakeContent();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewEnumEdit.hpp"
|
||||
#include "LogViewXdrStruct.hpp"
|
||||
#include "LogViewXdrValue.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
|
||||
LogViewEnumEdit::LogViewEnumEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly, const int a_index)
|
||||
: QComboBox(a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, a_readonly)
|
||||
{
|
||||
QString value = a_field->value(a_index);
|
||||
|
||||
|
||||
setToolTip(a_field->toolTipText());
|
||||
|
||||
|
||||
bool bCurrentIndexSet = false;
|
||||
int i = 0;
|
||||
while (LogViewXdrValue* child = (static_cast<const LogViewXdrStruct*>(a_field->xdrElement()))->getChildAsValue(i++))
|
||||
{
|
||||
QString enumText = LogViewField::makeClean(child->getName());
|
||||
if (!a_readonly || enumText == value)
|
||||
{
|
||||
addItem(QStringLiteral("%1 (%2)").arg(enumText).arg(child->getValue()), QVariant::fromValue(child->getValue()));
|
||||
if (a_readonly)
|
||||
bCurrentIndexSet = true;
|
||||
}
|
||||
|
||||
if (enumText == value)
|
||||
{
|
||||
setCurrentIndex(a_readonly ? 0 : i - 1);
|
||||
bCurrentIndexSet = true;
|
||||
if (!a_readonly || (0 != a_index))
|
||||
updateToolTip(itemData(currentIndex()).toString());
|
||||
}
|
||||
}
|
||||
|
||||
if (!bCurrentIndexSet)
|
||||
{
|
||||
addItem(value);
|
||||
setCurrentIndex(findText(value));
|
||||
}
|
||||
|
||||
|
||||
connect(this, QOverload<int>::of(&LogViewEnumEdit::currentIndexChanged),
|
||||
this, &LogViewEnumEdit::checkAndOvertakeContent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t LogViewEnumEdit::getSize() const
|
||||
{
|
||||
|
||||
const LogViewXdrStruct* xdrStruct = static_cast<const LogViewXdrStruct*>(m_Field->xdrElement());
|
||||
return xdrStruct->getEnumSize();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewEnumEdit::checkAndOvertakeContent()
|
||||
{
|
||||
updateToolTip(itemData(currentIndex()).toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewEnumEdit::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
bool ok;
|
||||
int value = itemData(currentIndex()).toInt(&ok);
|
||||
if (ok)
|
||||
{
|
||||
if (a_telegram->isJsonTelegram())
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), value);
|
||||
else
|
||||
a_telegram->setUIntX(getSize(), value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewWidget.hpp"
|
||||
#include <QComboBox>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewEnumEdit : public QComboBox, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
LogViewEnumEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly, const int a_index);
|
||||
|
||||
|
||||
uint16_t getSize() const override;
|
||||
|
||||
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
|
||||
protected slots:
|
||||
void checkAndOvertakeContent();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewField.hpp"
|
||||
#include <QtCore/QDateTime>
|
||||
#include "LogViewXdrElement.hpp"
|
||||
#include "LogViewXdrStandardType.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewField::LogViewField(const QString& a_name, const E_FieldKind a_kind, const LogViewXdrElement* a_xdrElement)
|
||||
: m_Name(a_name),
|
||||
m_IsRightAligned(false),
|
||||
m_Offset(0),
|
||||
m_Size(0),
|
||||
m_MaxArraySize(0),
|
||||
m_IsDynamicArray(false),
|
||||
m_HasContent(true),
|
||||
m_bDeleteXdr(false),
|
||||
m_Kind(a_kind),
|
||||
m_XdrElement(a_xdrElement),
|
||||
m_logger(getLogger("LogViewField"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LogViewField::~LogViewField()
|
||||
{
|
||||
for (LogViewField *f : qAsConst(m_Child))
|
||||
delete f;
|
||||
if (m_bDeleteXdr)
|
||||
delete m_XdrElement;
|
||||
}
|
||||
|
||||
LogViewField *LogViewField::clone(int arrayIdx) const
|
||||
{
|
||||
LogViewField *f = new LogViewField(*this);
|
||||
f->m_Child.clear();
|
||||
f->m_bDeleteXdr = false;
|
||||
for (auto * c : m_Child)
|
||||
{
|
||||
auto *clonedChild = c->clone(-1);
|
||||
if (arrayIdx >= 0)
|
||||
{
|
||||
QStringList sl = clonedChild->jsonPath();
|
||||
if (sl.size() > 1 && sl.at(sl.size() - 2).startsWith(QStringLiteral("index: ")))
|
||||
{
|
||||
sl[sl.size() - 2] = QStringLiteral("index: %1").arg(arrayIdx);
|
||||
clonedChild->setJsonPath(sl);
|
||||
}
|
||||
}
|
||||
f->addChild(clonedChild);
|
||||
}
|
||||
for (auto &val : f->m_ValueList)
|
||||
val.clear();
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewField::addChild(LogViewField* a_child)
|
||||
{
|
||||
if (a_child)
|
||||
m_Child.push_back(a_child);
|
||||
}
|
||||
|
||||
|
||||
void LogViewField::removeLastChild()
|
||||
{
|
||||
if (m_Child.empty())
|
||||
return;
|
||||
delete m_Child.takeLast();
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogViewField* LogViewField::child(int arrayIdx)
|
||||
{
|
||||
if (m_Child.size() > arrayIdx)
|
||||
return m_Child.at(arrayIdx);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void LogViewField::addValue(const QString &value)
|
||||
{
|
||||
m_ValueList.append(value);
|
||||
}
|
||||
|
||||
|
||||
void LogViewField::addValueBinaryHex(const QString &value)
|
||||
{
|
||||
const QByteArray ba = QByteArray::fromHex(value.toLatin1());
|
||||
for (const char c : ba)
|
||||
m_ValueList.append(QString::number(static_cast<unsigned char>(c)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QString LogViewField::value(int arrayIdx, const bool a_doNotMakeSpecialConversions) const
|
||||
{
|
||||
if (m_ValueList.size() > arrayIdx)
|
||||
{
|
||||
const QString &ret = m_ValueList.at(arrayIdx);
|
||||
if (!a_doNotMakeSpecialConversions)
|
||||
{
|
||||
if (isDateTimeField())
|
||||
return QDateTime::fromMSecsSinceEpoch(ret.toLongLong() * 1000).toString(QStringLiteral("dd.mm.yy hh:mm:ss.zzz"));
|
||||
if (isMSecsField())
|
||||
return QDateTime::fromMSecsSinceEpoch(ret.toLongLong()).toString(QStringLiteral("dd.mm.yy hh:mm:ss.zzz"));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
|
||||
int64_t LogViewField::getHighestValue() const
|
||||
{
|
||||
switch (m_XdrElement->getKind())
|
||||
{
|
||||
case LogViewXdrElement::e_KindStandardType:
|
||||
{
|
||||
int64_t highest = 1;
|
||||
|
||||
uint16_t bitSize = 8*static_cast<const LogViewXdrStandardType*>(m_XdrElement)->getEditSize();
|
||||
|
||||
if ((0 == m_Name.compare(QLatin1String("utm nordwert"), Qt::CaseInsensitive)) ||
|
||||
(0 == m_Name.compare(QLatin1String("utm ostwert"), Qt::CaseInsensitive)))
|
||||
bitSize -= 8;
|
||||
|
||||
switch (static_cast<const LogViewXdrStandardType*>(m_XdrElement)->getValueKind()) {
|
||||
case LogViewXdrStandardType::e_Boolean:
|
||||
return 1;
|
||||
case LogViewXdrStandardType::e_Signed:
|
||||
bitSize--;
|
||||
Q_FALLTHROUGH();
|
||||
case LogViewXdrStandardType::e_Unsigned:
|
||||
case LogViewXdrStandardType::e_Data:
|
||||
highest = highest << bitSize;
|
||||
highest--;
|
||||
break;
|
||||
default:
|
||||
highest = 0;
|
||||
break;
|
||||
}
|
||||
return highest;
|
||||
}
|
||||
default:
|
||||
ERROR_LOG(m_logger) << "Case not implemented";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int64_t LogViewField::getLowestValue() const
|
||||
{
|
||||
switch (m_XdrElement->getKind())
|
||||
{
|
||||
case LogViewXdrElement::e_KindStandardType:
|
||||
{
|
||||
int64_t lowest = 0;
|
||||
|
||||
switch (static_cast<const LogViewXdrStandardType*>(m_XdrElement)->getValueKind()) {
|
||||
case LogViewXdrStandardType::e_Boolean:
|
||||
return 0;
|
||||
case LogViewXdrStandardType::e_Signed:
|
||||
lowest = getHighestValue() + 1;
|
||||
lowest = -lowest;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
default:
|
||||
ERROR_LOG(m_logger) << "Case not implemented";
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewField::dump(const QString &a_indent) const
|
||||
{
|
||||
INFO_LOG(m_logger) << a_indent << "[";
|
||||
INFO_LOG(m_logger) << a_indent << "Field[" << m_Name << "]: m_Kind=" << m_Kind << " m_Offset=" << m_Offset << " m_Size=" << m_Size << " m_MaxArraySize=" << m_MaxArraySize << " m_IsRightAligned=" << m_IsRightAligned << " m_IsDynamicArray=" << m_IsDynamicArray << " m_ToolTipText=" << m_ToolTipText;
|
||||
|
||||
for (int i=0; i<m_ValueList.size(); i++)
|
||||
INFO_LOG(m_logger) << a_indent << "m_Value[" << i << "]=" << m_ValueList[i];
|
||||
|
||||
for (auto *c : m_Child)
|
||||
c->dump(a_indent + QLatin1Char(' '));
|
||||
|
||||
INFO_LOG(m_logger) << a_indent << "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QString LogViewField::makeClean(const QString &text)
|
||||
{
|
||||
QString a_uncleanText = text;
|
||||
|
||||
if (a_uncleanText.endsWith(QLatin1String("_rt")))
|
||||
a_uncleanText = a_uncleanText.left(a_uncleanText.length() - 3);
|
||||
|
||||
|
||||
a_uncleanText = a_uncleanText.replace(QLatin1Char('_'), QLatin1Char(' '));
|
||||
|
||||
|
||||
int pos = 0;
|
||||
while (a_uncleanText.length() > pos)
|
||||
{
|
||||
a_uncleanText[pos] = a_uncleanText[pos].toUpper();
|
||||
pos = a_uncleanText.indexOf(QLatin1Char(' '), pos + 1);
|
||||
if (-1 == pos)
|
||||
break;
|
||||
pos++;
|
||||
}
|
||||
|
||||
return a_uncleanText;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewField::isDateTimeField() const
|
||||
{
|
||||
QString name = m_Name.toLower();
|
||||
return name == QLatin1String("gps_zeit");
|
||||
}
|
||||
|
||||
bool LogViewField::isMSecsField() const
|
||||
{
|
||||
QString name = m_Name.toLower();
|
||||
return (name == QLatin1String("timestamp")) || (name == QLatin1String("effectstart"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewField::setMaxArraySize(uint16_t newVal, const bool a_isDynamic)
|
||||
{
|
||||
m_MaxArraySize = newVal;
|
||||
m_IsDynamicArray = a_isDynamic;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QStringList>
|
||||
#include <QVector>
|
||||
#include "logger.h"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewXdrElement;
|
||||
class LogViewField
|
||||
{
|
||||
public:
|
||||
enum E_FieldKind
|
||||
{
|
||||
e_FieldKindBorder,
|
||||
e_FieldKindEdit,
|
||||
e_FieldKindTab,
|
||||
e_FieldKindTabChild,
|
||||
e_FieldKindPodArray,
|
||||
e_FieldKindPodArrayChild
|
||||
};
|
||||
|
||||
|
||||
LogViewField(const QString& a_name, const E_FieldKind a_kind, const LogViewXdrElement* a_xdrElement);
|
||||
virtual ~LogViewField();
|
||||
|
||||
LogViewField *clone(int arrayIdx) const;
|
||||
|
||||
QString cleanName() const { return makeClean(m_Name); }
|
||||
QString name() const { return m_Name; }
|
||||
void setName(const QString &newVal) { m_Name = newVal; }
|
||||
|
||||
|
||||
void addChild(LogViewField* a_child);
|
||||
void removeLastChild();
|
||||
LogViewField *child(int arrayIdx);
|
||||
int childCount() const { return m_Child.size(); }
|
||||
|
||||
QString type() const { return m_type; }
|
||||
void setType(const QString &type) { m_type = type; }
|
||||
|
||||
LogViewField::E_FieldKind kind() const { return m_Kind; }
|
||||
|
||||
void addValue(const QString &value);
|
||||
void addValueBinaryHex(const QString &value);
|
||||
|
||||
|
||||
|
||||
QString value(int arrayIdx, const bool a_doNotMakeSpecialConversions = false) const;
|
||||
int valueListSize() const { return m_ValueList.size(); }
|
||||
|
||||
|
||||
bool isRightAligned() const { return m_IsRightAligned; }
|
||||
void setIsRightAligned(bool newVal) { m_IsRightAligned = newVal; }
|
||||
|
||||
|
||||
QString toolTipText() const { return m_ToolTipText; }
|
||||
void setToolTipText(const QString &newVal) { m_ToolTipText = newVal; }
|
||||
|
||||
|
||||
int64_t getHighestValue() const;
|
||||
int64_t getLowestValue() const;
|
||||
|
||||
|
||||
|
||||
void dump(const QString &a_indent = QString()) const;
|
||||
|
||||
|
||||
|
||||
static QString makeClean(const QString &text);
|
||||
|
||||
|
||||
int size() const { return m_Size; }
|
||||
void setSize(int newVal) { m_Size = newVal; }
|
||||
|
||||
|
||||
const LogViewXdrElement* xdrElement() const { return m_XdrElement; }
|
||||
|
||||
|
||||
|
||||
bool isDateTimeField() const;
|
||||
bool isMSecsField() const;
|
||||
|
||||
|
||||
uint16_t maxArraySize() const { return m_MaxArraySize; }
|
||||
void setMaxArraySize(uint16_t newVal, const bool a_isDynamic);
|
||||
|
||||
|
||||
|
||||
bool isDynamicArray() const { return m_IsDynamicArray; }
|
||||
|
||||
|
||||
bool hasContent() const { return m_HasContent; }
|
||||
void setHasContent(bool newVal) { m_HasContent = newVal; }
|
||||
|
||||
void setDeleteXdr(bool bDelete) { m_bDeleteXdr = bDelete; }
|
||||
|
||||
void setJsonPath(const QStringList &path) { m_jsonPath = path; }
|
||||
QStringList jsonPath() const { return m_jsonPath; }
|
||||
|
||||
protected:
|
||||
|
||||
QString m_Name;
|
||||
QString m_type;
|
||||
QStringList m_ValueList;
|
||||
QStringList m_jsonPath;
|
||||
bool m_IsRightAligned;
|
||||
QString m_ToolTipText;
|
||||
uint16_t m_Offset;
|
||||
int m_Size;
|
||||
uint16_t m_MaxArraySize;
|
||||
|
||||
|
||||
bool m_IsDynamicArray;
|
||||
bool m_HasContent;
|
||||
bool m_bDeleteXdr;
|
||||
QVector<LogViewField*> m_Child;
|
||||
|
||||
E_FieldKind m_Kind;
|
||||
|
||||
const LogViewXdrElement *m_XdrElement;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QtCore/QMap>
|
||||
#include "LogViewModels.hpp"
|
||||
#include "LogViewTelegramEditModel.hpp"
|
||||
#include <set>
|
||||
#include <QMenu>
|
||||
#include "logger.h"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewTelegram;
|
||||
}
|
||||
class QTableView;
|
||||
|
||||
class QGroupBox;
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class QSplitter;
|
||||
class QToolBox;
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewInjectionThread;
|
||||
class TelegramEdit;
|
||||
|
||||
|
||||
|
||||
class LogViewGui : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit LogViewGui(QWidget* a_parent);
|
||||
|
||||
static const QLatin1String WINDOW_GROUP;
|
||||
static const QLatin1String SCREEN;
|
||||
|
||||
protected:
|
||||
|
||||
const QSize RADIO_BUTTON_ICON_SIZE;
|
||||
static const QLatin1String SIZE;
|
||||
static const QLatin1String POS;
|
||||
static const QLatin1String SPLITTPOS;
|
||||
static const QLatin1String TOOLBOXINDEX;
|
||||
|
||||
QGroupBox *m_CentralSelectionGroup;
|
||||
std::set<int> m_CentralTelegramFilterList;
|
||||
QCheckBox* m_SentCentralTelCheckBox;
|
||||
QCheckBox* m_ReceivedCentralTelCheckBox;
|
||||
QCheckBox* m_PosCentralTelCheckBox;
|
||||
QCheckBox* m_ackCentralTelCheckBox;
|
||||
|
||||
QGroupBox *m_TetraSelectionGroup;
|
||||
std::set<int> m_TetraTelegramFilterList;
|
||||
QCheckBox* m_SentTetraTelCheckBox;
|
||||
QCheckBox* m_ReceivedTetraTelCheckBox;
|
||||
QCheckBox* m_PosTetraTelCheckBox;
|
||||
QCheckBox* m_LoginTetraTelCheckBox;
|
||||
QCheckBox* m_RegisterTetraTelCheckBox;
|
||||
QCheckBox* m_ReportTetraTelCheckBox;
|
||||
QCheckBox* m_FragmentedTetraTelCheckBox;
|
||||
QCheckBox* m_AirInterfaceLoadTetraTelCheckBox;
|
||||
|
||||
QGroupBox *m_WlsSelectionGroup;
|
||||
std::set<int> m_WlsTelegramFilterList;
|
||||
QCheckBox* m_SentWlsTelCheckBox;
|
||||
QCheckBox* m_ReceivedWlsTelCheckBox;
|
||||
QCheckBox* m_PosWlsTelCheckBox;
|
||||
QCheckBox* m_ackWlsTelCheckBox;
|
||||
|
||||
QString m_ActualLogfile;
|
||||
qint64 m_LogfileSize;
|
||||
bool m_DoReload;
|
||||
QToolBox* m_ToolBox;
|
||||
QTableView *m_ParticipantTableView;
|
||||
ParticipantModel *m_participantModel;
|
||||
QSortFilterProxyModel *m_participantProxyModel;
|
||||
|
||||
QTableView *m_logTelegramView;
|
||||
TelegramModel *m_telegramModel;
|
||||
TelegramProxyModel *m_telegramProxyModel;
|
||||
|
||||
QLabel *m_TelegramStatus;
|
||||
|
||||
QLabel *m_ParticipantStatus;
|
||||
|
||||
QGroupBox *m_ParticipantSelectionGroup;
|
||||
|
||||
TelegramEdit *m_EditTelegramController;
|
||||
|
||||
QTimer *m_TailTimer;
|
||||
|
||||
QSplitter *m_Splitter;
|
||||
|
||||
LogViewInjectionThread *m_InjectionThread;
|
||||
|
||||
QLabel *m_InjectionStatus;
|
||||
|
||||
|
||||
QHash<int, int> m_participantListTelCount;
|
||||
|
||||
QHash<int, int> m_participantListIssi;
|
||||
|
||||
QAction *m_reloadAction;
|
||||
QTimer *m_replayTimer;
|
||||
int m_currentReplayRow;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
protected:
|
||||
void readTelegramsFromLogFile(const QString& a_fileName, const qint64 a_filePos = 0);
|
||||
|
||||
|
||||
|
||||
void addToParticipantList(const QSharedPointer<LogViewTelegram> &a_telegram);
|
||||
void syncParticipantList();
|
||||
QCheckBox* createRadioButton(const QString& a_buttonName, const QString& a_iconName);
|
||||
|
||||
|
||||
|
||||
void startInjectionThread();
|
||||
|
||||
void closeEvent(QCloseEvent* a_closeEvent) override;
|
||||
|
||||
void createCentralSelectionWidget();
|
||||
void createTetraSelectionWidget();
|
||||
void createWlsSelectionWidget();
|
||||
|
||||
protected slots:
|
||||
void addTelegramToEdit();
|
||||
void showHexData();
|
||||
void exportAsCsv();
|
||||
void exportAsJson();
|
||||
void onStartLogReplay();
|
||||
void onReplayTimerTimeout();
|
||||
|
||||
void loadSpecificationFiles();
|
||||
|
||||
|
||||
void newTelegramFile();
|
||||
|
||||
|
||||
void loadTelegramFile();
|
||||
|
||||
|
||||
|
||||
void updateLogfile();
|
||||
|
||||
void selectedParticipantChanged();
|
||||
|
||||
void showTelegramTable();
|
||||
|
||||
|
||||
void customMenuRequested(const QPoint &pos);
|
||||
|
||||
void changeSettings();
|
||||
|
||||
|
||||
|
||||
void reloadOnOff();
|
||||
|
||||
|
||||
|
||||
void updateInjectionStatus(const QString& a_picName, const QString& a_toopTipText);
|
||||
|
||||
void onLogTelegramViewDoubleClicked(const QModelIndex &index);
|
||||
|
||||
private slots:
|
||||
void onSettingsChanged(uint32_t changedFlags);
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewInjectionThread.hpp"
|
||||
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include "LogViewOptionDialog.hpp"
|
||||
#include <CoPrtCnv/CoPrtCnvInjectionHeader.hpp>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
LogViewInjectionThread::LogViewInjectionThread()
|
||||
: m_DoStartConnection(false)
|
||||
, m_SendingPossible(false)
|
||||
, m_Socket(nullptr)
|
||||
, m_Timer(nullptr)
|
||||
, m_logger(getLogger("LogViewInjectionThread"))
|
||||
{
|
||||
|
||||
QSettings settings;
|
||||
settings.beginGroup(LogViewOptionDialog::INJECTION_GROUP);
|
||||
m_Hostname = settings.value(LogViewOptionDialog::INJECTION_HOSTNAME).toString();
|
||||
if (m_Hostname.isEmpty())
|
||||
{
|
||||
|
||||
m_Hostname = QLatin1String("localhost");
|
||||
settings.setValue(LogViewOptionDialog::INJECTION_HOSTNAME, m_Hostname);
|
||||
}
|
||||
m_Port = settings.value(LogViewOptionDialog::INJECTION_PORT).toInt();
|
||||
if (0 == m_Port || m_Port > 65535)
|
||||
{
|
||||
m_Port = 46666;
|
||||
settings.setValue(LogViewOptionDialog::INJECTION_PORT, m_Port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LogViewInjectionThread::run()
|
||||
{
|
||||
emit updateStatus(QLatin1String(":/image/RedLamp.png"),
|
||||
tr("LogView ist nicht mit TETRA-If-Injection-Server (%1:%2) verbunden").arg(m_Hostname).arg(m_Port));
|
||||
QTimer::singleShot(100, this, &LogViewInjectionThread::tryToConnect);
|
||||
|
||||
exec();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewInjectionThread::setPort(uint16_t port)
|
||||
{
|
||||
m_Port = port;
|
||||
QSettings settings;
|
||||
settings.beginGroup(LogViewOptionDialog::INJECTION_GROUP);
|
||||
settings.setValue(LogViewOptionDialog::INJECTION_PORT, m_Port);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool LogViewInjectionThread::isSendingPossible() const
|
||||
{
|
||||
return m_SendingPossible;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewInjectionThread::tryToConnect()
|
||||
{
|
||||
|
||||
if (!m_Socket)
|
||||
{
|
||||
m_Socket = new QTcpSocket(this);
|
||||
connect(m_Socket, &QTcpSocket::connected, this, &LogViewInjectionThread::doConnect);
|
||||
connect(m_Socket, &QTcpSocket::disconnected, this, &LogViewInjectionThread::doDisconnect);
|
||||
}
|
||||
|
||||
|
||||
if (!m_Timer)
|
||||
{
|
||||
m_Timer = new QTimer(this);
|
||||
connect(m_Timer, &QTimer::timeout, this, &LogViewInjectionThread::tryToConnect);
|
||||
}
|
||||
m_Timer->setInterval(3000);
|
||||
m_Timer->start();
|
||||
|
||||
INFO_LOG(m_logger) << "Try to connect to injection-server of TETRA-If (" << m_Hostname << ":" << m_Port << ")";
|
||||
m_Socket->connectToHost(m_Hostname, m_Port);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewInjectionThread::doConnect()
|
||||
{
|
||||
INFO_LOG(m_logger) << "LogView has successful connected to injection-server of TETRA-If";
|
||||
m_SendingPossible = true;
|
||||
m_Timer->stop();
|
||||
emit updateStatus(QLatin1String(":/image/GreenLamp.png"),
|
||||
tr("LogView ist mit TETRA-If-Injection-Server (%1:%2) verbunden").arg(m_Hostname).arg(m_Port));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewInjectionThread::doDisconnect()
|
||||
{
|
||||
INFO_LOG(m_logger) << "LogView was disconnected from injection-server of TETRA-If";
|
||||
m_SendingPossible = false;
|
||||
emit updateStatus(QLatin1String(":/image/RedLamp.png"),
|
||||
tr("LogView ist nicht mehr mit TETRA-If-Injection-Server (%1:%2) verbunden").arg(m_Hostname).arg(m_Port));
|
||||
tryToConnect();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewInjectionThread::sendTelegram(LogViewTelegram* a_telegram, const bool a_doSendAsCentralTelegram)
|
||||
{
|
||||
INFO_LOG(m_logger) << "inject " << (a_doSendAsCentralTelegram ? "central" : "Tetra") << " telegram";
|
||||
if (!m_Socket || m_Socket->state() != QAbstractSocket::ConnectedState)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Try to write a telegramm but we are not connected";
|
||||
return;
|
||||
}
|
||||
N_CoPrtCnv::CoPrtCnvInjectionHeader injectionHeader;
|
||||
injectionHeader.m_Kind = a_doSendAsCentralTelegram ? N_CoPrtCnv::CoPrtCnvInjectionHeader::eCentral : N_CoPrtCnv::CoPrtCnvInjectionHeader::eRadio;
|
||||
const QByteArray &data = a_telegram->getData();
|
||||
injectionHeader.m_Size = data.size();
|
||||
m_Socket->write((char*)(&injectionHeader), sizeof(injectionHeader));
|
||||
m_Socket->write(data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QThread>
|
||||
#include "logger.h"
|
||||
|
||||
class QTcpSocket;
|
||||
class QTimer;
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewTelegram;
|
||||
|
||||
|
||||
|
||||
class LogViewInjectionThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
LogViewInjectionThread();
|
||||
|
||||
void run();
|
||||
|
||||
void setPort(uint16_t port);
|
||||
|
||||
bool isSendingPossible() const;
|
||||
|
||||
|
||||
|
||||
void sendTelegram(LogViewTelegram* a_telegram, const bool a_doSendAsCentralTelegram);
|
||||
|
||||
protected:
|
||||
|
||||
bool m_DoStartConnection;
|
||||
bool m_SendingPossible;
|
||||
QString m_Hostname;
|
||||
int m_Port;
|
||||
QTcpSocket *m_Socket;
|
||||
|
||||
QTimer *m_Timer;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
protected:
|
||||
protected slots:
|
||||
void tryToConnect();
|
||||
|
||||
|
||||
void doConnect();
|
||||
|
||||
|
||||
void doDisconnect();
|
||||
|
||||
public:
|
||||
signals:
|
||||
|
||||
|
||||
void updateStatus(const QString& a_picName, const QString& a_toolTipText);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include <nglapplication/nglapplication.h>
|
||||
#include <QDesktopWidget>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QNetworkProxy>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "LogViewGui.hpp"
|
||||
#include "logger.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::string logConfigFileName;
|
||||
std::string dir;
|
||||
|
||||
#ifdef WIN32
|
||||
dir = argv[0];
|
||||
#else
|
||||
std::stringstream s;
|
||||
s << "/proc/" << getpid() << "/exe";
|
||||
char buf[1024];
|
||||
ssize_t len = readlink(s.str().c_str(), buf, 1024);
|
||||
if(len > 0) {
|
||||
buf[len] = '\0';
|
||||
dir = buf;
|
||||
} else {
|
||||
|
||||
dir = argv[0];
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string::size_type pos = dir.find_last_of('/');
|
||||
if (std::string::npos != pos)
|
||||
logConfigFileName += dir.substr(0, pos + 1);;
|
||||
logConfigFileName += "LogView_log4cxx.props";
|
||||
|
||||
qputenv("TDS_DEVEL", QByteArray::number(1));
|
||||
NGLApplication app(argc, argv);
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
||||
app.createLogger("LogView", logConfigFileName.c_str());
|
||||
|
||||
QCoreApplication::setOrganizationName(QLatin1String("RME"));
|
||||
QCoreApplication::setApplicationName(QLatin1String("LogView"));
|
||||
|
||||
QSettings settings;
|
||||
settings.beginGroup(N_LogView::LogViewGui::WINDOW_GROUP);
|
||||
int screenNbr = settings.value(N_LogView::LogViewGui::SCREEN, 0).toInt();
|
||||
settings.endGroup();
|
||||
|
||||
N_LogView::LogViewGui* logViewGui = new N_LogView::LogViewGui(QApplication::desktop()->screen(screenNbr));
|
||||
logViewGui->show();
|
||||
int ret = app.exec();
|
||||
|
||||
delete logViewGui;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,548 @@
|
||||
|
||||
|
||||
|
||||
#include "LogViewModels.hpp"
|
||||
|
||||
#include <QtGui/QFont>
|
||||
#include <QtGui/QPalette>
|
||||
#include <QtGui/QGuiApplication>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
|
||||
int ParticipantModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : m_particpants.size();
|
||||
}
|
||||
|
||||
|
||||
int ParticipantModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : 3;
|
||||
}
|
||||
|
||||
|
||||
QVariant ParticipantModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.isValid() && index.row() < m_particpants.size())
|
||||
{
|
||||
const auto &p = m_particpants.at(index.row());
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return p.first;
|
||||
case 1:
|
||||
return p.second;
|
||||
case 2:
|
||||
return m_particpantMap.value(p.first);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return tr("hex: 0x%1").arg(p.first, 4, 16, QLatin1Char('0'));
|
||||
case 1:
|
||||
return tr("hex: 0x%1").arg(p.second, 4, 16, QLatin1Char('0'));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (role == Qt::BackgroundColorRole)
|
||||
{
|
||||
if (p.first == 0)
|
||||
return QVariant();
|
||||
if (m_participantHeatmap.isEmpty())
|
||||
updateHeatMap();
|
||||
return m_participantHeatmap.value(p.first);
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant ParticipantModel::headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (role == Qt::DisplayRole && orientation == Qt::Horizontal)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return tr("Equip. No.");
|
||||
case 1:
|
||||
return tr("ISSI");
|
||||
case 2:
|
||||
return tr("#");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QAbstractTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
|
||||
void ParticipantModel::clearParticipants()
|
||||
{
|
||||
beginResetModel();
|
||||
m_particpantMap.clear();
|
||||
m_particpants.clear();
|
||||
m_participantHeatmap.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
||||
bool ParticipantModel::addUpdateParticipants(const QVector<int> &eqIds,
|
||||
const QVector<int> &issis,
|
||||
const QVector<int> &numberOfTelegrams)
|
||||
{
|
||||
QVector<QPair<int, int> > newParticpants;
|
||||
for (int i = 0; i < eqIds.size(); ++i)
|
||||
{
|
||||
const int eqId = eqIds.at(i);
|
||||
const int issi = issis.at(i);
|
||||
const int cntTelegrams = numberOfTelegrams.at(i);
|
||||
auto it = m_particpantMap.find(eqId);
|
||||
if (it != m_particpantMap.end())
|
||||
{
|
||||
it.value() = cntTelegrams;
|
||||
continue;
|
||||
}
|
||||
newParticpants.push_back(qMakePair(eqId, issi));
|
||||
m_particpantMap[eqId] = cntTelegrams;
|
||||
}
|
||||
|
||||
if (!newParticpants.isEmpty())
|
||||
{
|
||||
beginInsertRows(QModelIndex(), m_particpants.size(), m_particpants.size() + newParticpants.size() - 1);
|
||||
m_particpants.append(newParticpants);
|
||||
endInsertRows();
|
||||
}
|
||||
m_participantHeatmap.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ParticipantModel::updateHeatMap() const
|
||||
{
|
||||
int maxNumberOfTelegrams = 0;
|
||||
for (auto it = m_particpantMap.begin(); it != m_particpantMap.end(); ++it)
|
||||
{
|
||||
if (it.key() == 0)
|
||||
continue;
|
||||
maxNumberOfTelegrams = std::max(it.value(), maxNumberOfTelegrams);
|
||||
}
|
||||
|
||||
const QColor backgroundColor = QGuiApplication::palette().base().color();
|
||||
const QColor redColor = Qt::red;
|
||||
for (auto it = m_particpantMap.begin(); it != m_particpantMap.end(); ++it)
|
||||
{
|
||||
const int eqId = it.key();
|
||||
if (eqId == 0)
|
||||
continue;
|
||||
|
||||
const int nbrTelegrams = it.value();
|
||||
QColor curColor;
|
||||
double percent = static_cast<double>(nbrTelegrams) / maxNumberOfTelegrams;
|
||||
curColor.setRed(backgroundColor.red() - ((backgroundColor.red() - redColor.red()) * percent));
|
||||
curColor.setGreen(backgroundColor.green() - ((backgroundColor.green() - redColor.green()) * percent));
|
||||
curColor.setBlue(backgroundColor.blue() - ((backgroundColor.blue() - redColor.blue()) * percent));
|
||||
m_participantHeatmap[eqId] = curColor;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int TelegramModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : m_telegrams.size();
|
||||
}
|
||||
|
||||
|
||||
int TelegramModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : 6;
|
||||
}
|
||||
|
||||
|
||||
QVariant TelegramModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.isValid() && index.row() < m_telegrams.size())
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
const QSharedPointer<LogViewTelegram> &telegram = m_telegrams.at(index.row());
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return telegram->getDestinationText();
|
||||
case 1:
|
||||
return telegram->getName();
|
||||
case 2:
|
||||
return telegram->getParticipantId();
|
||||
case 3:
|
||||
return telegram->getLogTimeText();
|
||||
case 4:
|
||||
return telegram->getGpsTimeText();
|
||||
case 5:
|
||||
return telegram->getDelay();
|
||||
}
|
||||
}
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
const QSharedPointer<LogViewTelegram> telegram = m_telegrams.at(index.row());
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return telegram->getIcon();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
const QSharedPointer<LogViewTelegram> telegram = m_telegrams.at(index.row());
|
||||
switch (index.column())
|
||||
{
|
||||
case 1:
|
||||
return telegram->getToolTipText(LogViewTelegram::e_ColName);
|
||||
case 3:
|
||||
return telegram->getToolTipText(LogViewTelegram::e_ColLogTime);
|
||||
case 4:
|
||||
return telegram->getToolTipText(LogViewTelegram::e_ColGpsTime);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant TelegramModel::headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal)
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return tr("Dest.");
|
||||
case 1:
|
||||
return tr("Description");
|
||||
case 2:
|
||||
return tr("Equip. No.");
|
||||
case 3:
|
||||
return tr("Send/Recieve time");
|
||||
case 4:
|
||||
return tr("GPS time");
|
||||
case 5:
|
||||
return tr("Delay");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return QAbstractTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
|
||||
void TelegramModel::clearTelegrams()
|
||||
{
|
||||
beginResetModel();
|
||||
m_telegrams.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
||||
void TelegramModel::appendTelegrams(const QVector<QSharedPointer<LogViewTelegram> > &telegrams)
|
||||
{
|
||||
if (telegrams.isEmpty())
|
||||
return;
|
||||
beginInsertRows(QModelIndex(), m_telegrams.size(), m_telegrams.size() + telegrams.size() - 1);
|
||||
m_telegrams += telegrams;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
void TelegramModel::appendTelegram(const QSharedPointer<LogViewTelegram> &telegram)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), m_telegrams.size(), m_telegrams.size());
|
||||
m_telegrams.push_back(telegram);
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
QSharedPointer<LogViewTelegram> TelegramModel::telegram(int row) const
|
||||
{
|
||||
if (row >= 0 && row < m_telegrams.size())
|
||||
return m_telegrams.at(row);
|
||||
return QSharedPointer<LogViewTelegram>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilterByEquipmentIds(bool bFilterByEquipmentIds)
|
||||
{
|
||||
if (m_bFilterByEquipmentIds == bFilterByEquipmentIds)
|
||||
return;
|
||||
m_bFilterByEquipmentIds = bFilterByEquipmentIds;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setAllowedEquipmentIds(const std::set<int> &allowedEquipmentIds)
|
||||
{
|
||||
if (m_allowedEquipmentIds == allowedEquipmentIds)
|
||||
return;
|
||||
m_allowedEquipmentIds = allowedEquipmentIds;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilteredCentralTelegramIds(const std::set<int> &filteredCentralTelegramIds)
|
||||
{
|
||||
if (m_filteredCentralTelegramIds == filteredCentralTelegramIds)
|
||||
return;
|
||||
m_filteredCentralTelegramIds = filteredCentralTelegramIds;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilteredTetraTelegramIds(const std::set<int> &filteredTetraTelegramIds)
|
||||
{
|
||||
if (m_filteredTetraTelegramIds == filteredTetraTelegramIds)
|
||||
return;
|
||||
m_filteredTetraTelegramIds = filteredTetraTelegramIds;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilteredWlsTelegramIds(const std::set<int> &filteredWlsTelegramIds)
|
||||
{
|
||||
if (m_filteredWlsTelegramIds == filteredWlsTelegramIds)
|
||||
return;
|
||||
m_filteredWlsTelegramIds = filteredWlsTelegramIds;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilterCentralTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction,
|
||||
bool bFilter)
|
||||
{
|
||||
std::set<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol> curFilter = m_filterCentralTelegrams;
|
||||
if (bFilter)
|
||||
curFilter.insert(direction);
|
||||
else
|
||||
curFilter.erase(direction);
|
||||
if (curFilter == m_filterCentralTelegrams)
|
||||
return;
|
||||
m_filterCentralTelegrams = curFilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilterTetraTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction,
|
||||
bool bFilter)
|
||||
{
|
||||
std::set<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol> curFilter = m_filterTetraTelegrams;
|
||||
if (bFilter)
|
||||
curFilter.insert(direction);
|
||||
else
|
||||
curFilter.erase(direction);
|
||||
if (curFilter == m_filterTetraTelegrams)
|
||||
return;
|
||||
m_filterTetraTelegrams = curFilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type pduType,
|
||||
bool bFilter)
|
||||
{
|
||||
std::set<N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type> curFilter = m_filterTetraPDU;
|
||||
if (bFilter)
|
||||
curFilter.insert(pduType);
|
||||
else
|
||||
curFilter.erase(pduType);
|
||||
if (curFilter == m_filterTetraPDU)
|
||||
return;
|
||||
m_filterTetraPDU = curFilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void TelegramProxyModel::setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction,
|
||||
bool bFilter)
|
||||
{
|
||||
std::set<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol> curFilter = m_filterWlsTelegrams;
|
||||
if (bFilter)
|
||||
curFilter.insert(direction);
|
||||
else
|
||||
curFilter.erase(direction);
|
||||
if (curFilter == m_filterWlsTelegrams)
|
||||
return;
|
||||
m_filterWlsTelegrams = curFilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilterTetraLogin(bool bFilter)
|
||||
{
|
||||
if (m_bFilterLoginTelegrams == bFilter)
|
||||
return;
|
||||
m_bFilterLoginTelegrams = bFilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
void TelegramProxyModel::setFilterTetraFragmented(bool bFilter)
|
||||
{
|
||||
if (m_bFilterFragmentedTelegrams == bFilter)
|
||||
return;
|
||||
m_bFilterFragmentedTelegrams = bFilter;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
QSharedPointer<LogViewTelegram> TelegramProxyModel::telegram(int row) const
|
||||
{
|
||||
const TelegramModel *tm = qobject_cast<TelegramModel *>(sourceModel());
|
||||
if (!tm)
|
||||
return {};
|
||||
const int srcRow = mapToSource(index(row, 0)).row();
|
||||
return tm->telegram(srcRow);
|
||||
}
|
||||
|
||||
|
||||
bool TelegramProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
if (left.column() != right.column())
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
const TelegramModel *tm = qobject_cast<TelegramModel *>(sourceModel());
|
||||
if (!tm)
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
QSharedPointer<LogViewTelegram> teleLeft = tm->telegram(left.row());
|
||||
QSharedPointer<LogViewTelegram> teleRight = tm->telegram(right.row());
|
||||
if (!teleLeft || !teleRight)
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
|
||||
switch (left.column())
|
||||
{
|
||||
case 0:
|
||||
return teleLeft->getDestination() < teleRight->getDestination();
|
||||
case 1:
|
||||
return teleLeft->getName() < teleRight->getName();
|
||||
case 2:
|
||||
return teleLeft->getParticipantId() < teleRight->getParticipantId();
|
||||
case 3:
|
||||
return teleLeft->getLogTime() < teleRight->getLogTime();
|
||||
case 4:
|
||||
return teleLeft->getGpsTime() < teleRight->getGpsTime();
|
||||
case 5:
|
||||
return teleLeft->getDelay() < teleRight->getDelay();
|
||||
}
|
||||
return QSortFilterProxyModel::lessThan(left, right);
|
||||
}
|
||||
|
||||
|
||||
bool TelegramProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
|
||||
const TelegramModel *tm = qobject_cast<TelegramModel *>(sourceModel());
|
||||
if (!tm)
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
QSharedPointer<LogViewTelegram> tele = tm->telegram(source_row);
|
||||
if (!tele)
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
|
||||
if (m_bFilterByEquipmentIds)
|
||||
{
|
||||
int equipId = tele->getParticipantId();
|
||||
if (m_allowedEquipmentIds.find(equipId) == m_allowedEquipmentIds.end())
|
||||
return false;
|
||||
}
|
||||
switch (tele->getProtocol())
|
||||
{
|
||||
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral:
|
||||
if (!m_filteredCentralTelegramIds.empty())
|
||||
{
|
||||
const int telegramId = tele->getTelId();
|
||||
if (m_filteredCentralTelegramIds.find(telegramId) != m_filteredCentralTelegramIds.end())
|
||||
return false;
|
||||
}
|
||||
if (!m_filterCentralTelegrams.empty())
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction = tele->getDirection();
|
||||
if (m_filterCentralTelegrams.find(direction) != m_filterCentralTelegrams.end())
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolTetra:
|
||||
{
|
||||
if (!m_filteredTetraTelegramIds.empty())
|
||||
{
|
||||
const int telegramId = tele->getTelId();
|
||||
if (m_filteredTetraTelegramIds.find(telegramId) != m_filteredTetraTelegramIds.end())
|
||||
return false;
|
||||
}
|
||||
if (!m_filterTetraTelegrams.empty())
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction = tele->getDirection();
|
||||
if (m_filterTetraTelegrams.find(direction) != m_filterTetraTelegrams.end())
|
||||
return false;
|
||||
}
|
||||
const N_CoPrtCnv::CoPrtCnvRadioTelegram *tetraTelegram = tele->getTetraTelegram();
|
||||
if (tetraTelegram)
|
||||
{
|
||||
if (!m_filterTetraPDU.empty())
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type pduType = tetraTelegram->getPDU_Type();
|
||||
if (m_filterTetraPDU.find(pduType) != m_filterTetraPDU.end())
|
||||
return false;
|
||||
}
|
||||
if (m_bFilterLoginTelegrams)
|
||||
{
|
||||
if (tetraTelegram->isLoginTelegram())
|
||||
return false;
|
||||
}
|
||||
if (m_bFilterFragmentedTelegrams)
|
||||
{
|
||||
if (!tetraTelegram->isLoginTelegram() && !tetraTelegram->isNormalTelegram())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolWls:
|
||||
if (!m_filteredWlsTelegramIds.empty())
|
||||
{
|
||||
const int telegramId = tele->getTelId();
|
||||
if (m_filteredWlsTelegramIds.find(telegramId) != m_filteredWlsTelegramIds.end())
|
||||
return false;
|
||||
}
|
||||
if (!m_filterWlsTelegrams.empty())
|
||||
{
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction = tele->getDirection();
|
||||
if (m_filterWlsTelegrams.find(direction) != m_filterWlsTelegrams.end())
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <set>
|
||||
|
||||
#include <CoPrtCnv/CoPrtCnvLogHeader.hpp>
|
||||
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
|
||||
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
class ParticipantModel final : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QAbstractTableModel::QAbstractTableModel;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
void clearParticipants();
|
||||
bool addUpdateParticipants(const QVector<int> &eqIds,
|
||||
const QVector<int> &issis,
|
||||
const QVector<int> &numberOfTelegrams);
|
||||
protected:
|
||||
void updateHeatMap() const;
|
||||
protected:
|
||||
|
||||
QVector<QPair<int, int> > m_particpants;
|
||||
|
||||
QHash<int, int> m_particpantMap;
|
||||
|
||||
mutable QHash<int, QColor> m_participantHeatmap;
|
||||
};
|
||||
|
||||
class TelegramModel final : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QAbstractTableModel::QAbstractTableModel;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
void clearTelegrams();
|
||||
void appendTelegrams(const QVector<QSharedPointer<LogViewTelegram> > &telegrams);
|
||||
void appendTelegram(const QSharedPointer<LogViewTelegram> &telegram);
|
||||
QSharedPointer<LogViewTelegram> telegram(int row) const;
|
||||
protected:
|
||||
QVector<QSharedPointer<LogViewTelegram> > m_telegrams;
|
||||
};
|
||||
|
||||
class TelegramProxyModel final : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QSortFilterProxyModel::QSortFilterProxyModel;
|
||||
|
||||
void setFilterByEquipmentIds(bool bFilterByEquipmentIds);
|
||||
void setAllowedEquipmentIds(const std::set<int> &allowedEquipmentIds);
|
||||
|
||||
void setFilteredCentralTelegramIds(const std::set<int> &filteredCentralTelegramIds);
|
||||
void setFilteredTetraTelegramIds(const std::set<int> &filteredTetraTelegramIds);
|
||||
void setFilteredWlsTelegramIds(const std::set<int> &filteredWlsTelegramIds);
|
||||
|
||||
void setFilterCentralTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction, bool bFilter);
|
||||
void setFilterTetraTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction, bool bFilter);
|
||||
void setFilterTetraPDU(N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type pduType, bool bFilter);
|
||||
void setFilterWlsTelegrams(N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol direction, bool bFilter);
|
||||
|
||||
void setFilterTetraLogin(bool bFilter);
|
||||
void setFilterTetraFragmented(bool bFilter);
|
||||
|
||||
QSharedPointer<LogViewTelegram> telegram(int row) const;
|
||||
protected:
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
protected:
|
||||
std::set<int> m_allowedEquipmentIds;
|
||||
std::set<int> m_filteredCentralTelegramIds;
|
||||
std::set<int> m_filteredTetraTelegramIds;
|
||||
std::set<int> m_filteredWlsTelegramIds;
|
||||
bool m_bFilterByEquipmentIds = false;
|
||||
bool m_bFilterLoginTelegrams = false;
|
||||
bool m_bFilterFragmentedTelegrams = false;
|
||||
std::set<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol> m_filterCentralTelegrams;
|
||||
std::set<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol> m_filterTetraTelegrams;
|
||||
std::set<N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol> m_filterWlsTelegrams;
|
||||
std::set<N_CoPrtCnv::CoPrtCnvRadioTelegram::E_PDU_Type> m_filterTetraPDU;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewOptionDialog.hpp"
|
||||
#include <QCoreApplication>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QFileDialog>
|
||||
#include <QIntValidator>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
const QString LogViewOptionDialog::SPEC_FILES = tr("Spezifikations-Dateien (*.x)");
|
||||
const QString LogViewOptionDialog::KRLOG_FILES = tr("Log-Dateien (*.krlog)");
|
||||
const QLatin1String LogViewOptionDialog::SPEC_FILES_GROUP("SpecFiles");
|
||||
const QLatin1String LogViewOptionDialog::DIR("Dir");
|
||||
const QLatin1String LogViewOptionDialog::P0_FILENAME("Central2PrtCnv");
|
||||
const QLatin1String LogViewOptionDialog::P5_FILENAME("PrtCnv2TETRA");
|
||||
const QLatin1String LogViewOptionDialog::SERVER_GROUP("ServerPorts");
|
||||
const QLatin1String LogViewOptionDialog::CENTRAL_PORT("Central");
|
||||
const QLatin1String LogViewOptionDialog::TETRA_PORT("Tetra");
|
||||
const QLatin1String LogViewOptionDialog::LOG_FILENAME("LogFilename");
|
||||
const QLatin1String LogViewOptionDialog::INJECTION_GROUP("InjectionServer");
|
||||
const QLatin1String LogViewOptionDialog::INJECTION_HOSTNAME("InjectionHostname");
|
||||
const QLatin1String LogViewOptionDialog::INJECTION_PORT("InjectionPort");
|
||||
|
||||
|
||||
|
||||
LogViewOptionDialog::LogViewOptionDialog(QWidget* a_parent)
|
||||
: QDialog(a_parent)
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
|
||||
|
||||
m_Settings.beginGroup(LogViewOptionDialog::SPEC_FILES_GROUP);
|
||||
QGroupBox* groupBox = new QGroupBox(tr("Telegramm-Spezifikations-Dateien"), this);
|
||||
layout->addWidget(groupBox);
|
||||
|
||||
QGridLayout* groupLayout = new QGridLayout();
|
||||
|
||||
QLabel* p0Label = new QLabel(tr("&Zentrale - Protokollkonverter"), this);
|
||||
groupLayout->addWidget(p0Label, 0, 0, 1, 2);
|
||||
QString defString = QCoreApplication::applicationDirPath() + QLatin1String("/training_area_telegrams.h");
|
||||
m_P0Edit = new QLineEdit(m_Settings.value(P0_FILENAME, defString).toString(), this);
|
||||
m_P0Edit->setMinimumWidth(400);
|
||||
groupLayout->addWidget(m_P0Edit);
|
||||
QPushButton* p0Browse = new QPushButton(tr("Browse"), this);
|
||||
p0Label->setBuddy(p0Browse);
|
||||
connect(p0Browse, &QPushButton::clicked, this, &LogViewOptionDialog::browseP0File);
|
||||
groupLayout->addWidget(p0Browse, 1, 1);
|
||||
|
||||
QLabel* p5Label = new QLabel(tr("Protokollkonverter - &TETRA"), this);
|
||||
groupLayout->addWidget(p5Label, 2, 0, 1, 2);
|
||||
defString = QCoreApplication::applicationDirPath() + QLatin1String("/zsksxd_tetraForLogView.x");
|
||||
m_P5Edit = new QLineEdit(m_Settings.value(P5_FILENAME, defString).toString(), this);
|
||||
groupLayout->addWidget(m_P5Edit);
|
||||
QPushButton* p5Browse = new QPushButton(tr("Browse"), this);
|
||||
p5Label->setBuddy(p5Browse);
|
||||
connect(p5Browse, &QPushButton::clicked, this, &LogViewOptionDialog::browseP5File);
|
||||
groupLayout->addWidget(p5Browse, 3, 1);
|
||||
|
||||
groupBox->setLayout(groupLayout);
|
||||
m_Settings.endGroup();
|
||||
|
||||
|
||||
m_Settings.beginGroup(LogViewOptionDialog::INJECTION_GROUP);
|
||||
groupBox = new QGroupBox(tr("Telegram Injection Server"), this);
|
||||
layout->addWidget(groupBox);
|
||||
QGridLayout* injectLayout = new QGridLayout();
|
||||
|
||||
QLabel* injectPortLabel = new QLabel(tr("Port"), this);
|
||||
injectLayout->addWidget(injectPortLabel, 1, 0);
|
||||
m_InjectPortEdit = new QLineEdit(m_Settings.value(INJECTION_PORT).toString(), this);
|
||||
QIntValidator* validator = new QIntValidator(1024, 65535, this);
|
||||
m_InjectPortEdit->setValidator(validator);
|
||||
injectLayout->addWidget(m_InjectPortEdit, 1, 1);
|
||||
|
||||
QLabel* injectHostnameLabel = new QLabel(tr("Hostname"), this);
|
||||
injectLayout->addWidget(injectHostnameLabel, 0, 0);
|
||||
m_InjectHostnameEdit = new QLineEdit(m_Settings.value(INJECTION_HOSTNAME).toString(), this);
|
||||
injectLayout->addWidget(m_InjectHostnameEdit, 0, 1);
|
||||
|
||||
groupBox->setLayout(injectLayout);
|
||||
m_Settings.endGroup();
|
||||
|
||||
|
||||
layout->addStretch();
|
||||
QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &LogViewOptionDialog::save);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &LogViewOptionDialog::reject);
|
||||
layout->addWidget(buttonBox);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewOptionDialog::browseP0File()
|
||||
{
|
||||
QString newFilename = QFileDialog::getOpenFileName(this,
|
||||
tr("Zentrale - Protokollkonverter Spezifikations-Datei"),
|
||||
m_Settings.value(DIR).toString(),
|
||||
tr("TrainingArea Telegram Headerdatei (training_area_telegrams.h)"));
|
||||
if (!newFilename.isEmpty())
|
||||
{
|
||||
m_P0Edit->setText(newFilename);
|
||||
QDir dir;
|
||||
m_Settings.beginGroup(LogViewOptionDialog::SPEC_FILES_GROUP);
|
||||
m_Settings.setValue(DIR, dir.filePath(newFilename));
|
||||
m_Settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewOptionDialog::browseP5File()
|
||||
{
|
||||
QString newFilename = QFileDialog::getOpenFileName(this, tr("Protokollkonverter - TETRA Spezifikations-Datei"), m_Settings.value(DIR).toString(), SPEC_FILES);
|
||||
if (!newFilename.isEmpty())
|
||||
{
|
||||
m_P5Edit->setText(newFilename);
|
||||
QDir dir;
|
||||
m_Settings.beginGroup(LogViewOptionDialog::SPEC_FILES_GROUP);
|
||||
m_Settings.setValue(DIR, dir.filePath(newFilename));
|
||||
m_Settings.endGroup();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LogViewOptionDialog::save()
|
||||
{
|
||||
uint32_t changedFlags = 0;
|
||||
|
||||
|
||||
|
||||
m_Settings.beginGroup(LogViewOptionDialog::SPEC_FILES_GROUP);
|
||||
QString string = m_Settings.value(P0_FILENAME).toString();
|
||||
if ((string != m_P0Edit->text()) ||
|
||||
(m_Settings.value(P5_FILENAME).toString() != m_P5Edit->text()))
|
||||
{
|
||||
m_Settings.setValue(P0_FILENAME, m_P0Edit->text());
|
||||
m_Settings.setValue(P5_FILENAME, m_P5Edit->text());
|
||||
changedFlags |= SpecFilesGroup;
|
||||
}
|
||||
m_Settings.endGroup();
|
||||
|
||||
|
||||
m_Settings.beginGroup(LogViewOptionDialog::INJECTION_GROUP);
|
||||
if ((m_Settings.value(INJECTION_HOSTNAME).toString() != m_InjectHostnameEdit->text()) ||
|
||||
(m_Settings.value(INJECTION_PORT).toString() != m_InjectPortEdit->text()))
|
||||
{
|
||||
m_Settings.setValue(INJECTION_HOSTNAME, m_InjectHostnameEdit->text());
|
||||
m_Settings.setValue(INJECTION_PORT, m_InjectPortEdit->text());
|
||||
changedFlags |= InjectionGroup;
|
||||
}
|
||||
m_Settings.endGroup();
|
||||
|
||||
emit settingsChanged(changedFlags);
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewOptionDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum SettingsChangedFlag {
|
||||
SpecFilesGroup = 0x01,
|
||||
ServerGroup = 0x02,
|
||||
InjectionGroup = 0x04
|
||||
};
|
||||
|
||||
static const QString KRLOG_FILES;
|
||||
static const QLatin1String SPEC_FILES_GROUP;
|
||||
static const QLatin1String P0_FILENAME;
|
||||
static const QLatin1String P5_FILENAME;
|
||||
static const QLatin1String SERVER_GROUP;
|
||||
static const QLatin1String CENTRAL_PORT;
|
||||
static const QLatin1String TETRA_PORT;
|
||||
static const QLatin1String SIZE;
|
||||
static const QLatin1String POS;
|
||||
static const QLatin1String CENTRAL_IS_SERVER;
|
||||
static const QLatin1String CENTRAL_HOSTNAME;
|
||||
static const QLatin1String LOG_FILENAME;
|
||||
static const QLatin1String INJECTION_GROUP;
|
||||
static const QLatin1String INJECTION_HOSTNAME;
|
||||
static const QLatin1String INJECTION_PORT;
|
||||
|
||||
|
||||
|
||||
|
||||
explicit LogViewOptionDialog(QWidget* a_parent);
|
||||
|
||||
signals:
|
||||
void settingsChanged(uint32_t changed);
|
||||
|
||||
protected:
|
||||
|
||||
static const QString SPEC_FILES;
|
||||
static const QLatin1String DIR;
|
||||
bool m_IsServer;
|
||||
QLineEdit *m_P0Edit;
|
||||
QLineEdit *m_P5Edit;
|
||||
QSettings m_Settings;
|
||||
QLineEdit *m_InjectHostnameEdit;
|
||||
QLineEdit *m_InjectPortEdit;
|
||||
|
||||
protected slots:
|
||||
void browseP0File();
|
||||
void browseP5File();
|
||||
void save();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<RCC>
|
||||
<qresource prefix="/" >
|
||||
<file>image/P2C.png</file>
|
||||
<file>image/C2P.png</file>
|
||||
<file>image/P2W.png</file>
|
||||
<file>image/W2P.png</file>
|
||||
<file>image/P2T.png</file>
|
||||
<file>image/T2P.png</file>
|
||||
<file>image/Central.png</file>
|
||||
<file>image/Tetra.png</file>
|
||||
<file>image/TNE.png</file>
|
||||
<file>image/GreenLamp.png</file>
|
||||
<file>image/RedLamp.png</file>
|
||||
<file>image/YellowLamp.png</file>
|
||||
<file>image/ShowSend.png</file>
|
||||
<file>image/Wls.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewSpinBox.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewSpinBox::LogViewSpinBox(LogViewField* a_field, QWidget* a_parent, const int a_value)
|
||||
: QSpinBox(a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, false)
|
||||
{
|
||||
|
||||
uint16_t maxArraySize = a_field->maxArraySize();
|
||||
setRange(0, maxArraySize);
|
||||
|
||||
|
||||
setValue(a_value);
|
||||
|
||||
|
||||
setToolTip(tr("<nobr>Wertebereich: 0..%1</nobr>").arg(maxArraySize));
|
||||
|
||||
|
||||
connect(this, &LogViewSpinBox::editingFinished,
|
||||
this, &LogViewSpinBox::finishEditing);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewSpinBox::finishEditing()
|
||||
{
|
||||
emit valueEditingFinished(text().toInt());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewSpinBox::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
Q_UNUSED(a_telegram);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QSpinBox>
|
||||
#include "LogViewWidget.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewSpinBox : public QSpinBox, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
LogViewSpinBox(LogViewField* a_field, QWidget* a_parent, const int a_value);
|
||||
|
||||
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
|
||||
protected slots:
|
||||
void finishEditing();
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
void valueEditingFinished(int a_newValue);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewTabWidget.hpp"
|
||||
#include <QFrame>
|
||||
#include <QGridLayout>
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include "LogViewTelegramDialog.hpp"
|
||||
#include "LogViewSpinBox.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include "LogViewTetraTelegramsParser.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewTabWidget::LogViewTabWidget(LogViewField* a_field, LogViewTelegramDialog* a_parent, LogViewSpinBox* a_spinBox)
|
||||
: QTabWidget(a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, false)
|
||||
, m_TelegramDialog(a_parent)
|
||||
, m_SpinBox(a_spinBox)
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTabWidget::changeSize(const int a_newSize)
|
||||
{
|
||||
|
||||
for (int i = count(); i < a_newSize; i++)
|
||||
addTab(m_Field, true, i);
|
||||
|
||||
|
||||
while (count() > a_newSize)
|
||||
{
|
||||
QStringList path = m_Field->jsonPath();
|
||||
path += QStringLiteral("index: %1").arg(count() - 1);
|
||||
m_TelegramDialog->removeItemsFromEditInfoList(path);
|
||||
removeTab(count() - 1);
|
||||
}
|
||||
while (m_Field->childCount() > a_newSize)
|
||||
m_Field->removeLastChild();
|
||||
|
||||
|
||||
setVisible(a_newSize > 0);
|
||||
m_TelegramDialog->makePretty();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewTabWidget::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
if (a_telegram->isJsonTelegram())
|
||||
return true;
|
||||
|
||||
if (m_SpinBox)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
a_telegram->setUIntX(LogViewTelegram::SIZE_CENTRAL_DYN_ARRAY_SIZE, count());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTabWidget::addTab(LogViewField* a_field, const bool a_isEmpty, int arrayIdx)
|
||||
{
|
||||
if (arrayIdx < 0)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Invalid array index given: " << arrayIdx;
|
||||
return;
|
||||
}
|
||||
|
||||
QFrame *frame = new QFrame;
|
||||
QGridLayout *box = new QGridLayout(frame);
|
||||
QTabWidget::addTab(frame, QStringLiteral("%1 %2").arg(a_field->cleanName()).arg(count()+1));
|
||||
if (a_isEmpty)
|
||||
a_field->setHasContent(false);
|
||||
auto *childTree = a_field->child(arrayIdx);
|
||||
while (!childTree)
|
||||
{
|
||||
const auto *first = a_field->child(0);
|
||||
if (first)
|
||||
{
|
||||
LogViewField *fNew = first->clone(arrayIdx);
|
||||
a_field->addChild(fNew);
|
||||
childTree = a_field->child(arrayIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogViewTetraTelegramsParser *p = LogViewTelegram::jsonParser();
|
||||
const StructInformation si = p->structFromType(a_field->type());
|
||||
if (si.type != a_field->type())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not find type '" << a_field->type() << "' - can not add substructure";
|
||||
return;
|
||||
}
|
||||
LogViewField *tc = new LogViewField(a_field->name() + QStringLiteral("TabChild"), LogViewField::e_FieldKindTabChild, a_field->xdrElement());
|
||||
tc->setJsonPath(a_field->jsonPath());
|
||||
a_field->addChild(tc);
|
||||
const QString path(QStringLiteral("index: %1"));
|
||||
LogViewTelegram::addFieldTreeStruct(QJsonObject(), tc, si, path.arg(arrayIdx), m_logger);
|
||||
childTree = a_field->child(arrayIdx);
|
||||
}
|
||||
}
|
||||
m_TelegramDialog->showTree(childTree, box);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (m_SpinBox)
|
||||
{
|
||||
int spinValue = m_SpinBox->value();
|
||||
if (spinValue < count())
|
||||
m_SpinBox->setValue(count());
|
||||
}
|
||||
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QTabWidget>
|
||||
#include "LogViewWidget.hpp"
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewTelegramDialog;
|
||||
class LogViewSpinBox;
|
||||
|
||||
|
||||
|
||||
class LogViewTabWidget : public QTabWidget, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
LogViewTabWidget(LogViewField* a_field, LogViewTelegramDialog* a_parent, LogViewSpinBox* a_spinBox);
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
void addTab(LogViewField* a_field, const bool a_isEmpty, int arrayIdx);
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
void changeSize(const int a_newSize);
|
||||
|
||||
protected:
|
||||
|
||||
LogViewTelegramDialog* m_TelegramDialog;
|
||||
LogViewSpinBox* m_SpinBox;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewTableWidget.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include <QHeaderView>
|
||||
#include <QJsonArray>
|
||||
#include "LogViewXdrStandardType.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include "LogViewEnumEdit.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewTableWidget::LogViewTableWidget(LogViewField* a_field, QWidget* a_parent, const bool a_readonly)
|
||||
: QTableWidget(0, 2, a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, a_readonly)
|
||||
, m_IsFloat(false)
|
||||
, m_IsEnum(false)
|
||||
{
|
||||
switch (m_Field->xdrElement()->getKind())
|
||||
{
|
||||
case LogViewXdrElement::e_KindEnum:
|
||||
m_IsEnum = true;
|
||||
break;
|
||||
default:
|
||||
m_IsFloat = LogViewXdrStandardType::e_Float == static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement())->getValueKind();
|
||||
}
|
||||
if (!m_IsFloat)
|
||||
setColumnCount(3);
|
||||
if (m_IsEnum)
|
||||
setColumnCount(1);
|
||||
|
||||
setHorizontalHeaderItem(0, new QTableWidgetItem(m_IsEnum ? tr("Enum") : tr("Dez")));
|
||||
if (!m_IsEnum)
|
||||
{
|
||||
setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Hex")));
|
||||
if (!m_IsFloat)
|
||||
{
|
||||
setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Bin")));
|
||||
}
|
||||
}
|
||||
setAlternatingRowColors(true);
|
||||
|
||||
|
||||
|
||||
|
||||
updateToolTip();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int nbrOfRows = a_field->valueListSize();
|
||||
setRowCount(nbrOfRows);
|
||||
for (int i = 0; i < nbrOfRows; i++)
|
||||
changeRow(i, a_field->value(i));
|
||||
|
||||
makePretty();
|
||||
|
||||
|
||||
connect(this, &LogViewTableWidget::itemChanged,
|
||||
this, &LogViewTableWidget::checkAndOvertakeContent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTableWidget::changeSize(const int a_newSize)
|
||||
{
|
||||
setRowCount(a_newSize);
|
||||
|
||||
disconnect(this, &LogViewTableWidget::itemChanged,
|
||||
this, &LogViewTableWidget::checkAndOvertakeContent);
|
||||
|
||||
for (int i = 0; i < a_newSize; i++)
|
||||
changeRow(i, QLatin1String("0"));
|
||||
|
||||
connect(this, &LogViewTableWidget::itemChanged,
|
||||
this, &LogViewTableWidget::checkAndOvertakeContent);
|
||||
|
||||
makePretty();
|
||||
|
||||
m_Valid = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTableWidget::changeRow(const int a_rowIndex, const QString& a_value)
|
||||
{
|
||||
|
||||
|
||||
if (m_IsEnum)
|
||||
{
|
||||
|
||||
QWidget* enumItem = cellWidget(a_rowIndex, 0);
|
||||
if (!enumItem)
|
||||
setCellWidget(a_rowIndex, 0, new LogViewEnumEdit(m_Field, this, m_Readonly, a_rowIndex));
|
||||
}
|
||||
else
|
||||
{
|
||||
QFont font;
|
||||
font.setStyleHint(QFont::TypeWriter);
|
||||
font.setFamily(QString());
|
||||
|
||||
QTableWidgetItem* decItem = item(a_rowIndex, 0);
|
||||
if (!decItem)
|
||||
{
|
||||
decItem = new QTableWidgetItem();
|
||||
|
||||
decItem->setText(a_value);
|
||||
decItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
if (!m_Readonly)
|
||||
{
|
||||
decItem->setFlags(decItem->flags() | Qt::ItemIsEditable);
|
||||
}
|
||||
decItem->setFont(font);
|
||||
decItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
setItem(a_rowIndex, 0, decItem);
|
||||
}
|
||||
|
||||
|
||||
QTableWidgetItem* hexItem = item(a_rowIndex, 1);
|
||||
if (!hexItem)
|
||||
{
|
||||
hexItem = new QTableWidgetItem();
|
||||
hexItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
hexItem->setFont(font);
|
||||
hexItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
setItem(a_rowIndex, 1, hexItem);
|
||||
}
|
||||
|
||||
|
||||
if (!m_IsFloat)
|
||||
{
|
||||
QTableWidgetItem* binItem = item(a_rowIndex, 2);
|
||||
if (!binItem)
|
||||
{
|
||||
binItem = new QTableWidgetItem();
|
||||
binItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
binItem->setFont(font);
|
||||
binItem->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
|
||||
setItem(a_rowIndex, 2, binItem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
checkAndOvertakeContent(decItem);
|
||||
makePretty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTableWidget::checkAndOvertakeContent(QTableWidgetItem* a_changedItem)
|
||||
{
|
||||
if (a_changedItem->column() != 0) return;
|
||||
|
||||
int row = a_changedItem->row();
|
||||
QString text = a_changedItem->text();
|
||||
|
||||
|
||||
bool ok;
|
||||
int64_t intValue = 0;
|
||||
double floatValue = 0.0;
|
||||
|
||||
|
||||
if (m_IsFloat)
|
||||
floatValue = getFloat(text, (uint64_t&)intValue, ok, true);
|
||||
else
|
||||
intValue = getInteger(text, ok);
|
||||
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
setFocus();
|
||||
|
||||
setCurrentCell(row, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QTableWidgetItem* decField = item(row, 0);
|
||||
if (decField) decField->setText(QString::number(m_IsFloat ? floatValue : intValue));
|
||||
|
||||
|
||||
QTableWidgetItem* hexField = item(row, 1);
|
||||
if (hexField) hexField->setText(toHex(intValue));
|
||||
|
||||
|
||||
if (!m_IsFloat)
|
||||
{
|
||||
QTableWidgetItem* binField = item(row, 2);
|
||||
if (binField) binField->setText(toBin(intValue));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTableWidget::makePretty()
|
||||
{
|
||||
|
||||
resizeColumnsToContents();
|
||||
resizeRowsToContents();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewTableWidget::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
if (a_telegram->isJsonTelegram())
|
||||
{
|
||||
if (m_Field->kind() == LogViewField::e_FieldKindPodArray)
|
||||
{
|
||||
QJsonArray arr;
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
arr += item(i, 0)->text().toInt();
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), arr);
|
||||
}
|
||||
else
|
||||
{
|
||||
QString value;
|
||||
value.reserve(rowCount() * 2);
|
||||
for (int i = 0; i < rowCount(); ++i)
|
||||
{
|
||||
int val = item(i, 0)->text().toInt();
|
||||
value += QStringLiteral("%1").arg(val, 2, 16, QLatin1Char('0'));
|
||||
}
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t arraySize;
|
||||
if (m_Field->isDynamicArray())
|
||||
{
|
||||
arraySize = rowCount();
|
||||
a_telegram->setUIntX(LogViewTelegram::SIZE_CENTRAL_DYN_ARRAY_SIZE, arraySize);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
arraySize = m_Field->maxArraySize();
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "arraySize=" << arraySize;
|
||||
for (int i = 0; i < arraySize; i++)
|
||||
{
|
||||
if (m_IsEnum)
|
||||
{
|
||||
LogViewEnumEdit *enumEdit = dynamic_cast<LogViewEnumEdit*>(cellWidget(i,0));
|
||||
enumEdit->saveContent(a_telegram);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t size = getSize();
|
||||
QString text = item(i, 0)->text();
|
||||
if (!m_IsFloat)
|
||||
{
|
||||
a_telegram->setUIntX(size, text.toULong());
|
||||
}
|
||||
else
|
||||
{
|
||||
const LogViewXdrStandardType *stdType = static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement());
|
||||
LogViewXdrStandardType::E_ByteOrder byteOrder = stdType->getByteOrder();
|
||||
uint64_t hex;
|
||||
getFloat(text, hex, m_Valid);
|
||||
a_telegram->setUIntX(size, hex, byteOrder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QTableWidget>
|
||||
#include "LogViewWidget.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewTableWidget : public QTableWidget, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LogViewTableWidget(LogViewField* a_field, QWidget* a_parent, const bool a_readonly);
|
||||
|
||||
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
|
||||
public slots:
|
||||
void changeSize(const int a_newSize);
|
||||
|
||||
protected:
|
||||
void changeRow(const int a_rowIndex, const QString& a_value);
|
||||
void makePretty();
|
||||
protected slots:
|
||||
void checkAndOvertakeContent(QTableWidgetItem* a_changedItem);
|
||||
|
||||
private:
|
||||
bool m_IsFloat;
|
||||
bool m_IsEnum;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewXdrStandardType.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include <CoPrtCnv/CoPrtCnvLogHeader.hpp>
|
||||
#include <QIcon>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace N_CoPrtCnv
|
||||
{
|
||||
class CoPrtCnvRadioTelegram;
|
||||
}
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
struct StructInformation;
|
||||
struct MemberInformation;
|
||||
class LogViewTetraTelegramsParser;
|
||||
class LogViewXdrParser;
|
||||
class LogViewXdrType;
|
||||
|
||||
|
||||
class LogViewTelegram final
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
enum E_Validity
|
||||
{
|
||||
e_NotYetEvaluated,
|
||||
e_Valid,
|
||||
e_Invalid
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_Column
|
||||
{
|
||||
e_ColName,
|
||||
e_ColGpsTime,
|
||||
e_ColLogTime,
|
||||
e_ColJsonData,
|
||||
e_ColMax
|
||||
};
|
||||
|
||||
|
||||
~LogViewTelegram();
|
||||
|
||||
|
||||
|
||||
static const uint16_t SIZE_CENTRAL_DYN_ARRAY_SIZE;
|
||||
|
||||
|
||||
|
||||
|
||||
LogViewTelegram(const LogViewTelegram &o);
|
||||
|
||||
LogViewTelegram &operator=(const LogViewTelegram &o) = delete;
|
||||
|
||||
|
||||
LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol a_destination,
|
||||
int telegramId);
|
||||
|
||||
|
||||
|
||||
LogViewTelegram(const N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol a_destination,
|
||||
const quint64 a_unixTime,
|
||||
const QByteArray &a_telegramData);
|
||||
|
||||
|
||||
|
||||
void setUIntX(const uint8_t a_size,
|
||||
quint64 a_value,
|
||||
const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian);
|
||||
|
||||
|
||||
|
||||
bool setData(const uint16_t a_offset, const uint8_t a_data);
|
||||
|
||||
|
||||
|
||||
quint64 getLogTime() const { return m_LogTime; }
|
||||
quint64 getLogTimeMsec() const;
|
||||
|
||||
|
||||
|
||||
QString getLogTimeText() const;
|
||||
|
||||
|
||||
QString getDestinationText() const;
|
||||
|
||||
|
||||
|
||||
quint64 getGpsTime() const { return m_GpsTime; }
|
||||
|
||||
|
||||
|
||||
QString getGpsTimeText() const;
|
||||
|
||||
|
||||
uint32_t getISSI() const { return m_ISSI; }
|
||||
|
||||
|
||||
int getParticipantId() const { return m_ParticipantId; }
|
||||
|
||||
|
||||
|
||||
int32_t getDelay() const;
|
||||
|
||||
|
||||
|
||||
QString getToolTipText(const E_Column a_col);
|
||||
|
||||
|
||||
void resetOffset();
|
||||
|
||||
|
||||
LogViewField* getFieldTree();
|
||||
|
||||
|
||||
void dump() const;
|
||||
|
||||
|
||||
QString getStructName() const;
|
||||
|
||||
|
||||
bool isValid();
|
||||
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol getDestination() const { return m_Destination; }
|
||||
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol getDirection() const;
|
||||
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol getProtocol() const { return m_Protocol; }
|
||||
|
||||
|
||||
int getTelId() const { return m_TelId; }
|
||||
|
||||
|
||||
QIcon getIcon() const;
|
||||
|
||||
bool isJsonTelegram() const { return N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral == m_Protocol; }
|
||||
void clearJsonData() { m_json.remove(QStringLiteral("data")); }
|
||||
void rebuildJsonString() { if (!m_json.isEmpty()) m_data.clear(); }
|
||||
void setJsonValue(const QStringList &path, const QJsonValue &val);
|
||||
QJsonObject jsonData() const { return m_json; }
|
||||
void updateJsonValue(const QStringList &path, const QJsonValue &newVal, QJsonObject &obj);
|
||||
void updateJsonValue(const QStringList &path, const QJsonValue &newVal, QJsonArray &arr);
|
||||
|
||||
|
||||
const N_CoPrtCnv::CoPrtCnvRadioTelegram* getTetraTelegram() const;
|
||||
|
||||
static LogViewTetraTelegramsParser *jsonParser();
|
||||
static LogViewXdrParser *tetraParser();
|
||||
|
||||
QByteArray getData(QJsonDocument::JsonFormat format = QJsonDocument::JsonFormat::Compact) const;
|
||||
|
||||
|
||||
|
||||
uint32_t getWaitTime() const { return m_WaitTime; }
|
||||
|
||||
|
||||
|
||||
void setWaitTime(uint32_t newVal) { m_WaitTime = newVal; }
|
||||
|
||||
|
||||
|
||||
QString getName() const { return m_Name; }
|
||||
|
||||
|
||||
|
||||
void setName(const QString &newVal) { m_Name = newVal; }
|
||||
|
||||
|
||||
void setNextFieldAsGpsTimeField();
|
||||
|
||||
QVector<uint16_t> getGpsTimeField() const { return m_GpsFieldOffset; }
|
||||
|
||||
void setGpsTimeField(const QVector<uint16_t> &gpsFieldOffset) { m_GpsFieldOffset = gpsFieldOffset; }
|
||||
|
||||
void actualizeGpsTime();
|
||||
|
||||
|
||||
|
||||
void createToolTipTextForColName();
|
||||
|
||||
|
||||
static double xdrToDouble(quint64 in);
|
||||
static float xdrToFloat(uint32_t in);
|
||||
static quint64 doubleToXdr(double in);
|
||||
static uint32_t floatToXdr(float in);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
QString m_Name;
|
||||
|
||||
|
||||
std::vector<QString> m_ToolTipText;
|
||||
|
||||
|
||||
uint32_t m_WaitTime;
|
||||
int m_ParticipantId;
|
||||
|
||||
|
||||
uint32_t m_ISSI;
|
||||
|
||||
|
||||
int m_AllocatedSize;
|
||||
static const LogViewXdrParser* m_Parser;
|
||||
uint16_t m_ActOffset;
|
||||
QVector<uint16_t> m_GpsFieldOffset;
|
||||
int m_TelId;
|
||||
|
||||
|
||||
uint32_t m_LastUnsignedValue;
|
||||
|
||||
|
||||
uint16_t m_MaxArraySize;
|
||||
static const uint16_t START_OFFSET_CENTRAL;
|
||||
static const uint16_t POS_CENTRAL_COUNTER;
|
||||
static const uint16_t POS_CENTRAL_TELID;
|
||||
static const uint16_t POS_CENTRAL_PARTICIPANTID;
|
||||
static const uint16_t START_OFFSET_TETRA_REGISTER;
|
||||
static const uint16_t START_OFFSET_TETRA_AIRLOAD;
|
||||
static const uint16_t START_OFFSET_TETRA_DATA;
|
||||
static const uint16_t START_OFFSET_TETRA_LOGIN;
|
||||
static const uint16_t START_OFFSET_TETRA_FRAGMENT;
|
||||
LogViewXdrStandardType::E_DynArraySizeMethod m_DynArraySizeMethod;
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol m_Destination;
|
||||
|
||||
E_Validity m_Validity;
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvLogHeader::E_CoPrtCnvProtocol m_Protocol;
|
||||
|
||||
quint64 m_LogTime;
|
||||
|
||||
mutable QString m_logTimeText;
|
||||
|
||||
quint64 m_GpsTime;
|
||||
|
||||
QByteArray m_data;
|
||||
QJsonObject m_json;
|
||||
|
||||
N_CoPrtCnv::CoPrtCnvRadioTelegram *m_TetraTelegram;
|
||||
|
||||
LogViewField *getFieldTree(const QString& a_type, const QString& a_name,
|
||||
uint16_t a_arraySize, const LogViewXdrType* a_parentElement = nullptr,
|
||||
const bool a_hasContent = true);
|
||||
LogViewField *getFieldTreeJson(const QJsonValue &data,
|
||||
const QString &name,
|
||||
const StructInformation &si,
|
||||
const QStringList &objectPathBase);
|
||||
|
||||
static void addFieldTreeStruct(const QJsonObject &parentObject,
|
||||
LogViewField *parent,
|
||||
const StructInformation &si,
|
||||
const QString &objectNameArrayHint,
|
||||
NGL::INGLLogger &logger);
|
||||
static void addFieldTreeJsonString(const QJsonValue &val,
|
||||
LogViewField *parent,
|
||||
const QString &name,
|
||||
bool isBinary,
|
||||
const QString &objectNameArrayHint,
|
||||
LogViewField::E_FieldKind fieldKind,
|
||||
NGL::INGLLogger &logger);
|
||||
static void addFieldTreeJsonPod(const QJsonValue &val,
|
||||
LogViewField *parent,
|
||||
const QString &name,
|
||||
const QString &type,
|
||||
const QString &objectNameArrayHint,
|
||||
LogViewField::E_FieldKind fieldKind,
|
||||
NGL::INGLLogger &logger);
|
||||
static void addFieldTreeJsonEnum(const QJsonValue &val,
|
||||
LogViewField *parent,
|
||||
const QString &name,
|
||||
const QString &type,
|
||||
const QString &objectNameArrayHint,
|
||||
LogViewField::E_FieldKind fieldKind,
|
||||
NGL::INGLLogger &logger);
|
||||
|
||||
static QString typeFromStructInformation(const StructInformation &si, const QString &name);
|
||||
static MemberInformation memberFromStructInformation(const StructInformation &si, const QString &name);
|
||||
|
||||
|
||||
|
||||
uint16_t getUInt16(const uint16_t a_offset) const;
|
||||
|
||||
|
||||
|
||||
uint32_t getUInt32(const uint16_t a_offset) const;
|
||||
|
||||
|
||||
|
||||
int32_t getInt32(const uint16_t a_offset) const;
|
||||
|
||||
|
||||
|
||||
quint64 getUIntX(const uint16_t a_offset, const uint8_t a_size, const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian) const;
|
||||
|
||||
|
||||
|
||||
int32_t getSIntX(const uint16_t a_offset, const uint8_t a_size, const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian) const;
|
||||
|
||||
|
||||
|
||||
char getChar(const uint16_t a_offset, const uint8_t a_size) const;
|
||||
|
||||
|
||||
|
||||
LogViewField* getContent(const LogViewXdrStandardType* a_standardType, uint16_t& a_offset, const uint16_t a_arraySize);
|
||||
|
||||
|
||||
|
||||
bool isScalar(const LogViewXdrType* a_xdrType) const;
|
||||
|
||||
|
||||
|
||||
void showMessageBox(const QString& a_errorText, const QString& a_title = QObject::tr("Invalid telegram")) const;
|
||||
|
||||
|
||||
|
||||
uint16_t getDynArraySize(uint16_t& a_offset) const;
|
||||
|
||||
|
||||
|
||||
static QString formatToolTipLine(const QString& a_name, const uint32_t a_value)
|
||||
{
|
||||
return formatToolTipLine(a_name, QString::number(a_value), a_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static QString formatToolTipLine(const QString& a_name, const QString& a_text, const uint32_t a_value);
|
||||
|
||||
static QString formatToolTipLine(const QString& a_name, const std::string& a_text, const uint32_t a_value)
|
||||
{
|
||||
return formatToolTipLine(a_name, QString::fromStdString(a_text), a_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t getData(const uint16_t a_offset) const;
|
||||
|
||||
private:
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
friend class LogViewTabWidget;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,497 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewTelegramDialog.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QSettings>
|
||||
#include <QScrollArea>
|
||||
#include <QTextEdit>
|
||||
#include <QVBoxLayout>
|
||||
#include "LogViewXdrElement.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include "IntegerCalculator.hpp"
|
||||
#include "LogViewBooleanEdit.hpp"
|
||||
#include "LogViewTextEdit.hpp"
|
||||
#include "LogViewValueEdit.hpp"
|
||||
#include "LogViewEnumEdit.hpp"
|
||||
#include "LogViewDateTimeEdit.hpp"
|
||||
#include "LogViewSpinBox.hpp"
|
||||
#include "LogViewTableWidget.hpp"
|
||||
#include "LogViewTabWidget.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LogViewTelegramDialog::LogViewTelegramDialog(QWidget *a_parent, const bool a_readonly)
|
||||
: QDialog(a_parent)
|
||||
, m_ReadOnly(a_readonly)
|
||||
, m_logger(getLogger("LogViewTelegramDialog"))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
}
|
||||
|
||||
|
||||
void LogViewTelegramDialog::showDialog(const QSharedPointer<LogViewTelegram> &a_telegram)
|
||||
{
|
||||
delete layout();
|
||||
hide();
|
||||
|
||||
m_Telegram = a_telegram;
|
||||
a_telegram->dump();
|
||||
|
||||
m_fieldTree.reset(a_telegram->getFieldTree());
|
||||
|
||||
if (m_fieldTree)
|
||||
{
|
||||
QGridLayout *dialogLayout = new QGridLayout;
|
||||
if (!m_ReadOnly)
|
||||
{
|
||||
|
||||
QLabel *waitTimeLabel = new QLabel(tr("Wartezeit [ms]"), this);
|
||||
dialogLayout->addWidget(waitTimeLabel, dialogLayout->rowCount(), 0);
|
||||
m_WaitTimeEdit = new QLineEdit(QString::number(a_telegram->getWaitTime()), this);
|
||||
dialogLayout->addWidget(m_WaitTimeEdit, dialogLayout->rowCount() - 1, 1);
|
||||
|
||||
|
||||
QLabel *nameLabel = new QLabel(tr("Name"), this);
|
||||
dialogLayout->addWidget(nameLabel, dialogLayout->rowCount(), 0);
|
||||
m_NameEdit = new QLineEdit(a_telegram->getName(), this);
|
||||
dialogLayout->addWidget(m_NameEdit, dialogLayout->rowCount() - 1, 1);
|
||||
|
||||
QFrame *f = new QFrame(this);
|
||||
f->setFrameShape(QFrame::HLine);
|
||||
f->setFrameShadow(QFrame::Sunken);
|
||||
dialogLayout->addWidget(f, dialogLayout->rowCount(), 0, 1, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
showTree(m_fieldTree.data(), dialogLayout);
|
||||
if (this->findChild<LogViewTableWidget *>() == nullptr)
|
||||
dialogLayout->setRowStretch(dialogLayout->rowCount(), 1);
|
||||
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
|
||||
|
||||
m_contentsWidget = new QWidget;
|
||||
m_contentsWidget->setLayout(dialogLayout);
|
||||
|
||||
m_ScrollArea = new QScrollArea(this);
|
||||
m_ScrollArea->setWidget(m_contentsWidget);
|
||||
m_ScrollArea->setWidgetResizable(true);
|
||||
|
||||
mainLayout->addWidget(m_ScrollArea);
|
||||
|
||||
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout;
|
||||
btnLayout->addStretch();
|
||||
showButtons(btnLayout);
|
||||
|
||||
mainLayout->addLayout(btnLayout);
|
||||
|
||||
setWindowTitle(m_fieldTree->cleanName() + QStringLiteral(" (%1)").arg(a_telegram->getTelId()));
|
||||
|
||||
setModal(true);
|
||||
show();
|
||||
|
||||
makePretty();
|
||||
}
|
||||
else
|
||||
showDataDump(a_telegram, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::showDataDump(const QSharedPointer<LogViewTelegram> &a_telegram, bool showErrorMessage)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->addWidget(new QLabel(tr("Telegramm-Dump")));
|
||||
|
||||
if (showErrorMessage)
|
||||
|
||||
layout->addWidget(new QLabel(tr("Konnte Dialog basierend auf Struktur \'%1\' nicht generieren!").arg(a_telegram->getStructName())));
|
||||
else
|
||||
layout->addWidget(new QLabel(tr("HexData from \'%1\' - telegram:").arg(a_telegram->getName())));
|
||||
|
||||
|
||||
QString theDump = QLatin1String("<code>");
|
||||
const QByteArray &data = a_telegram->getData();
|
||||
for (int i = 0; i < data.size(); i++)
|
||||
{
|
||||
if (0 == (i % 8))
|
||||
theDump += QStringLiteral("%1:").arg(i, 4, 16, QLatin1Char('0'));
|
||||
|
||||
theDump += QStringLiteral(" %1").arg(static_cast<unsigned char>(data[i]), 2, 16, QLatin1Char('0'));
|
||||
if (7 == (i % 8))
|
||||
theDump += QLatin1String("<br>");
|
||||
}
|
||||
theDump += QLatin1String("</code>");
|
||||
|
||||
QTextEdit *telegramDump = new QTextEdit(theDump);
|
||||
layout->addWidget(telegramDump);
|
||||
QPushButton *btnClose = new QPushButton(QIcon(QLatin1String(":icons/16x16/edit-delete.png")), tr("&Schliessen"));
|
||||
QHBoxLayout *btnLayout = new QHBoxLayout;
|
||||
btnLayout->addStretch();
|
||||
btnLayout->addWidget(btnClose);
|
||||
layout->addLayout(btnLayout);
|
||||
connect(btnClose, &QPushButton::clicked,
|
||||
this, &LogViewTelegramDialog::reject);
|
||||
setLayout(layout);
|
||||
show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::makePretty()
|
||||
{
|
||||
return;
|
||||
|
||||
int sbWidth = m_ScrollArea->width() - m_ScrollArea->viewport()->width();
|
||||
int wDiff = m_contentsWidget->width() - m_ScrollArea->width();
|
||||
int hDiff = m_contentsWidget->height() - m_ScrollArea->viewport()->height();
|
||||
const QRect screenSize = QApplication::desktop()->screenGeometry(this);
|
||||
|
||||
int newWidth = std::min(width() + wDiff + sbWidth, screenSize.width() * 9 / 10);
|
||||
int newHeight = std::min(height() + hDiff, screenSize.height() * 9 / 10);
|
||||
|
||||
|
||||
resize(QSize(newWidth, newHeight));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::showTree(LogViewField *a_fieldTree, QGridLayout *a_box)
|
||||
{
|
||||
int i = 0;
|
||||
while (LogViewField *child = a_fieldTree->child(i++))
|
||||
{
|
||||
if (!a_fieldTree->hasContent())
|
||||
child->setHasContent(false);
|
||||
switch (child->kind())
|
||||
{
|
||||
case LogViewField::e_FieldKindBorder:
|
||||
{
|
||||
QGroupBox *groupBox = new QGroupBox(child->cleanName());
|
||||
QGridLayout *actBox = new QGridLayout(groupBox);
|
||||
a_box->addWidget(groupBox, a_box->rowCount(), 0, 1, 2);
|
||||
showTree(child, actBox);
|
||||
break;
|
||||
}
|
||||
case LogViewField::e_FieldKindTab:
|
||||
showTab(child, a_box);
|
||||
break;
|
||||
case LogViewField::e_FieldKindTabChild:
|
||||
{
|
||||
QWidget *widget = new QWidget;
|
||||
widget->setContentsMargins(QMargins());
|
||||
QGridLayout *actBox = new QGridLayout(widget);
|
||||
a_box->addWidget(widget, a_box->rowCount(), 0, 1, 2);
|
||||
showTree(child, actBox);
|
||||
break;
|
||||
}
|
||||
case LogViewField::e_FieldKindEdit:
|
||||
case LogViewField::e_FieldKindPodArray:
|
||||
case LogViewField::e_FieldKindPodArrayChild:
|
||||
showEditField(child, a_box);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::fillTelegram(LogViewTelegram *a_telegram)
|
||||
{
|
||||
INFO_LOG(m_logger) << "******************************************";
|
||||
|
||||
|
||||
|
||||
for (const auto ptr : qAsConst(m_EditInfoList))
|
||||
{
|
||||
if (!ptr->isValid())
|
||||
{
|
||||
INFO_LOG(m_logger) << ptr->field()->name() << " is invalid";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
a_telegram->resetOffset();
|
||||
a_telegram->clearJsonData();
|
||||
for (auto ptr : qAsConst(m_EditInfoList))
|
||||
{
|
||||
if (!ptr->saveContent(a_telegram))
|
||||
{
|
||||
QMessageBox::warning(this, tr("Error while saving telegram"),
|
||||
tr("Found an invalid value - the telegram may be not saved correctly"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::saveTelegram()
|
||||
{
|
||||
fillTelegram(m_Telegram.data());
|
||||
|
||||
|
||||
N_SST::IntegerCalculator calculator;
|
||||
N_SST::IntegerCalculator::E_Error error;
|
||||
m_Telegram->setWaitTime(calculator.calc(m_WaitTimeEdit->text().toStdString(), error));
|
||||
m_Telegram->setName(m_NameEdit->text());
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
|
||||
void LogViewTelegramDialog::sendCurrentTelegram()
|
||||
{
|
||||
emit sendTelegram(m_Telegram);
|
||||
}
|
||||
|
||||
|
||||
void LogViewTelegramDialog::showButtons(QLayout *a_layout)
|
||||
{
|
||||
if (N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral == m_Telegram->getProtocol())
|
||||
{
|
||||
QPushButton *btnSend = new QPushButton(QIcon(QLatin1String(":icons/16x16/mail-send.png")), tr("&Send"));
|
||||
btnSend->setEnabled(true);
|
||||
connect(btnSend, &QPushButton::clicked, this, &LogViewTelegramDialog::sendCurrentTelegram);
|
||||
a_layout->addWidget(btnSend);
|
||||
}
|
||||
|
||||
if (m_ReadOnly)
|
||||
{
|
||||
QPushButton *btnClose = new QPushButton(QIcon(QLatin1String(":icons/16x16/edit-delete.png")), tr("&Schliessen"));
|
||||
connect(btnClose, &QPushButton::clicked, this, &LogViewTelegramDialog::reject);
|
||||
a_layout->addWidget(btnClose);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
QPushButton *btnClose = new QPushButton(QIcon(QLatin1String(":icons/16x16/edit-delete.png")), tr("&Abbrechen"));
|
||||
connect(btnClose, &QPushButton::clicked, this, &LogViewTelegramDialog::reject);
|
||||
a_layout->addWidget(btnClose);
|
||||
|
||||
QPushButton *btnOk = new QPushButton(QIcon(QLatin1String(":icons/16x16/dialog-ok-apply.png")), tr("&OK"));
|
||||
btnOk->setDefault(true);
|
||||
|
||||
connect(btnOk, &QPushButton::clicked, this, &LogViewTelegramDialog::saveTelegram);
|
||||
a_layout->addWidget(btnOk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::showEditField(LogViewField *a_logViewField, QGridLayout *a_box)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
switch (a_logViewField->valueListSize())
|
||||
{
|
||||
case 1:
|
||||
|
||||
if (m_ReadOnly || !a_logViewField->isDynamicArray() || (LogViewXdrStandardType::e_Character == static_cast<const LogViewXdrStandardType *>(a_logViewField->xdrElement())->getValueKind()))
|
||||
{
|
||||
QLabel *label = new QLabel(a_logViewField->cleanName());
|
||||
a_box->addWidget(label, a_box->rowCount(), 0);
|
||||
LogViewWidget *valueWidget = nullptr;
|
||||
|
||||
|
||||
{
|
||||
|
||||
|
||||
if (LogViewXdrElement::e_KindEnum == a_logViewField->xdrElement()->getKind())
|
||||
{
|
||||
|
||||
|
||||
valueWidget = new LogViewEnumEdit(a_logViewField, this, m_ReadOnly, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a_logViewField->isDateTimeField() || a_logViewField->isMSecsField())
|
||||
{
|
||||
|
||||
|
||||
valueWidget = new LogViewDateTimeEdit(a_logViewField, this, m_ReadOnly);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (static_cast<const LogViewXdrStandardType *>(a_logViewField->xdrElement())->getValueKind())
|
||||
{
|
||||
case LogViewXdrStandardType::e_Boolean:
|
||||
valueWidget = new LogViewBooleanEdit(a_logViewField, this, m_ReadOnly);
|
||||
break;
|
||||
case LogViewXdrStandardType::e_Signed:
|
||||
case LogViewXdrStandardType::e_Unsigned:
|
||||
case LogViewXdrStandardType::e_Float:
|
||||
case LogViewXdrStandardType::e_Data:
|
||||
valueWidget = new LogViewValueEdit(a_logViewField, this, m_ReadOnly);
|
||||
break;
|
||||
case LogViewXdrStandardType::e_Character:
|
||||
valueWidget = new LogViewTextEdit(a_logViewField, this, m_ReadOnly);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (valueWidget)
|
||||
m_EditInfoList.push_back(valueWidget);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QWidget *w = dynamic_cast<QWidget *>(valueWidget);
|
||||
if (w)
|
||||
a_box->addWidget(w, a_box->rowCount() - 1, 1);
|
||||
else
|
||||
WARNING_LOG(m_logger) << "Internal error - LogViewWidget is not derived from QWidget... !?";
|
||||
break;
|
||||
}
|
||||
|
||||
Q_FALLTHROUGH();
|
||||
case 0:
|
||||
if (m_ReadOnly)
|
||||
{
|
||||
|
||||
a_box->addWidget(new QLabel(tr("Keine %1").arg(a_logViewField->cleanName())));
|
||||
break;
|
||||
}
|
||||
|
||||
Q_FALLTHROUGH();
|
||||
default:
|
||||
{
|
||||
|
||||
QLabel *label = new QLabel(a_logViewField->cleanName());
|
||||
a_box->addWidget(label, a_box->rowCount(), 0);
|
||||
|
||||
|
||||
LogViewSpinBox *spinBox = nullptr;
|
||||
if (!m_ReadOnly && a_logViewField->isDynamicArray())
|
||||
{
|
||||
spinBox = new LogViewSpinBox(a_logViewField, this, a_logViewField->valueListSize());
|
||||
a_box->addWidget(spinBox, a_box->rowCount() - 1, 1);
|
||||
}
|
||||
|
||||
|
||||
LogViewTableWidget *tableWidget = new LogViewTableWidget(a_logViewField, this, m_ReadOnly);
|
||||
m_EditInfoList.push_back(tableWidget);
|
||||
a_box->addWidget(tableWidget, a_box->rowCount(), 0, 1, 2);
|
||||
|
||||
|
||||
if (spinBox)
|
||||
{
|
||||
connect(spinBox, &LogViewSpinBox::valueEditingFinished,
|
||||
tableWidget, &LogViewTableWidget::changeSize);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramDialog::showTab(LogViewField *a_logViewField, QGridLayout *a_box)
|
||||
{
|
||||
LogViewSpinBox *spinBox = nullptr;
|
||||
if (!m_ReadOnly && a_logViewField->isDynamicArray())
|
||||
{
|
||||
|
||||
QLabel *label = new QLabel(a_logViewField->cleanName());
|
||||
a_box->addWidget(label, a_box->rowCount(), 0);
|
||||
spinBox = new LogViewSpinBox(a_logViewField, this, 0);
|
||||
a_box->addWidget(spinBox, a_box->rowCount() - 1, 1);
|
||||
}
|
||||
|
||||
LogViewTabWidget *a_tabWidget = new LogViewTabWidget(a_logViewField, this, spinBox);
|
||||
m_EditInfoList.push_back(dynamic_cast<LogViewWidget *>(a_tabWidget));
|
||||
a_box->addWidget(a_tabWidget, a_box->rowCount(), 0, 1, 2);
|
||||
|
||||
|
||||
if (spinBox)
|
||||
{
|
||||
connect(spinBox, &LogViewSpinBox::valueEditingFinished,
|
||||
a_tabWidget, &LogViewTabWidget::changeSize);
|
||||
}
|
||||
|
||||
|
||||
if (a_logViewField->hasContent())
|
||||
{
|
||||
for (int i = 0; i < a_logViewField->childCount(); ++i)
|
||||
a_tabWidget->addTab(a_logViewField, false, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LogViewTelegramDialog::removeItemsFromEditInfoList(const QStringList &jsonPath)
|
||||
{
|
||||
if (m_EditInfoList.empty())
|
||||
return false;
|
||||
for (int i = m_EditInfoList.size() - 1; i >= 0; --i)
|
||||
{
|
||||
LogViewWidget *lvw = m_EditInfoList.at(i);
|
||||
const QStringList jsonPathChild = lvw->field()->jsonPath();
|
||||
if (jsonPathChild.size() < jsonPath.size())
|
||||
continue;
|
||||
bool bIsChild = true;
|
||||
for (int j = 0; j < jsonPath.size(); ++j)
|
||||
{
|
||||
if (jsonPath.at(j) != jsonPathChild.at(j))
|
||||
{
|
||||
bIsChild = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bIsChild)
|
||||
continue;
|
||||
delete m_EditInfoList.at(i);
|
||||
m_EditInfoList.removeAt(i);
|
||||
}
|
||||
m_EditInfoList.resize(m_EditInfoList.size() - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include "logger.h"
|
||||
|
||||
class QGridLayout;
|
||||
class QTabWidget;
|
||||
class QFrame;
|
||||
class QScrollArea;
|
||||
class QLineEdit;
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewWidget;
|
||||
class LogViewTelegram;
|
||||
class LogViewField;
|
||||
|
||||
|
||||
|
||||
class LogViewTelegramDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LogViewTelegramDialog(QWidget *a_parent = nullptr, const bool a_readonly = true);
|
||||
|
||||
void showDialog(const QSharedPointer<LogViewTelegram> &a_telegram);
|
||||
void showDataDump(const QSharedPointer<LogViewTelegram> &a_telegram, bool showErrorMessage);
|
||||
void makePretty();
|
||||
void showTree(LogViewField *a_fieldTree, QGridLayout *a_box);
|
||||
|
||||
|
||||
|
||||
bool removeItemsFromEditInfoList(const QStringList &jsonPath);
|
||||
|
||||
Q_SIGNALS:
|
||||
void sendTelegram(const QSharedPointer<LogViewTelegram> &telegramToSend);
|
||||
protected slots:
|
||||
void saveTelegram();
|
||||
|
||||
void sendCurrentTelegram();
|
||||
|
||||
protected:
|
||||
|
||||
void fillTelegram(LogViewTelegram *a_telegram);
|
||||
void showButtons(QLayout *a_layout);
|
||||
void showEditField(LogViewField *a_logViewField, QGridLayout *a_box);
|
||||
void showTab(LogViewField *a_logViewField, QGridLayout *a_box);
|
||||
|
||||
private:
|
||||
QSharedPointer<LogViewTelegram> m_Telegram;
|
||||
QVector<LogViewWidget *> m_EditInfoList;
|
||||
QScopedPointer<LogViewField> m_fieldTree;
|
||||
QWidget *m_contentsWidget = nullptr;
|
||||
QScrollArea *m_ScrollArea = nullptr;
|
||||
QLineEdit *m_NameEdit = nullptr;
|
||||
QLineEdit *m_WaitTimeEdit = nullptr;
|
||||
bool m_ReadOnly = false;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,586 @@
|
||||
|
||||
|
||||
|
||||
#include "LogViewTelegramEdit.hpp"
|
||||
|
||||
#include "LogViewInjectionThread.hpp"
|
||||
#include "LogViewTelegramDialog.hpp"
|
||||
#include "LogViewTelegramEditModel.hpp"
|
||||
#include "LogViewTelegramSelectionDialog.hpp"
|
||||
#include <CoPrtCnv/CoPrtCnvHexDumpHelper.hpp>
|
||||
|
||||
#include <QAction>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QHeaderView>
|
||||
#include <QIcon>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QModelIndex>
|
||||
#include <QSettings>
|
||||
#include <QTableView>
|
||||
#include <QTimer>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
QString TelegramEdit::s_DIR()
|
||||
{
|
||||
return QStringLiteral("Dir");
|
||||
}
|
||||
QString TelegramEdit::s_EDIT_TELEGRAM_GROUP()
|
||||
{
|
||||
return QStringLiteral("EditTelegrams");
|
||||
}
|
||||
QString TelegramEdit::s_TELEGRAMLIST_FILE_ID()
|
||||
{
|
||||
return QStringLiteral("RDETGL");
|
||||
}
|
||||
QString TelegramEdit::s_TELEGRAMLIST_FILES()
|
||||
{
|
||||
return tr("Telegrammliste-Dateien (*.tgl);;Alle Dateien (*)");
|
||||
}
|
||||
|
||||
TelegramEdit::TelegramEdit(QWidget *parent)
|
||||
: QObject(parent)
|
||||
, m_addTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-add.png")), tr("Add Telegram"), this))
|
||||
, m_editTeleAction(new QAction(QIcon(QLatin1String(":/image/Edit.png")), tr("Edit Telegram"), this))
|
||||
, m_copyTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-copy.png")), tr("Copy Telegram"), this))
|
||||
, m_pasteTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/edit-paste.png")), tr("Paste Telegram"), this))
|
||||
, m_deleteTeleAction(new QAction(QIcon(QLatin1String(":icons/16x16/list-remove.png")), tr("Delete Telegram"), this))
|
||||
, m_moveTeleUpAction(new QAction(QIcon(QLatin1String(":icons/16x16/go-up.png")), tr("Move up"), this))
|
||||
, m_moveTeleDownAction(new QAction(QIcon(QLatin1String(":icons/16x16/go-down.png")), tr("Move down"), this))
|
||||
, m_teleListLoad(new QAction(QIcon(QLatin1String(":icons/16x16/document-open-data.png")), tr("Load Telegram list"), this))
|
||||
, m_teleListAppend(new QAction(QIcon(), tr("Telegrammliste anhaengen"), this))
|
||||
, m_teleListSave(new QAction(QIcon(QLatin1String(":icons/16x16/document-save.png")), tr("Save Telegram list"), this))
|
||||
, m_tableView(new QTableView(parent))
|
||||
, m_DoLoop(false)
|
||||
, m_InjectionThread(nullptr)
|
||||
, m_EditModel(new TelegramEditModel(this))
|
||||
, m_logger(getLogger("LogViewTelegramEdit"))
|
||||
{
|
||||
m_addTeleAction->setShortcut(tr("Ctrl+A"));
|
||||
m_editTeleAction->setShortcut(tr("Ctrl+E"));
|
||||
m_copyTeleAction->setShortcut(tr("Ctrl+C"));
|
||||
m_pasteTeleAction->setShortcut(tr("Ctrl+V"));
|
||||
m_deleteTeleAction->setShortcut(Qt::Key_Delete);
|
||||
m_moveTeleUpAction->setShortcut(tr("Ctrl+U"));
|
||||
m_moveTeleDownAction->setShortcut(tr("Ctrl+D"));
|
||||
m_teleListLoad->setShortcut(tr("Ctrl+L"));
|
||||
m_teleListAppend->setShortcut(tr("Ctrl+K"));
|
||||
m_teleListSave->setShortcut(tr("Ctrl+S"));
|
||||
m_addTeleAction->setEnabled(true);
|
||||
m_copyTeleAction->setEnabled(false);
|
||||
m_pasteTeleAction->setEnabled(false);
|
||||
m_deleteTeleAction->setEnabled(false);
|
||||
m_moveTeleUpAction->setEnabled(false);
|
||||
m_moveTeleDownAction->setEnabled(false);
|
||||
m_teleListLoad->setEnabled(true);
|
||||
m_teleListAppend->setEnabled(true);
|
||||
m_teleListSave->setEnabled(false);
|
||||
|
||||
connect(m_addTeleAction, &QAction::triggered, this, &TelegramEdit::addTelegram);
|
||||
connect(m_editTeleAction, &QAction::triggered, this, &TelegramEdit::editTelegram);
|
||||
connect(m_copyTeleAction, &QAction::triggered, this, &TelegramEdit::copy);
|
||||
connect(m_pasteTeleAction, &QAction::triggered, this, &TelegramEdit::paste);
|
||||
connect(m_deleteTeleAction, &QAction::triggered, this, &TelegramEdit::deleteTelegram);
|
||||
connect(m_moveTeleUpAction, &QAction::triggered, this, &TelegramEdit::moveUp);
|
||||
connect(m_moveTeleDownAction, &QAction::triggered, this, &TelegramEdit::moveDown);
|
||||
connect(m_teleListLoad, &QAction::triggered, this, &TelegramEdit::loadTelegramListReplace);
|
||||
connect(m_teleListAppend, &QAction::triggered, this, &TelegramEdit::loadTelegramListAppend);
|
||||
connect(m_teleListSave, &QAction::triggered, this, &TelegramEdit::saveTelegramList);
|
||||
|
||||
m_tableView->setModel(m_EditModel);
|
||||
m_tableView->verticalHeader()->hide();
|
||||
m_tableView->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
m_tableView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
connect(m_tableView->selectionModel(), &QItemSelectionModel::selectionChanged,
|
||||
this, &TelegramEdit::onSelectionChanged);
|
||||
connect(m_tableView, &QTableView::doubleClicked,
|
||||
this, &TelegramEdit::editTelegram);
|
||||
connect(m_tableView, &QTableView::customContextMenuRequested,
|
||||
this, &TelegramEdit::tableViewCustomContextMenu);
|
||||
m_tableView->addAction(m_addTeleAction);
|
||||
m_tableView->addAction(m_editTeleAction);
|
||||
m_tableView->addAction(m_copyTeleAction);
|
||||
m_tableView->addAction(m_pasteTeleAction);
|
||||
m_tableView->addAction(m_deleteTeleAction);
|
||||
m_tableView->addAction(m_moveTeleUpAction);
|
||||
m_tableView->addAction(m_moveTeleDownAction);
|
||||
}
|
||||
|
||||
void TelegramEdit::setInjectionThread(LogViewInjectionThread *a_injectionThread)
|
||||
{
|
||||
m_InjectionThread = a_injectionThread;
|
||||
}
|
||||
|
||||
void TelegramEdit::appendTelegram(const QSharedPointer<LogViewTelegram> &telegram)
|
||||
{
|
||||
m_EditModel->appendTelegram(telegram);
|
||||
m_teleListSave->setEnabled(true);
|
||||
}
|
||||
|
||||
void TelegramEdit::tableViewCustomContextMenu(const QPoint &pos)
|
||||
{
|
||||
QMenu menu;
|
||||
|
||||
|
||||
|
||||
menu.addAction(m_addTeleAction);
|
||||
menu.addAction(m_editTeleAction);
|
||||
menu.addAction(m_copyTeleAction);
|
||||
menu.addAction(m_pasteTeleAction);
|
||||
menu.addAction(m_deleteTeleAction);
|
||||
|
||||
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addAction(m_moveTeleUpAction);
|
||||
menu.addAction(m_moveTeleDownAction);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
const bool itemSelected = m_tableView->currentIndex().isValid();
|
||||
|
||||
bool isCentral = false;
|
||||
QSharedPointer<LogViewTelegram> tele = m_EditModel->telegram(m_tableView->currentIndex().row());
|
||||
if (tele)
|
||||
isCentral = (tele->getProtocol() == N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral);
|
||||
|
||||
|
||||
|
||||
if (isInjectionPossible())
|
||||
{
|
||||
QAction *action = menu.addAction(QIcon(QLatin1String(":/image/InjectCentral.png")), tr("Injektiere Zentral-Telegramm"));
|
||||
|
||||
action->setEnabled(itemSelected && isCentral);
|
||||
connect(action, &QAction::triggered, this, &TelegramEdit::injectCentralTelegram);
|
||||
|
||||
action = menu.addAction(QIcon(QLatin1String(":/image/InjectTetra.png")), tr("Injektiere Tetra-Telegramm"));
|
||||
|
||||
action->setEnabled(itemSelected && isCentral);
|
||||
connect(action, &QAction::triggered, this, &TelegramEdit::injectTetraTelegram);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
|
||||
|
||||
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/mail-send.png")), tr("Sende Telegramm"));
|
||||
|
||||
action->setEnabled(itemSelected && isCentral);
|
||||
connect(action, &QAction::triggered, this, &TelegramEdit::sendCurrentTelegram);
|
||||
|
||||
if (m_DoLoop)
|
||||
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-playback-stop.png")), tr("Stop Loopen"));
|
||||
else
|
||||
{
|
||||
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-playback-start.png")), tr("Loop Telegramme"));
|
||||
action->setEnabled(itemSelected);
|
||||
}
|
||||
connect(action, &QAction::triggered, this, &TelegramEdit::loopTelegrams);
|
||||
|
||||
action = menu.addAction(QIcon(QLatin1String(":icons/16x16/media-play-normal.png")), tr("Sende Sequenz"));
|
||||
action->setEnabled(itemSelected);
|
||||
connect(action, &QAction::triggered, this, &TelegramEdit::sequenceTelegrams);
|
||||
|
||||
|
||||
|
||||
menu.addSeparator();
|
||||
}
|
||||
|
||||
menu.addAction(m_teleListLoad);
|
||||
menu.addAction(m_teleListAppend);
|
||||
menu.addAction(m_teleListSave);
|
||||
|
||||
menu.exec(m_tableView->viewport()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void TelegramEdit::addTelegram()
|
||||
{
|
||||
|
||||
LogViewTelegramSelectionDialog telegramSelectionDialog(m_tableView);
|
||||
if (QDialog::Accepted == telegramSelectionDialog.exec())
|
||||
{
|
||||
QSharedPointer<LogViewTelegram> newTelegram = QSharedPointer<LogViewTelegram>(new LogViewTelegram(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral,
|
||||
telegramSelectionDialog.getSelectedTelegramId()));
|
||||
m_curEditTelegramRow = m_EditModel->appendTelegram(newTelegram);
|
||||
|
||||
|
||||
LogViewTelegramDialog *editTelegramDialog = new LogViewTelegramDialog(m_tableView, false);
|
||||
connect(editTelegramDialog, &LogViewTelegramDialog::finished,
|
||||
this, &TelegramEdit::editTelegramDialogFinished);
|
||||
connect(editTelegramDialog, &LogViewTelegramDialog::sendTelegram,
|
||||
this, &TelegramEdit::sendTelegram);
|
||||
editTelegramDialog->showDialog(newTelegram);
|
||||
|
||||
m_teleListSave->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<LogViewTelegram> TelegramEdit::currentSelectedTelegram() const
|
||||
{
|
||||
return m_EditModel->telegram(currentSelectedIndex().row());
|
||||
}
|
||||
|
||||
QModelIndex TelegramEdit::currentSelectedIndex() const
|
||||
{
|
||||
return m_tableView->currentIndex();
|
||||
}
|
||||
|
||||
void TelegramEdit::editTelegramDialogFinished()
|
||||
{
|
||||
|
||||
m_EditModel->emitDataChanged(m_curEditTelegramRow);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TelegramEdit::editTelegram()
|
||||
{
|
||||
m_curEditTelegramRow = currentSelectedIndex().row();
|
||||
if (m_curEditTelegramRow < 0)
|
||||
return;
|
||||
LogViewTelegramDialog *editTelegramDialog = new LogViewTelegramDialog(m_tableView, false);
|
||||
connect(editTelegramDialog, &LogViewTelegramDialog::finished, this, &TelegramEdit::editTelegramDialogFinished);
|
||||
editTelegramDialog->showDialog(currentSelectedTelegram());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void TelegramEdit::showTelegram()
|
||||
{
|
||||
LogViewTelegramDialog *showTelegramDialog = new LogViewTelegramDialog(m_tableView, true);
|
||||
showTelegramDialog->showDialog(currentSelectedTelegram());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void TelegramEdit::deleteTelegram()
|
||||
{
|
||||
const QModelIndexList indexList = m_tableView->selectionModel()->selectedIndexes();
|
||||
QSet<int> rows;
|
||||
rows.reserve(indexList.size());
|
||||
for (const QModelIndex &index : indexList)
|
||||
rows += index.row();
|
||||
|
||||
m_EditModel->removeTelegrams(rows);
|
||||
m_teleListSave->setEnabled(m_EditModel->rowCount() > 0);
|
||||
}
|
||||
|
||||
void TelegramEdit::injectCentralTelegram()
|
||||
{
|
||||
injectTelegram(true);
|
||||
}
|
||||
|
||||
void TelegramEdit::injectTetraTelegram()
|
||||
{
|
||||
injectTelegram(false);
|
||||
}
|
||||
|
||||
void TelegramEdit::injectTelegram(bool a_bAsCentralTelegram)
|
||||
{
|
||||
injectTelegram(currentSelectedTelegram(), a_bAsCentralTelegram);
|
||||
}
|
||||
|
||||
void TelegramEdit::injectTelegram(const QSharedPointer<LogViewTelegram> &a_telegram, bool a_bAsCentralTelegram)
|
||||
{
|
||||
if (!isInjectionPossible())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Try to inject a telegramm but the injection thread is not running";
|
||||
return;
|
||||
}
|
||||
if (a_telegram.isNull())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Try to inject a telegramm but no telegramm selected";
|
||||
return;
|
||||
}
|
||||
a_telegram->actualizeGpsTime();
|
||||
m_InjectionThread->sendTelegram(a_telegram.data(), a_bAsCentralTelegram);
|
||||
}
|
||||
|
||||
void TelegramEdit::sendCurrentTelegram()
|
||||
{
|
||||
sendTelegram(currentSelectedTelegram());
|
||||
}
|
||||
|
||||
void TelegramEdit::sendTelegram(const QSharedPointer<LogViewTelegram> &a_telegram)
|
||||
{
|
||||
injectTelegram(a_telegram, true);
|
||||
}
|
||||
|
||||
void TelegramEdit::loopTelegrams()
|
||||
{
|
||||
|
||||
if (m_DoLoop)
|
||||
{
|
||||
m_DoLoop = false;
|
||||
m_deleteTeleAction->setEnabled(m_tableView->currentIndex().isValid());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_DoLoop = true;
|
||||
m_deleteTeleAction->setEnabled(false);
|
||||
m_currentRowToSend = currentSelectedIndex().row();
|
||||
if (m_currentRowToSend < 0)
|
||||
return;
|
||||
QSharedPointer<LogViewTelegram> tele = currentSelectedTelegram();
|
||||
sendTelegram(tele);
|
||||
QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::loopNextTelegram);
|
||||
}
|
||||
}
|
||||
|
||||
void TelegramEdit::loopNextTelegram()
|
||||
{
|
||||
if (!m_DoLoop)
|
||||
return;
|
||||
++m_currentRowToSend;
|
||||
|
||||
if (m_currentRowToSend >= m_tableView->model()->rowCount())
|
||||
m_currentRowToSend = 0;
|
||||
|
||||
QSharedPointer<LogViewTelegram> tele = telegramAtRow(m_currentRowToSend);
|
||||
if (!tele)
|
||||
return;
|
||||
|
||||
sendTelegram(tele);
|
||||
QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::loopNextTelegram);
|
||||
}
|
||||
|
||||
void TelegramEdit::sequenceTelegrams()
|
||||
{
|
||||
m_currentRowToSend = currentSelectedIndex().row();
|
||||
if (m_currentRowToSend < 0)
|
||||
return;
|
||||
QSharedPointer<LogViewTelegram> tele = currentSelectedTelegram();
|
||||
sendTelegram(tele);
|
||||
QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::sequenceNextTelegram);
|
||||
}
|
||||
|
||||
void TelegramEdit::sequenceNextTelegram()
|
||||
{
|
||||
++m_currentRowToSend;
|
||||
if (m_currentRowToSend >= m_tableView->model()->rowCount())
|
||||
return;
|
||||
|
||||
QSharedPointer<LogViewTelegram> tele = telegramAtRow(m_currentRowToSend);
|
||||
if (!tele)
|
||||
return;
|
||||
|
||||
sendTelegram(tele);
|
||||
QTimer::singleShot(tele->getWaitTime(), this, &TelegramEdit::sequenceNextTelegram);
|
||||
}
|
||||
|
||||
QSharedPointer<LogViewTelegram> TelegramEdit::telegramAtRow(int row)
|
||||
{
|
||||
return m_EditModel->telegram(row);
|
||||
}
|
||||
|
||||
void TelegramEdit::copy()
|
||||
{
|
||||
m_copyTelegram = currentSelectedTelegram();
|
||||
m_pasteTeleAction->setEnabled(m_copyTelegram != nullptr);
|
||||
if (!m_copyTelegram)
|
||||
return;
|
||||
m_copyTelegram = QSharedPointer<LogViewTelegram>(new LogViewTelegram(*m_copyTelegram.data()));
|
||||
}
|
||||
|
||||
void TelegramEdit::paste()
|
||||
{
|
||||
if (!m_copyTelegram)
|
||||
return;
|
||||
int row = currentSelectedIndex().row() + 1;
|
||||
m_EditModel->pasteRows(row, m_copyTelegram);
|
||||
}
|
||||
|
||||
void TelegramEdit::moveUp()
|
||||
{
|
||||
const QModelIndex idx = currentSelectedIndex();
|
||||
if (m_EditModel->moveUp(idx.row()))
|
||||
{
|
||||
m_tableView->clearSelection();
|
||||
m_tableView->setCurrentIndex(m_EditModel->index(idx.row() - 1, idx.column(), idx.parent()));
|
||||
m_moveTeleUpAction->setEnabled(idx.row() > 1);
|
||||
m_moveTeleDownAction->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TelegramEdit::moveDown()
|
||||
{
|
||||
const QModelIndex idx = currentSelectedIndex();
|
||||
if (m_EditModel->moveDown(idx.row()))
|
||||
{
|
||||
m_tableView->clearSelection();
|
||||
m_tableView->setCurrentIndex(m_EditModel->index(idx.row() + 1, idx.column(), idx.parent()));
|
||||
m_moveTeleUpAction->setEnabled(true);
|
||||
m_moveTeleDownAction->setEnabled(idx.row() < m_EditModel->rowCount() - 2);
|
||||
}
|
||||
}
|
||||
|
||||
void TelegramEdit::saveTelegramList()
|
||||
{
|
||||
|
||||
QSettings settings;
|
||||
QString newFilename = QFileDialog::getSaveFileName(m_tableView,
|
||||
tr("Dateiname der Telegrammliste"),
|
||||
settings.value(s_DIR()).toString(),
|
||||
s_TELEGRAMLIST_FILES());
|
||||
if (!newFilename.isEmpty())
|
||||
{
|
||||
if (!newFilename.contains(QLatin1Char('.')))
|
||||
newFilename += QLatin1String(".tgl");
|
||||
|
||||
|
||||
QDir dir;
|
||||
settings.beginGroup(s_EDIT_TELEGRAM_GROUP());
|
||||
settings.setValue(s_DIR(), dir.filePath(newFilename));
|
||||
settings.endGroup();
|
||||
|
||||
|
||||
QFile telegramFile(newFilename);
|
||||
telegramFile.open(QIODevice::WriteOnly);
|
||||
QDataStream stream(&telegramFile);
|
||||
|
||||
|
||||
uint32_t version = 1;
|
||||
stream << s_TELEGRAMLIST_FILE_ID() << version;
|
||||
|
||||
|
||||
int rows = m_tableView->model()->rowCount();
|
||||
stream << rows;
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
QSharedPointer<LogViewTelegram> telegram = telegramAtRow(i);
|
||||
if (!telegram)
|
||||
continue;
|
||||
|
||||
const QByteArray &data = telegram->getData();
|
||||
const QString name = telegram->getName();
|
||||
const unsigned int waitTime = telegram->getWaitTime();
|
||||
|
||||
stream << waitTime
|
||||
<< name
|
||||
<< telegram->getGpsTimeField()
|
||||
<< data.size();
|
||||
stream.writeRawData(data.data(), data.size());
|
||||
}
|
||||
telegramFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void TelegramEdit::loadTelegramListAppend()
|
||||
{
|
||||
loadTelegramList(true);
|
||||
}
|
||||
|
||||
void TelegramEdit::loadTelegramListReplace()
|
||||
{
|
||||
loadTelegramList(false);
|
||||
}
|
||||
|
||||
void TelegramEdit::loadTelegramList(bool checkAppend)
|
||||
{
|
||||
|
||||
QSettings settings;
|
||||
QString newFilename = QFileDialog::getOpenFileName(m_tableView,
|
||||
tr("Dateiname der Telegrammliste"),
|
||||
settings.value(s_DIR()).toString(),
|
||||
s_TELEGRAMLIST_FILES());
|
||||
if (!newFilename.isEmpty())
|
||||
{
|
||||
|
||||
QDir dir;
|
||||
settings.beginGroup(s_EDIT_TELEGRAM_GROUP());
|
||||
settings.setValue(s_DIR(), dir.filePath(newFilename));
|
||||
settings.endGroup();
|
||||
|
||||
|
||||
{
|
||||
if (!checkAppend)
|
||||
m_EditModel->clearTelegrams();
|
||||
}
|
||||
|
||||
|
||||
QFile telegramFile(newFilename);
|
||||
telegramFile.open(QIODevice::ReadOnly);
|
||||
QDataStream stream(&telegramFile);
|
||||
|
||||
|
||||
QString id;
|
||||
stream >> id;
|
||||
if (id != s_TELEGRAMLIST_FILE_ID())
|
||||
{
|
||||
QMessageBox::critical(m_tableView, tr("Error"), tr("<b>%1</b> does not contain telegram data").arg(newFilename));
|
||||
return;
|
||||
}
|
||||
uint32_t version = 0;
|
||||
stream >> version;
|
||||
if (version != 1)
|
||||
{
|
||||
QMessageBox::critical(m_tableView, tr("Error"), tr("Wrong telegram list file version"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int rows = 0;
|
||||
QVector<uint16_t> gpsFieldOffset;
|
||||
stream >> rows;
|
||||
for (int i = 0; i < rows; i++)
|
||||
{
|
||||
uint32_t waitTime = 0;
|
||||
QString name;
|
||||
int telegramSize = 0;
|
||||
stream >> waitTime >> name >> gpsFieldOffset >> telegramSize;
|
||||
if (telegramSize > 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "telegramSize=" << telegramSize;
|
||||
QByteArray buf(telegramSize, Qt::Uninitialized);
|
||||
stream.readRawData(buf.data(), telegramSize);
|
||||
NGL::NGLLoggerHelper::hexDumpHelper(m_logger, NGL::LogLevel::Debug, buf);
|
||||
LogViewTelegram *telegram = new LogViewTelegram(N_CoPrtCnv::CoPrtCnvLogHeader::e_DestProtocolCentral,
|
||||
0,
|
||||
buf);
|
||||
telegram->setWaitTime(waitTime);
|
||||
telegram->setName(name);
|
||||
telegram->setGpsTimeField(gpsFieldOffset);
|
||||
m_EditModel->appendTelegram(QSharedPointer<LogViewTelegram>(telegram));
|
||||
}
|
||||
}
|
||||
telegramFile.close();
|
||||
|
||||
m_teleListSave->setEnabled(m_EditModel->rowCount() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TelegramEdit::isInjectionPossible() const
|
||||
{
|
||||
return m_InjectionThread ? m_InjectionThread->isSendingPossible() : false;
|
||||
}
|
||||
|
||||
|
||||
void TelegramEdit::onSelectionChanged()
|
||||
{
|
||||
const QModelIndex idx = currentSelectedIndex();
|
||||
|
||||
m_editTeleAction->setEnabled(idx.isValid());
|
||||
m_copyTeleAction->setEnabled(idx.isValid());
|
||||
m_deleteTeleAction->setEnabled(idx.isValid());
|
||||
m_moveTeleUpAction->setEnabled(idx.row() > 0);
|
||||
m_moveTeleDownAction->setEnabled(idx.isValid() && idx.row() < m_EditModel->rowCount() - 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include <QModelIndex>
|
||||
|
||||
class QAction;
|
||||
class QTableView;
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewInjectionThread;
|
||||
class TelegramEditModel;
|
||||
|
||||
class TelegramEdit :public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TelegramEdit(QWidget *parent = nullptr);
|
||||
|
||||
QTableView *tableView() { return m_tableView; }
|
||||
|
||||
void appendTelegram(const QSharedPointer<LogViewTelegram> &telegram);
|
||||
|
||||
void setInjectionThread(LogViewInjectionThread* a_injectionThread);
|
||||
|
||||
bool isInjectionPossible() const;
|
||||
|
||||
protected:
|
||||
QSharedPointer<LogViewTelegram> m_copyTelegram;
|
||||
|
||||
QSharedPointer<LogViewTelegram> currentSelectedTelegram() const;
|
||||
|
||||
QModelIndex currentSelectedIndex() const;
|
||||
|
||||
QSharedPointer<LogViewTelegram> telegramAtRow(int row);
|
||||
|
||||
void loadTelegramList(bool checkAppend);
|
||||
|
||||
protected:
|
||||
QAction *m_addTeleAction;
|
||||
QAction *m_editTeleAction;
|
||||
QAction *m_copyTeleAction;
|
||||
QAction *m_pasteTeleAction;
|
||||
QAction *m_deleteTeleAction;
|
||||
QAction *m_moveTeleUpAction;
|
||||
QAction *m_moveTeleDownAction;
|
||||
QAction *m_teleListLoad;
|
||||
QAction *m_teleListAppend;
|
||||
QAction *m_teleListSave;
|
||||
QTableView *m_tableView;
|
||||
bool m_DoLoop;
|
||||
|
||||
LogViewInjectionThread *m_InjectionThread;
|
||||
|
||||
int m_currentRowToSend;
|
||||
|
||||
int m_curEditTelegramRow;
|
||||
|
||||
TelegramEditModel *m_EditModel;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
static QString s_DIR();
|
||||
static QString s_EDIT_TELEGRAM_GROUP();
|
||||
static QString s_TELEGRAMLIST_FILE_ID();
|
||||
static QString s_TELEGRAMLIST_FILES();
|
||||
|
||||
protected Q_SLOTS:
|
||||
|
||||
void addTelegram();
|
||||
|
||||
void injectTelegram(bool a_bAsCentralTelegram);
|
||||
|
||||
void injectTelegram(const QSharedPointer<LogViewTelegram> &a_telegram, bool a_bAsCentralTelegram);
|
||||
|
||||
void sendTelegram(const QSharedPointer<LogViewTelegram> &a_telegram);
|
||||
|
||||
void sendCurrentTelegram();
|
||||
|
||||
void tableViewCustomContextMenu(const QPoint &pos);
|
||||
|
||||
void editTelegram();
|
||||
|
||||
void showTelegram();
|
||||
|
||||
void deleteTelegram();
|
||||
|
||||
void injectCentralTelegram();
|
||||
|
||||
void injectTetraTelegram();
|
||||
|
||||
void loopTelegrams();
|
||||
|
||||
void loopNextTelegram();
|
||||
|
||||
void sequenceTelegrams();
|
||||
|
||||
void sequenceNextTelegram();
|
||||
|
||||
void copy();
|
||||
|
||||
void paste();
|
||||
|
||||
void moveUp();
|
||||
|
||||
void moveDown();
|
||||
|
||||
void saveTelegramList();
|
||||
|
||||
void loadTelegramListAppend();
|
||||
|
||||
void loadTelegramListReplace();
|
||||
|
||||
void editTelegramDialogFinished();
|
||||
|
||||
void onSelectionChanged();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
|
||||
|
||||
|
||||
#include "LogViewTelegramEditModel.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
int TelegramEditModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : m_telegrams.size();
|
||||
}
|
||||
|
||||
|
||||
int TelegramEditModel::columnCount(const QModelIndex &parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : 3;
|
||||
}
|
||||
|
||||
|
||||
QVariant TelegramEditModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.isValid() && index.row() < m_telegrams.size())
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
const QSharedPointer<LogViewTelegram> telegram = m_telegrams.at(index.row());
|
||||
switch (index.column())
|
||||
{
|
||||
case 0:
|
||||
return telegram->getName();
|
||||
case 1:
|
||||
return telegram->getParticipantId();
|
||||
case 2:
|
||||
return telegram->getWaitTime();
|
||||
}
|
||||
}
|
||||
else if (role == Qt::ToolTipRole)
|
||||
{
|
||||
const QSharedPointer<LogViewTelegram> telegram = m_telegrams.at(index.row());
|
||||
if (telegram->isJsonTelegram())
|
||||
return telegram->getData(QJsonDocument::JsonFormat::Indented);
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
QVariant TelegramEditModel::headerData(int section,
|
||||
Qt::Orientation orientation,
|
||||
int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return tr("Description");
|
||||
case 1:
|
||||
return tr("Equip. No.");
|
||||
case 2:
|
||||
return tr("Wait Time");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QAbstractTableModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
|
||||
void TelegramEditModel::clearTelegrams()
|
||||
{
|
||||
beginResetModel();
|
||||
m_telegrams.clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
||||
void TelegramEditModel::appendTelegrams(const QVector<QSharedPointer<LogViewTelegram> > &telegrams)
|
||||
{
|
||||
if (telegrams.isEmpty())
|
||||
return;
|
||||
beginInsertRows(QModelIndex(), m_telegrams.size(), m_telegrams.size() + telegrams.size() - 1);
|
||||
m_telegrams += telegrams;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
|
||||
int TelegramEditModel::appendTelegram(const QSharedPointer<LogViewTelegram> &telegram)
|
||||
{
|
||||
beginInsertRows(QModelIndex(), m_telegrams.size(), m_telegrams.size());
|
||||
m_telegrams.push_back(telegram);
|
||||
telegram->rebuildJsonString();
|
||||
endInsertRows();
|
||||
return m_telegrams.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
QSharedPointer<LogViewTelegram> TelegramEditModel::telegram(int row) const
|
||||
{
|
||||
if (row >= 0 && row < m_telegrams.size())
|
||||
return m_telegrams.at(row);
|
||||
return QSharedPointer<LogViewTelegram>();
|
||||
}
|
||||
|
||||
|
||||
bool TelegramEditModel::moveUp(int row)
|
||||
{
|
||||
if (row <= 0 || row >= m_telegrams.size())
|
||||
return false;
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), row - 1);
|
||||
std::swap(m_telegrams[row], m_telegrams[row - 1]);
|
||||
endMoveRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TelegramEditModel::moveDown(int row)
|
||||
{
|
||||
if (row >= (m_telegrams.size() - 1))
|
||||
return false;
|
||||
beginMoveRows(QModelIndex(), row, row, QModelIndex(), row + 1);
|
||||
std::swap(m_telegrams[row], m_telegrams[row + 1]);
|
||||
endMoveRows();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void TelegramEditModel::emitDataChanged(int row)
|
||||
{
|
||||
QModelIndex top = createIndex(row, 0);
|
||||
QModelIndex bottom = createIndex(row, columnCount() - 1);
|
||||
emit dataChanged(top, bottom, {Qt::DisplayRole, Qt::ToolTipRole});
|
||||
}
|
||||
|
||||
|
||||
void TelegramEditModel::removeTelegrams(const QSet<int> &rows)
|
||||
{
|
||||
QList<int> rowList = rows.values();
|
||||
std::sort(rowList.begin(), rowList.end());
|
||||
|
||||
for (int i = rowList.size() - 1 ; i >= 0; --i)
|
||||
{
|
||||
int row = rowList.at(i);
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
m_telegrams.remove(row);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TelegramEditModel::pasteRows(int row, const QSharedPointer<LogViewTelegram> &tele)
|
||||
{
|
||||
if (row < 0 || row > m_telegrams.size())
|
||||
return;
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
m_telegrams.insert(row, QSharedPointer<LogViewTelegram>(new LogViewTelegram(*tele.data())));
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QSet>
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class TelegramEditModel final : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QAbstractTableModel::QAbstractTableModel;
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
|
||||
void clearTelegrams();
|
||||
void appendTelegrams(const QVector<QSharedPointer<LogViewTelegram> > &telegrams);
|
||||
int appendTelegram(const QSharedPointer<LogViewTelegram> &telegram);
|
||||
QSharedPointer<LogViewTelegram> telegram(int row) const;
|
||||
|
||||
bool moveUp(int row);
|
||||
bool moveDown(int row);
|
||||
|
||||
void emitDataChanged(int row);
|
||||
|
||||
void removeTelegrams(const QSet<int> &rows);
|
||||
|
||||
void pasteRows(int row, const QSharedPointer<LogViewTelegram> &tele);
|
||||
protected:
|
||||
QVector<QSharedPointer<LogViewTelegram> > m_telegrams;
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewTelegramSelectionDialog.hpp"
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include "LogViewXdrType.hpp"
|
||||
#include "LogViewXdrParser.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include "LogViewTetraTelegramsParser.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
static int s_currentRow = 0;
|
||||
|
||||
LogViewTelegramSelectionDialog::LogViewTelegramSelectionDialog(QWidget* a_parent)
|
||||
: QDialog(a_parent)
|
||||
{
|
||||
setMinimumSize(QSize(600, 500));
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
layout->addWidget(new QLabel(tr("Select a telegram:")));
|
||||
m_TelegramList = new QListWidget(this);
|
||||
const auto telegramMap = LogViewTelegram::jsonParser()->telegramsToCreate();
|
||||
for (auto it = telegramMap.cbegin(); it != telegramMap.cend(); ++it)
|
||||
{
|
||||
if (it.key() == 0)
|
||||
continue;
|
||||
auto lwi = new QListWidgetItem(it.value() + QStringLiteral(" (%1)").arg(it.key()));
|
||||
lwi->setData(Qt::UserRole, it.key());
|
||||
m_TelegramList->addItem(lwi);
|
||||
}
|
||||
|
||||
m_TelegramList->sortItems();
|
||||
m_TelegramList->setCurrentRow(s_currentRow);
|
||||
connect(m_TelegramList, &QListWidget::itemActivated,
|
||||
this, &LogViewTelegramSelectionDialog::selectTelegram);
|
||||
layout->addWidget(m_TelegramList);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTelegramSelectionDialog::selectTelegram(QListWidgetItem* a_telegramItem)
|
||||
{
|
||||
s_currentRow = m_TelegramList->currentRow();
|
||||
m_SelectedTelegramId = a_telegramItem->data(Qt::UserRole).toInt();
|
||||
accept();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewTelegramSelectionDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
explicit LogViewTelegramSelectionDialog(QWidget* a_parent);
|
||||
|
||||
|
||||
int getSelectedTelegramId() const { return m_SelectedTelegramId; }
|
||||
|
||||
protected slots:
|
||||
|
||||
|
||||
void selectTelegram(QListWidgetItem* a_telegramItem);
|
||||
|
||||
protected:
|
||||
|
||||
QListWidget *m_TelegramList;
|
||||
int m_SelectedTelegramId;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,516 @@
|
||||
|
||||
|
||||
|
||||
#include "LogViewTetraTelegramsParser.hpp"
|
||||
|
||||
#include <QFile>
|
||||
#include <QVector>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
LogViewTetraTelegramsParser::LogViewTetraTelegramsParser()
|
||||
: m_logger(getLogger("LogViewTetraTelegramsParser"))
|
||||
{
|
||||
insertPod(QStringLiteral("bool"), 1, true, true, true);
|
||||
insertPod(QStringLiteral("int"), 4, true, true);
|
||||
insertPod(QStringLiteral("int32_t"), 4, true, true);
|
||||
insertPod(QStringLiteral("qint64"), 8, true, true);
|
||||
insertPod(QStringLiteral("float"), 4, true, false);
|
||||
insertPod(QStringLiteral("double"), 8, true, false);
|
||||
}
|
||||
|
||||
EnumInformation LogViewTetraTelegramsParser::enumFromType(const QString &type) const
|
||||
{
|
||||
for (const auto &ei : m_enums)
|
||||
{
|
||||
const QString fqType = ei.ns.isEmpty() ? ei.type : (ei.ns + QStringLiteral("::") + ei.type);
|
||||
if (fqType == type)
|
||||
return ei;
|
||||
}
|
||||
return EnumInformation();
|
||||
}
|
||||
|
||||
StructInformation LogViewTetraTelegramsParser::structFromType(const QString &type) const
|
||||
{
|
||||
return m_structs.value(type);
|
||||
}
|
||||
|
||||
PodInformation LogViewTetraTelegramsParser::podFromType(const QString &type) const
|
||||
{
|
||||
return m_pods.value(type);
|
||||
}
|
||||
|
||||
bool LogViewTetraTelegramsParser::isEnum(const QString &type) const
|
||||
{
|
||||
for (const auto &ei : m_enums)
|
||||
if (ei.type == type)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LogViewTetraTelegramsParser::isStruct(const QString &type) const
|
||||
{
|
||||
return m_structs.contains(type);
|
||||
}
|
||||
|
||||
bool LogViewTetraTelegramsParser::isPod(const QString &type) const
|
||||
{
|
||||
return m_pods.contains(type);
|
||||
}
|
||||
|
||||
static void fillBasemembers(StructInformation &si, const QHash<QString, StructInformation> &structs)
|
||||
{
|
||||
if (si.baseStruct.isEmpty())
|
||||
return;
|
||||
StructInformation base = structs.value(si.baseStruct);
|
||||
fillBasemembers(base, structs);
|
||||
si.member = (base.member + si.member);
|
||||
}
|
||||
|
||||
bool LogViewTetraTelegramsParser::parse(const QString &filename)
|
||||
{
|
||||
m_telegramIdEnum = EnumInformation();
|
||||
m_enums.clear();
|
||||
m_structs.clear();
|
||||
|
||||
m_visibleTelegrams.clear();
|
||||
|
||||
QFile f(filename);
|
||||
if (!f.open(QIODevice::ReadOnly))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not open file " << filename << " for reading: " << f.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString content = QString::fromUtf8(f.readAll());
|
||||
f.close();
|
||||
|
||||
const QVector<QStringRef> lines = content.splitRef(QLatin1Char('\n'));
|
||||
QVector<QStringRef> linesTrimmed;
|
||||
linesTrimmed.reserve(lines.size());
|
||||
for (const QStringRef &line : lines)
|
||||
linesTrimmed += line.trimmed();
|
||||
|
||||
int i = 0;
|
||||
while (i < linesTrimmed.size())
|
||||
{
|
||||
const QStringRef &line = linesTrimmed.at(i);
|
||||
if (line.startsWith(QLatin1String("struct")))
|
||||
{
|
||||
i = parseStruct(linesTrimmed, i);
|
||||
if (i < 0)
|
||||
return false;
|
||||
}
|
||||
else if (line.startsWith(QLatin1String("enum")))
|
||||
{
|
||||
i = parseEnum(linesTrimmed, i, QString());
|
||||
if (i < 0)
|
||||
return false;
|
||||
}
|
||||
else if (line.startsWith(QLatin1String("template <> struct Constraints")))
|
||||
{
|
||||
i = parseConstraint(linesTrimmed, i);
|
||||
if (i < 0)
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
const auto completeStructs = m_structs;
|
||||
for (StructInformation &si : m_structs)
|
||||
fillBasemembers(si, completeStructs);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LogViewTetraTelegramsParser::insertPod(const QString &type, int byteLen, bool isSigned, bool isIntegral, bool isBoolean)
|
||||
{
|
||||
PodInformation pod;
|
||||
pod.type = type;
|
||||
pod.byteLen = byteLen;
|
||||
pod.isBoolean = isBoolean;
|
||||
pod.isIntegral = isIntegral;
|
||||
pod.isSigned = isSigned;
|
||||
m_pods[type] = pod;
|
||||
}
|
||||
|
||||
|
||||
int LogViewTetraTelegramsParser::parseStruct(const QVector<QStringRef> &lines, int iStartPos)
|
||||
{
|
||||
const QVector<QStringRef> tokens = tokenize(lines.at(iStartPos));
|
||||
if (tokens.size() < 2)
|
||||
return -1;
|
||||
const QStringRef &structType = tokens.at(1);
|
||||
if (structType.endsWith(QLatin1Char(';')))
|
||||
return iStartPos;
|
||||
|
||||
StructInformation si;
|
||||
si.type = structType.toString();
|
||||
if (tokens.size() > 2)
|
||||
{
|
||||
if (tokens.at(2) != QLatin1String(":"))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse struct: '" << lines.at(iStartPos).toString() << "', line: " << iStartPos + 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 3; i < tokens.size(); ++i)
|
||||
{
|
||||
if (!si.baseStruct.isEmpty())
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse struct: '" << lines.at(iStartPos).toString() << "', line: " << iStartPos + 1;
|
||||
return -1;
|
||||
}
|
||||
QStringRef base = tokens.at(i);
|
||||
if (base == QLatin1String("public") ||
|
||||
base == QLatin1String("protected") ||
|
||||
base == QLatin1String("private"))
|
||||
continue;
|
||||
if (base.endsWith(QLatin1Char(',')))
|
||||
base.chop(1);
|
||||
if (base.endsWith(QLatin1Char('>')))
|
||||
{
|
||||
si.isVisible = true;
|
||||
continue;
|
||||
}
|
||||
si.baseStruct = tokens.at(i).toString();
|
||||
}
|
||||
}
|
||||
|
||||
int i = iStartPos + 1;
|
||||
while (i < lines.size())
|
||||
{
|
||||
const QVector<QStringRef> tokens = tokenize(lines.at(i));
|
||||
if (!validStructTokens(tokens))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (tokens.at(0) == QLatin1String("};"))
|
||||
break;
|
||||
if (tokens.at(0) == QLatin1String("enum"))
|
||||
{
|
||||
i = parseEnum(lines, i, si.type, &si);
|
||||
if (i < 0)
|
||||
return -1;
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
|
||||
MemberInformation mi;
|
||||
if (tokens.size() > 2)
|
||||
{
|
||||
const int parserCommentPos = tokens.at(2) == QLatin1String("=") ? 4 : 2;
|
||||
if (tokens.size() > parserCommentPos)
|
||||
{
|
||||
const QStringRef &comment = tokens.at(parserCommentPos);
|
||||
DEBUG_LOG(m_logger) << "comment: " << comment.toString();
|
||||
if (comment.startsWith(QLatin1String("//@array: ")))
|
||||
{
|
||||
const QStringRef hint = comment.mid(QLatin1String("//@array: ").size());
|
||||
QString structStr = QLatin1String("struct ") + si.type + QLatin1String("::") + tokens.at(0).toString() + QLatin1Char('\n') + hint.toString();
|
||||
structStr.replace(QLatin1Char(';'), QLatin1String(";\n"));
|
||||
DEBUG_LOG(m_logger) << "structStr: " << structStr;
|
||||
parseStruct(structStr.splitRef(QLatin1Char('\n')), 0);
|
||||
|
||||
mi.type = si.type + QLatin1String("::") + tokens.at(0).toString();
|
||||
mi.isArray = true;
|
||||
}
|
||||
if (comment == QLatin1String("//@invisible"))
|
||||
mi.isVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
QStringRef name = tokens.at(1);
|
||||
if (name.endsWith(QLatin1Char(';')))
|
||||
name.chop(1);
|
||||
if (mi.type.isEmpty())
|
||||
mi.type += tokens.at(0).toString();
|
||||
categorizeMember(mi);
|
||||
mi.name = name.toString();
|
||||
if (mi.isEnum && !mi.type.contains(QLatin1String("::")))
|
||||
{
|
||||
|
||||
for (const auto &ei : qAsConst(m_enums))
|
||||
{
|
||||
if (ei.type == mi.type)
|
||||
{
|
||||
if (!ei.ns.isEmpty())
|
||||
mi.type = ei.ns + QLatin1String("::") + mi.type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
si.member.push_back(std::move(mi));
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
{
|
||||
if (si.baseStruct.isEmpty())
|
||||
DEBUG_LOG(m_logger) << "Found Struct: " << si.type;
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "Found Struct: " << si.type << ", base: " << si.baseStruct;
|
||||
for (int j = 0; j < si.member.size(); ++j)
|
||||
{
|
||||
const MemberInformation &mi = si.member.at(j);
|
||||
DEBUG_LOG(m_logger) << "Member[" << j << "]: " << mi.type << " - " << mi.name;
|
||||
}
|
||||
}
|
||||
|
||||
m_structs[si.type] = si;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int LogViewTetraTelegramsParser::parseEnum(const QVector<QStringRef> &lines, int iStartPos, const QString &ns, StructInformation *si)
|
||||
{
|
||||
const QVector<QStringRef> tokens = tokenize(lines.at(iStartPos));
|
||||
if (tokens.size() < 2)
|
||||
return -1;
|
||||
QStringRef enumName = tokens.at(1);
|
||||
if (enumName == QLatin1String("class"))
|
||||
{
|
||||
if (tokens.size() < 3)
|
||||
return -1;
|
||||
enumName = tokens.at(2);
|
||||
}
|
||||
if (enumName.endsWith(QLatin1Char(';')))
|
||||
return iStartPos;
|
||||
|
||||
EnumInformation ei;
|
||||
ei.type = enumName.toString();
|
||||
ei.ns = ns;
|
||||
|
||||
int i = iStartPos + 1;
|
||||
while (i < lines.size())
|
||||
{
|
||||
const QVector<QStringRef> tokens = tokenize(lines.at(i).split(QStringLiteral("//")).first());
|
||||
if (tokens.isEmpty() ||
|
||||
(tokens.at(0) == QLatin1String("{")))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (tokens.at(0) == QLatin1String("};"))
|
||||
break;
|
||||
if ((tokens.size() != 1 && tokens.size() != 3) ||
|
||||
(tokens.size() == 3 && tokens.at(1) != QLatin1String("=")))
|
||||
{
|
||||
if (tokens.size() == 4 && tokens.at(0) == QLatin1String("}") && tokens.at(3).endsWith(QLatin1Char(';')) && si)
|
||||
{
|
||||
|
||||
MemberInformation mi;
|
||||
if (ns.isEmpty())
|
||||
mi.type = ei.type;
|
||||
else
|
||||
mi.type = ns + QStringLiteral("::") + ei.type;
|
||||
mi.isEnum = true;
|
||||
mi.name = tokens.at(1).toString();
|
||||
si->member.push_back(std::move(mi));
|
||||
break;
|
||||
}
|
||||
WARNING_LOG(m_logger) << "Could not parse enum: '" << lines.at(i).toString() << "', line: " << i + 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
EnumValue ev;
|
||||
ev.key = tokens.at(0).toString();
|
||||
if (tokens.size() == 3)
|
||||
{
|
||||
QStringRef value = tokens.at(2);
|
||||
if (value.endsWith(QLatin1Char(',')))
|
||||
value.chop(1);
|
||||
ev.value = value.toInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
int val = ei.values.isEmpty() ? 0 : (ei.values.last().value + 1);
|
||||
ev.value = val;
|
||||
}
|
||||
ei.values.push_back(std::move(ev));
|
||||
++i;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Found Enum: " << ei.type;
|
||||
for (const EnumValue &ev : qAsConst(ei.values))
|
||||
DEBUG_LOG(m_logger) << "Member[" << i << "]: " << ev.key << " = " << ev.value;
|
||||
|
||||
if (ei.type == QLatin1String("TelegramId"))
|
||||
m_telegramIdEnum = ei;
|
||||
|
||||
m_enums.push_back(std::move(ei));
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int LogViewTetraTelegramsParser::parseConstraint(const QVector<QStringRef> &lines, int iStartPos)
|
||||
{
|
||||
const QVector<QStringRef> tokens = tokenize(lines.at(iStartPos));
|
||||
if (tokens.size() != 4)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse constraint: '" << lines.at(iStartPos).toString() << "'";
|
||||
return -1;
|
||||
}
|
||||
const QStringRef &cs = tokens.at(3);
|
||||
if (!cs.startsWith(QLatin1String("Constraints<")) || !cs.endsWith(QLatin1Char('>')))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse constraint: '" << lines.at(iStartPos).toString() << "'";
|
||||
return -1;
|
||||
}
|
||||
QStringRef structName = cs.mid(QLatin1String("Constraints<").size());
|
||||
structName.chop(1);
|
||||
DEBUG_LOG(m_logger) << "Constraint: " << structName.toString();
|
||||
|
||||
int i = iStartPos + 1;
|
||||
while (i < lines.size())
|
||||
{
|
||||
const QVector<QStringRef> tokens = tokenize(lines.at(i));
|
||||
if (tokens.isEmpty() ||
|
||||
(tokens.at(0) == QLatin1String("{")))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (tokens.at(0) == QLatin1String("};"))
|
||||
break;
|
||||
if (tokens.size() != 8 || tokens.at(2) != QLatin1String("TelegramId"))
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
const QVector<QStringRef> parts = tokens.at(6).split(QLatin1String("::"));
|
||||
if (parts.size() != 2)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse constraint: '" << lines.at(i).toString() << "'";
|
||||
return -1;
|
||||
}
|
||||
|
||||
QStringRef enumKey = parts.at(1);
|
||||
if (enumKey.endsWith(QLatin1Char(';')))
|
||||
enumKey.chop(1);
|
||||
bool bFound = false;
|
||||
for (const auto &v : qAsConst(m_telegramIdEnum.values))
|
||||
{
|
||||
if (v.key == enumKey)
|
||||
{
|
||||
m_visibleTelegrams.insert(v.value, structName.toString());
|
||||
bFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!bFound)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not find enum value '" << enumKey.toString() << "' in enum TelegramId";
|
||||
return -1;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
QString LogViewTetraTelegramsParser::getInnerType(const QString &type)
|
||||
{
|
||||
int idxLt = type.lastIndexOf(QLatin1Char('>'));
|
||||
if (idxLt < 0)
|
||||
return QString();
|
||||
int idxGt = type.indexOf(QLatin1Char('<'));
|
||||
if (idxGt < 0)
|
||||
return QString();
|
||||
return type.mid(idxGt + 1, idxLt - idxGt - 1);
|
||||
}
|
||||
|
||||
void LogViewTetraTelegramsParser::categorizeMember(MemberInformation &mi) const
|
||||
{
|
||||
mi.isPod = isPod(mi.type);
|
||||
mi.isEnum = mi.isPod ? false : isEnum(mi.type);
|
||||
if (mi.type.startsWith(QLatin1String("std::vector<")))
|
||||
mi.isArray = true;
|
||||
mi.isStruct = mi.isArray ? false : isStruct(mi.type);
|
||||
mi.isString = (mi.type == QLatin1String("std::string") || mi.type == QLatin1String("QString"));
|
||||
mi.isBinary = (mi.type == QLatin1String("std::vector<unsigned char>") || mi.type == QLatin1String("QByteArray"));
|
||||
}
|
||||
|
||||
static inline void bracketCount(const QStringRef &str, int &cntLt, int &cntGt)
|
||||
{
|
||||
cntLt = 0;
|
||||
cntGt = 0;
|
||||
for (int i = 0; i < str.size(); ++i)
|
||||
{
|
||||
if (str.at(i) == QLatin1Char('<'))
|
||||
cntLt++;
|
||||
else if (str.at(i) == QLatin1Char('>'))
|
||||
cntGt++;
|
||||
}
|
||||
}
|
||||
|
||||
QVector<QStringRef> LogViewTetraTelegramsParser::tokenize(const QStringRef &line) const
|
||||
{
|
||||
QVector<QStringRef> ret = line.split(QLatin1Char(' '), QString::SkipEmptyParts);
|
||||
int i = 0;
|
||||
while (i < ret.size())
|
||||
{
|
||||
const QStringRef &token = ret.at(i);
|
||||
if (token.startsWith(QLatin1String("//")))
|
||||
{
|
||||
|
||||
if (i == ret.size() - 1)
|
||||
break;
|
||||
const QStringRef &lastToken = ret.last();
|
||||
const QStringRef newToken = QStringRef(token.string(), token.position(), lastToken.position() - token.position() + lastToken.size());
|
||||
DEBUG_LOG(m_logger) << "New Token: " << newToken.toString();
|
||||
ret.resize(i + 1);
|
||||
ret[i] = newToken;
|
||||
break;
|
||||
}
|
||||
if (i == ret.size() - 1)
|
||||
break;
|
||||
int cntLt;
|
||||
int cntGt;
|
||||
bracketCount(token, cntLt, cntGt);
|
||||
if (cntLt == cntGt)
|
||||
{
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
const QStringRef &nextToken = ret.at(i + 1);
|
||||
const QStringRef newToken = QStringRef(token.string(), token.position(), nextToken.position() - token.position() + nextToken.size());
|
||||
DEBUG_LOG(m_logger) << "New Token: " << newToken.toString();
|
||||
ret.removeAt(i + 1);
|
||||
ret[i] = newToken;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool LogViewTetraTelegramsParser::validStructTokens(const QVector<QStringRef> &tokens)
|
||||
{
|
||||
if (tokens.isEmpty() ||
|
||||
(tokens.at(0) == QLatin1String("{")) ||
|
||||
(tokens.at(0) == QLatin1String("{}")) ||
|
||||
(tokens.at(0) == QLatin1String("}")) ||
|
||||
(tokens.at(0) == QLatin1String(":")) ||
|
||||
(tokens.at(0) == QLatin1String(",")) ||
|
||||
(tokens.at(0) == QLatin1String("virtual")))
|
||||
return false;
|
||||
|
||||
if (tokens.at(0) == QLatin1String("};") || tokens.at(0) == QLatin1String("enum"))
|
||||
return true;
|
||||
|
||||
const int len = tokens.last().startsWith(QLatin1String("//")) ? tokens.size() - 1 : tokens.size();
|
||||
|
||||
if (len == 2)
|
||||
return true;
|
||||
|
||||
if (len < 4)
|
||||
return false;
|
||||
|
||||
if (len >= 4 && tokens.at(2) == QLatin1String("="))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QHash>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
#include "logger.h"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
struct MemberInformation
|
||||
{
|
||||
QString name;
|
||||
QString type;
|
||||
bool isArray = false;
|
||||
bool isBinary = false;
|
||||
bool isEnum = false;
|
||||
bool isPod = false;
|
||||
bool isString = false;
|
||||
bool isStruct = false;
|
||||
bool isVisible = true;
|
||||
};
|
||||
|
||||
struct StructInformation
|
||||
{
|
||||
QString type;
|
||||
QString baseStruct;
|
||||
|
||||
QVector<MemberInformation> member;
|
||||
bool isVisible = false;
|
||||
};
|
||||
|
||||
struct EnumValue
|
||||
{
|
||||
QString key;
|
||||
int value = 0;
|
||||
};
|
||||
|
||||
struct EnumInformation
|
||||
{
|
||||
QString ns;
|
||||
QString type;
|
||||
QVector<EnumValue> values;
|
||||
};
|
||||
|
||||
struct PodInformation
|
||||
{
|
||||
QString type;
|
||||
int byteLen = 0;
|
||||
bool isBoolean = false;
|
||||
bool isIntegral = false;
|
||||
bool isSigned = false;
|
||||
};
|
||||
|
||||
class LogViewTetraTelegramsParser
|
||||
{
|
||||
public:
|
||||
LogViewTetraTelegramsParser();
|
||||
|
||||
bool parse(const QString &filename);
|
||||
|
||||
EnumInformation enumFromType(const QString &type) const;
|
||||
StructInformation structFromType(const QString &type) const;
|
||||
PodInformation podFromType(const QString &type) const;
|
||||
bool isEnum(const QString &type) const;
|
||||
bool isStruct(const QString &type) const;
|
||||
bool isPod(const QString &type) const;
|
||||
QHash<int, QString> telegramsToCreate() const { return m_visibleTelegrams; }
|
||||
QString nameFromTelegramId(int telId) const { return m_visibleTelegrams.value(telId); }
|
||||
static QString getInnerType(const QString &type);
|
||||
private:
|
||||
void insertPod(const QString &type, int byteLen, bool isSigned, bool isIntegral, bool isBoolean = false);
|
||||
int parseStruct(const QVector<QStringRef> &lines, int iStartPos);
|
||||
int parseEnum(const QVector<QStringRef> &lines, int iStartPos, const QString &ns, StructInformation *si = nullptr);
|
||||
int parseConstraint(const QVector<QStringRef> &lines, int iStartPos);
|
||||
void categorizeMember(MemberInformation &mi) const;
|
||||
QVector<QStringRef> tokenize(const QStringRef &line) const;
|
||||
static bool validStructTokens(const QVector<QStringRef> &tokens);
|
||||
private:
|
||||
EnumInformation m_telegramIdEnum;
|
||||
QVector<EnumInformation> m_enums;
|
||||
QHash<QString, StructInformation> m_structs;
|
||||
QHash<QString, PodInformation> m_pods;
|
||||
QHash<int, QString> m_visibleTelegrams;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewTextEdit.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewTextEdit::LogViewTextEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly)
|
||||
: QLineEdit(a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, a_readonly)
|
||||
{
|
||||
const QString value = a_field->value(0);
|
||||
setText(value);
|
||||
|
||||
if (a_readonly)
|
||||
{
|
||||
setReadOnly(true);
|
||||
setAlignment(a_field->isRightAligned() ? Qt::AlignRight : Qt::AlignLeft);
|
||||
}
|
||||
|
||||
|
||||
uint16_t maxArraySize = a_field->maxArraySize();
|
||||
setMaxLength(maxArraySize);
|
||||
updateToolTip(value);
|
||||
|
||||
|
||||
QFontMetrics fm(font());
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||
setMinimumWidth(fm.width(QLatin1Char(' ') + value + QLatin1Char(' ')));
|
||||
#else
|
||||
setMinimumWidth(fm.horizontalAdvance(QLatin1Char(' ') + value + QLatin1Char(' ')));
|
||||
#endif
|
||||
|
||||
|
||||
connect(this, &LogViewTextEdit::editingFinished,
|
||||
this, &LogViewTextEdit::checkAndOvertakeContent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewTextEdit::checkAndOvertakeContent()
|
||||
{
|
||||
updateToolTip(text());
|
||||
m_Valid = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewTextEdit::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
if (a_telegram->isJsonTelegram())
|
||||
{
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), text());
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t size = getSize();
|
||||
QString content = text();
|
||||
uint16_t arraySize;
|
||||
if (m_Field->isDynamicArray())
|
||||
{
|
||||
arraySize = content.length();
|
||||
a_telegram->setUIntX(LogViewTelegram::SIZE_CENTRAL_DYN_ARRAY_SIZE, arraySize);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
arraySize = m_Field->maxArraySize();
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < arraySize; i++)
|
||||
a_telegram->setUIntX(size, i < content.length() ? content[i].toLatin1() : 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewWidget.hpp"
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewTextEdit : public QLineEdit, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
LogViewTextEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly);
|
||||
|
||||
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
|
||||
protected slots:
|
||||
void checkAndOvertakeContent();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewValueEdit.hpp"
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewValueEdit::LogViewValueEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly)
|
||||
: QLineEdit(a_parent)
|
||||
, LogViewWidget(a_field, this, a_parent, a_readonly)
|
||||
, m_IsFloat(false)
|
||||
{
|
||||
const LogViewXdrStandardType *stdType = static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement());
|
||||
m_IsFloat = (LogViewXdrStandardType::e_Float == stdType->getValueKind());
|
||||
|
||||
const QString valueText = a_field->value(0);
|
||||
|
||||
setText(valueText);
|
||||
|
||||
|
||||
updateToolTip(valueText);
|
||||
|
||||
|
||||
QFontMetrics fm(font());
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 11, 0)
|
||||
setMinimumWidth(fm.width(QLatin1Char(' ') + valueText + QLatin1Char(' ')));
|
||||
#else
|
||||
setMinimumWidth(fm.horizontalAdvance(QLatin1Char(' ') + valueText + QLatin1Char(' ')));
|
||||
#endif
|
||||
|
||||
if (a_readonly)
|
||||
{
|
||||
setReadOnly(true);
|
||||
setAlignment(a_field->isRightAligned() ? Qt::AlignRight : Qt::AlignLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(this, &LogViewValueEdit::editingFinished,
|
||||
this, &LogViewValueEdit::checkAndOvertakeContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewValueEdit::checkAndOvertakeContent()
|
||||
{
|
||||
bool ok;
|
||||
int64_t intValue = 0;
|
||||
double floatValue = 0.0;
|
||||
|
||||
|
||||
if (m_IsFloat)
|
||||
floatValue = getFloat(text(), (uint64_t&)intValue, ok);
|
||||
else
|
||||
intValue = getInteger(text(), ok);
|
||||
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
setFocus();
|
||||
selectAll();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (m_IsFloat)
|
||||
setText(QString::number(floatValue));
|
||||
else
|
||||
setText(QString::number(intValue));
|
||||
|
||||
updateToolTip(text());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool LogViewValueEdit::saveContent(LogViewTelegram* a_telegram)
|
||||
{
|
||||
if (m_Valid)
|
||||
{
|
||||
bool ok;
|
||||
if (m_IsFloat)
|
||||
{
|
||||
|
||||
uint64_t valueAsUint64;
|
||||
const double value = getFloat(text(), valueAsUint64, ok);
|
||||
if (ok)
|
||||
{
|
||||
if (a_telegram->isJsonTelegram())
|
||||
{
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), value);
|
||||
}
|
||||
else
|
||||
{
|
||||
const LogViewXdrStandardType *stdType = static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement());
|
||||
LogViewXdrStandardType::E_ByteOrder byteOrder = stdType->getByteOrder();
|
||||
a_telegram->setUIntX(getSize(), valueAsUint64, byteOrder);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
qint64 intValue = getInteger(text(), ok);
|
||||
if (ok)
|
||||
{
|
||||
if (a_telegram->isJsonTelegram())
|
||||
a_telegram->setJsonValue(m_Field->jsonPath(), intValue);
|
||||
else
|
||||
a_telegram->setUIntX(getSize(), intValue);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewWidget.hpp"
|
||||
#include <QLineEdit>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewValueEdit : public QLineEdit, public LogViewWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
|
||||
LogViewValueEdit(LogViewField* a_field, QWidget* a_parent, const bool a_readonly);
|
||||
|
||||
|
||||
|
||||
bool saveContent(LogViewTelegram* a_telegram) override;
|
||||
|
||||
protected:
|
||||
|
||||
bool m_IsFloat;
|
||||
|
||||
protected slots:
|
||||
void checkAndOvertakeContent();
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewWidget.hpp"
|
||||
|
||||
#include "LogViewField.hpp"
|
||||
#include "LogViewTelegram.hpp"
|
||||
#include "LogViewXdrStandardType.hpp"
|
||||
#include "IntegerCalculator.hpp"
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewWidget::LogViewWidget(LogViewField* a_field, QWidget* a_widget, QWidget* a_parent, bool a_readonly)
|
||||
: m_Readonly(a_readonly)
|
||||
, m_Valid(true)
|
||||
, m_Widget(a_widget)
|
||||
, m_Field(a_field)
|
||||
, m_Parent(a_parent)
|
||||
, m_logger(getLogger("LogViewWidget"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
uint16_t LogViewWidget::getSize() const
|
||||
{
|
||||
|
||||
const LogViewXdrStandardType* xdrStandardType = static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement());
|
||||
return xdrStandardType->getValueSize();
|
||||
}
|
||||
|
||||
|
||||
void LogViewWidget::showMessageBox(const QString &a_errorText) const
|
||||
{
|
||||
QMessageBox::warning(m_Parent, QObject::tr("Fehler"), a_errorText);
|
||||
}
|
||||
|
||||
|
||||
void LogViewWidget::updateToolTip(const QString &a_text)
|
||||
{
|
||||
bool isList = m_Field->valueListSize() > 1 || m_Field->isDynamicArray();
|
||||
switch (m_Field->xdrElement()->getKind())
|
||||
{
|
||||
case LogViewXdrElement::e_KindStandardType:
|
||||
switch (static_cast<const LogViewXdrStandardType*>(m_Field->xdrElement())->getValueKind())
|
||||
{
|
||||
case LogViewXdrStandardType::e_Character:
|
||||
m_Widget->setToolTip(QObject::tr("%1 Zeichen").arg(a_text.length()));
|
||||
if (!m_Readonly)
|
||||
m_Widget->setToolTip(QObject::tr("%1<br><nobr>Maximal %2 Zeichen erlaubt</nobr>").arg(m_Widget->toolTip()).arg(m_Field->maxArraySize()));
|
||||
break;
|
||||
case LogViewXdrStandardType::e_Data:
|
||||
if (m_Readonly)
|
||||
m_Widget->setToolTip(QObject::tr("%1 Bytes").arg(m_Field->valueListSize()));
|
||||
break;
|
||||
case LogViewXdrStandardType::e_Unsigned:
|
||||
case LogViewXdrStandardType::e_Signed:
|
||||
if (m_Readonly && isList)
|
||||
{
|
||||
m_Widget->setToolTip(QObject::tr("%1 Elemente").arg(m_Field->valueListSize()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (m_Field->isDateTimeField())
|
||||
{
|
||||
m_Widget->setToolTip(QObject::tr("Unixzeit: %1 ").arg(a_text));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Widget->setToolTip(QString());
|
||||
}
|
||||
|
||||
if (!isList)
|
||||
{
|
||||
int64_t value = a_text.toLong();
|
||||
m_Widget->setToolTip(QStringLiteral("%1<b>%2</b> %3").arg(m_Widget->toolTip(), toHex(value), toBin(value)));
|
||||
}
|
||||
|
||||
if (!m_Field->isDateTimeField() && !m_Readonly)
|
||||
{
|
||||
const QString sep(isList ? QString() : QStringLiteral("<br>"));
|
||||
m_Widget->setToolTip(QStringLiteral("%1%2<nobr>Wertebereich: %3..%4</nobr>").arg(m_Widget->toolTip(), sep).arg(m_Field->getLowestValue()).arg(m_Field->getHighestValue()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LogViewXdrStandardType::e_Float:
|
||||
if (4 == m_Field->size())
|
||||
m_Widget->setToolTip(QStringLiteral("<nobr>Wertebereich: +/-3.4e+/-38</nobr>"));
|
||||
else
|
||||
m_Widget->setToolTip(QStringLiteral("<nobr>Wertebereich: +/-1.7e+/-308</nobr>"));
|
||||
break;
|
||||
case LogViewXdrStandardType::e_Boolean:
|
||||
m_Widget->setToolTip(QStringLiteral("true/false"));
|
||||
|
||||
}
|
||||
break;
|
||||
case LogViewXdrElement::e_KindEnum:
|
||||
{
|
||||
uint64_t enumValue = a_text.toLong();
|
||||
m_Widget->setToolTip(QStringLiteral("<b>%1 %2</b> %3").arg(enumValue).arg(toHex(enumValue), toBin(enumValue)));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ERROR_LOG(m_logger) << "Case not implemented";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
double LogViewWidget::getFloat(const QString& a_text, uint64_t& a_FloatAsData, bool& a_ok, const bool a_reverse)
|
||||
{
|
||||
|
||||
|
||||
|
||||
double value;
|
||||
if (8 == getSize())
|
||||
{
|
||||
value = a_text.toDouble(&a_ok);
|
||||
a_FloatAsData = LogViewTelegram::doubleToXdr(value);
|
||||
} else {
|
||||
value = a_text.toFloat(&a_ok);
|
||||
a_FloatAsData = LogViewTelegram::floatToXdr(value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!a_ok)
|
||||
showMessageBox(QStringLiteral("Inalid real value: '%1'").arg(a_text));
|
||||
|
||||
m_Valid = a_ok;
|
||||
|
||||
|
||||
if (a_reverse)
|
||||
{
|
||||
int j = getSize() - 1;
|
||||
uint64_t* ptr = &a_FloatAsData;
|
||||
for (int i = 0; i < getSize() / 2; i++)
|
||||
{
|
||||
uint8_t data = ((uint8_t*)ptr)[j];
|
||||
((uint8_t*)&a_FloatAsData)[j] = ((uint8_t*)&a_FloatAsData)[i];
|
||||
((uint8_t*)&a_FloatAsData)[i] = data;
|
||||
j--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (4 == getSize())
|
||||
{
|
||||
((uint8_t*)&a_FloatAsData)[4] = 0;
|
||||
((uint8_t*)&a_FloatAsData)[5] = 0;
|
||||
((uint8_t*)&a_FloatAsData)[6] = 0;
|
||||
((uint8_t*)&a_FloatAsData)[7] = 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int64_t LogViewWidget::getInteger(const QString& a_text, bool& a_ok)
|
||||
{
|
||||
|
||||
N_SST::IntegerCalculator calculator;
|
||||
N_SST::IntegerCalculator::E_Error error;
|
||||
int64_t value = calculator.calc(a_text.toStdString(), error);
|
||||
m_Valid = false;
|
||||
a_ok = true;
|
||||
if (N_SST::IntegerCalculator::e_Ok != error)
|
||||
{
|
||||
|
||||
if (a_text != m_LastErrorValueText)
|
||||
{
|
||||
showMessageBox(QString::fromUtf8("Die Berechnung '%1' ist falsch").arg(a_text));
|
||||
m_LastErrorValueText = a_text;
|
||||
}
|
||||
a_ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
int64_t highest = m_Field->getHighestValue();
|
||||
if (value > highest)
|
||||
{
|
||||
a_ok = false;
|
||||
|
||||
|
||||
if (a_text != m_LastErrorValueText)
|
||||
{
|
||||
showMessageBox(QString::fromUtf8("Der Wert '%1' ist zu hoch. Maximalwert: %2").arg(a_text).arg(highest));
|
||||
m_LastErrorValueText = a_text;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
int64_t lowest = m_Field->getLowestValue();
|
||||
if (value < lowest)
|
||||
{
|
||||
a_ok = false;
|
||||
if (a_text != m_LastErrorValueText)
|
||||
{
|
||||
showMessageBox(QString::fromUtf8("Der Wert '%1' ist zu tief. Minimalwert: %2").arg(a_text).arg(lowest));
|
||||
m_LastErrorValueText = a_text;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
m_Valid = true;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include "logger.h"
|
||||
|
||||
class QWidget;
|
||||
class QFont;
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
template <typename T>
|
||||
inline QString toHex(T num)
|
||||
{
|
||||
return QStringLiteral("0x%1").arg(num, 2, 16, QLatin1Char('0'));
|
||||
}
|
||||
template <typename T>
|
||||
inline QString toBin(T num)
|
||||
{
|
||||
return QStringLiteral("0b%1").arg(num, 8, 2, QLatin1Char('0'));
|
||||
}
|
||||
|
||||
class LogViewField;
|
||||
class LogViewTelegram;
|
||||
|
||||
|
||||
|
||||
class LogViewWidget
|
||||
{
|
||||
public:
|
||||
LogViewWidget(LogViewField* a_field, QWidget* a_widget, QWidget* a_parent, bool a_readonly);
|
||||
virtual ~LogViewWidget() = default;
|
||||
|
||||
virtual uint16_t getSize() const;
|
||||
LogViewField* field() const { return m_Field; }
|
||||
bool isValid() const { return m_Valid; }
|
||||
|
||||
|
||||
|
||||
QString getText() const { return m_Text; }
|
||||
|
||||
|
||||
|
||||
virtual bool saveContent(LogViewTelegram* a_telegram) = 0;
|
||||
|
||||
protected:
|
||||
void showMessageBox(const QString &a_errorText) const;
|
||||
void updateToolTip(const QString &a_text = QString());
|
||||
double getFloat(const QString& a_text, uint64_t& a_FloatAsData, bool& a_ok, const bool a_reverse = false);
|
||||
|
||||
|
||||
|
||||
int64_t getInteger(const QString& a_text, bool& a_ok);
|
||||
|
||||
|
||||
protected:
|
||||
bool m_Readonly;
|
||||
bool m_Valid;
|
||||
|
||||
|
||||
QString m_Text;
|
||||
QString m_LastErrorValueText;
|
||||
QWidget *m_Widget;
|
||||
|
||||
LogViewField *m_Field;
|
||||
|
||||
QWidget *m_Parent;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewXdrElement.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
LogViewXdrElement::LogViewXdrElement(const QString& a_name, const E_ElementKind a_kind, const char *loggerName)
|
||||
: m_Name(a_name)
|
||||
, m_Kind(a_kind)
|
||||
, m_logger(getLogger(loggerName))
|
||||
{
|
||||
if (a_name.indexOf(QLatin1Char('<')) >= 0 || a_name.indexOf(QLatin1Char('[')) >= 0)
|
||||
ERROR_LOG(m_logger) << "Element \'" << a_name.toStdString() << "\' has a problem";
|
||||
}
|
||||
|
||||
|
||||
void LogViewXdrElement::dump() const
|
||||
{
|
||||
INFO_LOG(m_logger) << "Element[" << getName() << "]: kind=" << getKindName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString LogViewXdrElement::getKindName() const
|
||||
{
|
||||
switch (getKind())
|
||||
{
|
||||
case e_KindDefine:
|
||||
return QLatin1String("Define");
|
||||
case e_KindEnum:
|
||||
return QLatin1String("Enum");
|
||||
case e_KindEnumElement:
|
||||
return QLatin1String("EnumElement");
|
||||
case e_KindStandardType:
|
||||
return QLatin1String("StandardType");
|
||||
case e_KindStruct:
|
||||
return QLatin1String("Struct");
|
||||
case e_KindStructElement:
|
||||
return QLatin1String("StructElement");
|
||||
case e_KindTypedef:
|
||||
return QLatin1String("Typedef");
|
||||
}
|
||||
return QStringLiteral("Unknown (%1)").arg(getKind());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include "logger.h"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewXdrElement
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
enum E_ElementKind
|
||||
{
|
||||
e_KindStandardType,
|
||||
e_KindTypedef,
|
||||
e_KindStruct,
|
||||
e_KindStructElement,
|
||||
e_KindEnum,
|
||||
e_KindEnumElement,
|
||||
e_KindDefine
|
||||
};
|
||||
|
||||
virtual ~LogViewXdrElement() = default;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
LogViewXdrElement(const QString& a_name, const E_ElementKind a_kind, const char *loggerName);
|
||||
|
||||
public:
|
||||
const QString& getName() const { return m_Name; }
|
||||
LogViewXdrElement::E_ElementKind getKind() const { return m_Kind; }
|
||||
|
||||
virtual void dump() const;
|
||||
|
||||
protected:
|
||||
QString m_Name;
|
||||
E_ElementKind m_Kind;
|
||||
QString getKindName() const;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include "IntegerCalculator.hpp"
|
||||
#include "logger.h"
|
||||
#include "LogViewXdrStandardType.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewXdrElement;
|
||||
class LogViewXdrStruct;
|
||||
class LogViewField;
|
||||
class LogViewXdrValue;
|
||||
class LogViewXdrType;
|
||||
|
||||
|
||||
|
||||
class LogViewXdrParser : public N_SST::IntegerCalculator
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
enum E_ParseState
|
||||
{
|
||||
e_ParseMain,
|
||||
e_ParseStruct,
|
||||
e_ParseEnum,
|
||||
e_ParseUnion
|
||||
};
|
||||
|
||||
|
||||
LogViewXdrParser();
|
||||
~LogViewXdrParser();
|
||||
|
||||
|
||||
|
||||
|
||||
void parseX_File(const QString& a_fileName);
|
||||
|
||||
|
||||
|
||||
QString getTelegramName(int a_telegramId) const;
|
||||
|
||||
|
||||
|
||||
QString getStructName(int a_telegramId) const;
|
||||
|
||||
|
||||
|
||||
bool getDefine(const QString& a_name, int64_t& a_value) const;
|
||||
|
||||
|
||||
|
||||
const LogViewXdrElement* getElement(const QString& a_name) const;
|
||||
|
||||
protected:
|
||||
|
||||
QString m_MessageBoxTitle;
|
||||
bool m_WithinComment;
|
||||
QString m_Line;
|
||||
uint32_t m_LineNbr;
|
||||
QString m_Filename;
|
||||
bool m_DoReadUntilSemicolon;
|
||||
QStringList m_WordList;
|
||||
int m_WordListIndex;
|
||||
|
||||
|
||||
QString m_UnionType;
|
||||
std::map<QString, LogViewXdrElement*> m_ElementMap;
|
||||
|
||||
LogViewXdrStruct *m_ActElement;
|
||||
|
||||
E_ParseState m_State;
|
||||
|
||||
std::map<QString, LogViewXdrValue> m_DefinesMap;
|
||||
|
||||
std::map<int, LogViewXdrType> m_TelegramMap;
|
||||
|
||||
|
||||
|
||||
void addStandardType(const QString& a_name,
|
||||
const uint16_t a_dataSize,
|
||||
const uint16_t a_realSize,
|
||||
const LogViewXdrStandardType::E_ValueKind a_kind,
|
||||
const LogViewXdrStandardType::E_DynArraySizeMethod a_dynArraySizeMethod = LogViewXdrStandardType::e_DynArrayMsgLength,
|
||||
const LogViewXdrStandardType::E_ByteOrder a_byteOrder = LogViewXdrStandardType::e_ByteOrderBigEndian);
|
||||
|
||||
|
||||
|
||||
QString removeComments(const QString& a_line);
|
||||
|
||||
|
||||
|
||||
void parseTypedef(const QString &a_line);
|
||||
|
||||
|
||||
|
||||
void parseDefine(const QString &a_line);
|
||||
|
||||
|
||||
|
||||
void parseEnum(const QString &a_line, const uint16_t a_enumSize = 4);
|
||||
|
||||
|
||||
|
||||
void parseStruct(const QString &a_line);
|
||||
|
||||
|
||||
|
||||
void parseUnion(const QString& a_line);
|
||||
|
||||
|
||||
|
||||
bool parseEnumLine(const QString& a_line, QString& a_name, QString& a_value) const;
|
||||
|
||||
|
||||
|
||||
void showErrorMessage(const QString& a_errorText) const;
|
||||
|
||||
|
||||
|
||||
int64_t calcValue(const QString& a_calcText, bool& a_isOk);
|
||||
|
||||
|
||||
|
||||
bool getVariableValue(const std::string& a_variableName, int64_t& a_value) const override;
|
||||
|
||||
|
||||
|
||||
uint16_t parseArray(QString& a_name, uint16_t& a_dynArrayMsgOffset) const;
|
||||
|
||||
|
||||
|
||||
bool isNextWord(const char *a_word, const bool a_doIncrement = true);
|
||||
|
||||
|
||||
|
||||
void fillWordList(const QString& a_line);
|
||||
|
||||
|
||||
|
||||
QString getNextWord(const char *a_errorText = nullptr);
|
||||
|
||||
|
||||
|
||||
QString getNextType(bool& a_ok);
|
||||
|
||||
|
||||
|
||||
QString getNextEnum(const LogViewXdrStruct*& a_enumStruct);
|
||||
|
||||
|
||||
|
||||
bool parseBitfield(const QString& a_fieldText, int16_t& a_firstBit, int16_t& a_lastBit) const;
|
||||
|
||||
|
||||
|
||||
bool addToElementMap(const QString& a_name, LogViewXdrElement* a_element);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewXdrStandardType.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LogViewXdrStandardType::LogViewXdrStandardType(const QString& a_name, const int a_valueSize,
|
||||
const int a_editSize, const E_ValueKind a_valueKind,
|
||||
const E_DynArraySizeMethod a_dynArraySizeMethod, E_ByteOrder a_byteOrder)
|
||||
: LogViewXdrElement(a_name, e_KindStandardType, "LogViewXdrStandardType")
|
||||
, m_ValueSize(a_valueSize)
|
||||
, m_EditSize(a_editSize)
|
||||
, m_ValueKind(a_valueKind)
|
||||
, m_ByteOrder(a_byteOrder)
|
||||
, m_DynArraySizeMethod(a_dynArraySizeMethod)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
uint16_t LogViewXdrStandardType::getValueSize() const
|
||||
{
|
||||
return m_ValueSize;
|
||||
}
|
||||
|
||||
|
||||
LogViewXdrStandardType::E_ValueKind LogViewXdrStandardType::getValueKind() const
|
||||
{
|
||||
return m_ValueKind;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewXdrStandardType::dump() const
|
||||
{
|
||||
INFO_LOG(m_logger) << "Element[" << getName()
|
||||
<< "]: kind=" << getKindName()
|
||||
<< " valueKind=" << getValueKind()
|
||||
<< " valueSize=" << getValueSize()
|
||||
<< " editSize=" << getEditSize()
|
||||
<< " dynArrSizeMethod=" << getDynArraySizeMethod()
|
||||
<< " byteOrder=" << getByteOrder();
|
||||
}
|
||||
|
||||
|
||||
LogViewXdrStandardType::E_DynArraySizeMethod LogViewXdrStandardType::getDynArraySizeMethod() const
|
||||
{
|
||||
return m_DynArraySizeMethod;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogViewXdrStandardType::E_ByteOrder LogViewXdrStandardType::getByteOrder() const
|
||||
{
|
||||
return m_ByteOrder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t LogViewXdrStandardType::getEditSize() const
|
||||
{
|
||||
return m_EditSize;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewXdrElement.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewXdrStandardType final : public LogViewXdrElement
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
enum E_ValueKind
|
||||
{
|
||||
|
||||
|
||||
e_Unsigned,
|
||||
|
||||
|
||||
e_Signed,
|
||||
|
||||
|
||||
e_Float,
|
||||
|
||||
|
||||
e_Character,
|
||||
|
||||
|
||||
e_Boolean,
|
||||
|
||||
|
||||
e_Data
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_ByteOrder
|
||||
{
|
||||
e_ByteOrderBigEndian,
|
||||
e_ByteOrderLittleEndian
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum E_DynArraySizeMethod
|
||||
{
|
||||
|
||||
|
||||
e_DynArrayMsgLength,
|
||||
|
||||
|
||||
e_DynArrayIndex,
|
||||
|
||||
|
||||
e_DynArrayIndexDiv8
|
||||
};
|
||||
|
||||
|
||||
|
||||
LogViewXdrStandardType(const QString &a_name,
|
||||
const int a_valueSize,
|
||||
const int a_editSize,
|
||||
const E_ValueKind a_valueKind,
|
||||
const E_DynArraySizeMethod a_dynArraySizeMethod,
|
||||
E_ByteOrder a_byteOrder);
|
||||
|
||||
|
||||
uint16_t getValueSize() const;
|
||||
|
||||
|
||||
LogViewXdrStandardType::E_ValueKind getValueKind() const;
|
||||
|
||||
|
||||
void dump() const override;
|
||||
|
||||
|
||||
LogViewXdrStandardType::E_DynArraySizeMethod getDynArraySizeMethod() const;
|
||||
|
||||
|
||||
LogViewXdrStandardType::E_ByteOrder getByteOrder() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getEditSize() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
int m_ValueSize;
|
||||
|
||||
|
||||
int m_EditSize;
|
||||
E_ValueKind m_ValueKind;
|
||||
|
||||
E_ByteOrder m_ByteOrder;
|
||||
|
||||
E_DynArraySizeMethod m_DynArraySizeMethod;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewXdrStruct.hpp"
|
||||
#include "LogViewXdrValue.hpp"
|
||||
#include "LogViewXdrType.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewXdrStruct::LogViewXdrStruct(const QString& a_name, const LogViewXdrElement::E_ElementKind a_kind, uint16_t enumSize)
|
||||
: LogViewXdrElement(a_name, a_kind, "LogViewXdrStruct")
|
||||
, m_EnumSize(enumSize)
|
||||
{
|
||||
}
|
||||
|
||||
LogViewXdrStruct::~LogViewXdrStruct()
|
||||
{
|
||||
for (auto ptr : m_ChildList)
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewXdrStruct::addElement(const QString& a_name, const QString& a_type, const uint16_t a_arraySize, const uint16_t a_dynArrayOffset, const E_ElementKind a_kind, const int16_t a_firstBit, const int16_t a_lastBit, const bool a_isLast)
|
||||
{
|
||||
m_ChildList.push_back(new LogViewXdrType(a_name, a_type, a_arraySize, a_dynArrayOffset, a_kind, a_firstBit, a_lastBit, a_isLast));
|
||||
}
|
||||
|
||||
|
||||
void LogViewXdrStruct::addElement(const QString& a_name, const uint32_t a_value, const E_ElementKind a_kind)
|
||||
{
|
||||
m_ChildList.push_back(new LogViewXdrValue(a_name, a_value, a_kind));
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogViewXdrElement* LogViewXdrStruct::getChild(const uint32_t a_childIndex) const
|
||||
{
|
||||
if (m_ChildList.size() > a_childIndex)
|
||||
return m_ChildList[a_childIndex];
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogViewXdrType* LogViewXdrStruct::getChildAsType(const uint32_t a_childIndex) const
|
||||
{
|
||||
return static_cast<LogViewXdrType*>(getChild(a_childIndex));
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogViewXdrValue* LogViewXdrStruct::getChildAsValue(const uint32_t a_childIndex) const
|
||||
{
|
||||
return static_cast<LogViewXdrValue*>(getChild(a_childIndex));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewXdrStruct::dump() const
|
||||
{
|
||||
INFO_LOG(m_logger) << "Element[" << getName().toStdString() << "]: kind=" << getKindName().toStdString() << " enumSize=" << getEnumSize();
|
||||
INFO_LOG(m_logger) << "-------------- childs start -----------------";
|
||||
|
||||
std::vector<LogViewXdrElement*>::const_iterator iter = m_ChildList.begin();
|
||||
while (iter != m_ChildList.end())
|
||||
{
|
||||
(*iter)->dump();
|
||||
++iter;
|
||||
}
|
||||
INFO_LOG(m_logger) << "-------------- childs end -----------------";
|
||||
}
|
||||
|
||||
|
||||
uint32_t LogViewXdrStruct::getChildValue(const QString& a_name, bool* a_error) const
|
||||
{
|
||||
if (a_error)
|
||||
*a_error = false;
|
||||
std::vector<LogViewXdrElement*>::const_iterator iter = m_ChildList.begin();
|
||||
while (iter != m_ChildList.end())
|
||||
{
|
||||
if ((*iter)->getName() == a_name)
|
||||
return static_cast<const LogViewXdrValue*>(*iter)->getValue();
|
||||
++iter;
|
||||
}
|
||||
if (a_error)
|
||||
*a_error = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include "LogViewXdrElement.hpp"
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewXdrValue;
|
||||
}
|
||||
namespace N_LogView
|
||||
{
|
||||
class LogViewXdrType;
|
||||
}
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewXdrStruct final : public LogViewXdrElement
|
||||
{
|
||||
public:
|
||||
LogViewXdrStruct(const QString& a_name, const LogViewXdrElement::E_ElementKind a_kind, uint16_t enumSize = 0);
|
||||
~LogViewXdrStruct();
|
||||
|
||||
void addElement(const QString& a_name, const QString& a_type, const uint16_t a_arraySize, const uint16_t a_dynArrayOffset, const E_ElementKind a_kind, const int16_t a_firstBit = -1, const int16_t a_lastBit = -1, const bool a_isLast = true);
|
||||
void addElement(const QString& a_name, const uint32_t a_value, const E_ElementKind a_kind);
|
||||
|
||||
LogViewXdrElement* getChild(const uint32_t a_childIndex) const;
|
||||
LogViewXdrType* getChildAsType(const uint32_t a_childIndex) const;
|
||||
LogViewXdrValue* getChildAsValue(const uint32_t a_childIndex) const;
|
||||
|
||||
|
||||
void dump() const override;
|
||||
|
||||
uint32_t getChildValue(const QString& a_name, bool* a_error = nullptr) const;
|
||||
uint16_t getEnumSize() const { return m_EnumSize; }
|
||||
|
||||
protected:
|
||||
|
||||
uint16_t m_EnumSize;
|
||||
std::vector<LogViewXdrElement*> m_ChildList;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewXdrType.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewXdrType::LogViewXdrType(const QString& a_name, const QString& a_type, const uint16_t a_arraySize, const uint16_t a_dynArrayOffset, const E_ElementKind a_kind)
|
||||
: LogViewXdrElement(a_name, a_kind, "LogViewXdrElement")
|
||||
, m_Type(a_type)
|
||||
, m_ArraySize(a_arraySize)
|
||||
, m_MaxArraySize(a_dynArrayOffset)
|
||||
, m_FirstBit(-1)
|
||||
, m_LastBit(-1)
|
||||
, m_IsLast(true)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogViewXdrType::LogViewXdrType(const QString& a_name, const QString& a_type, const uint16_t a_arraySize, const uint16_t a_dynArrayOffset, const E_ElementKind a_kind, const int16_t a_firstBit, const int16_t a_lastBit, const bool a_isLast)
|
||||
: LogViewXdrElement(a_name, a_kind, "LogViewXdrType")
|
||||
, m_Type(a_type)
|
||||
, m_ArraySize(a_arraySize)
|
||||
, m_MaxArraySize(a_dynArrayOffset)
|
||||
, m_FirstBit(a_firstBit)
|
||||
, m_LastBit(a_lastBit)
|
||||
, m_IsLast(a_isLast)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LogViewXdrType::dump() const
|
||||
{
|
||||
INFO_LOG(m_logger) << "Element[" << getName()
|
||||
<< "]: kind=" << getKindName()
|
||||
<< " type=" << getType()
|
||||
<< " arraySize=" << getArraySize()
|
||||
<< " maxArraySize=" << getMaxArraySize()
|
||||
<< " firstBit=" << m_FirstBit
|
||||
<< " lastBit=" << m_LastBit
|
||||
<< " isLast=" << m_IsLast;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const QString& LogViewXdrType::getType() const
|
||||
{
|
||||
return m_Type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
uint16_t LogViewXdrType::getArraySize() const
|
||||
{
|
||||
return m_ArraySize;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool LogViewXdrType::maskValue(uint32_t& a_value, const uint16_t a_size, QString& a_tooltip) const
|
||||
{
|
||||
|
||||
if (m_FirstBit != -1 && m_LastBit != -1)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "MaskValue for Element " << m_Name
|
||||
<< " type: " << m_Type
|
||||
<< " size: " << m_ArraySize
|
||||
<< " first:last " << m_FirstBit << ":" << m_LastBit
|
||||
<< " isLast: " << m_IsLast;
|
||||
uint16_t bitshift = (a_size*8)-m_LastBit-1;
|
||||
uint32_t mask = (1<<(m_LastBit-m_FirstBit+1))-1;
|
||||
|
||||
a_value = (a_value >> bitshift) & mask;
|
||||
|
||||
a_tooltip.insert(a_tooltip.length()-(a_size*8)+m_FirstBit, QLatin1String("<b>"));
|
||||
a_tooltip.insert(a_tooltip.length()-(a_size*8)+m_LastBit+1, QLatin1String("</b>"));
|
||||
return m_IsLast;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t LogViewXdrType::getMaxArraySize() const
|
||||
{
|
||||
return m_MaxArraySize;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewXdrElement.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewXdrType final : public LogViewXdrElement
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
|
||||
LogViewXdrType(const QString& a_name, const QString& a_type, const uint16_t a_arraySize, const uint16_t a_dynArrayOffset, const E_ElementKind a_kind);
|
||||
|
||||
|
||||
|
||||
LogViewXdrType(const QString& a_name, const QString& a_type, const uint16_t a_arraySize, const uint16_t a_dynArrayOffset, const E_ElementKind a_kind, const int16_t a_firstBit, const int16_t a_lastBit, const bool a_isLast);
|
||||
|
||||
|
||||
void dump() const override;
|
||||
|
||||
|
||||
const QString& getType() const;
|
||||
|
||||
|
||||
|
||||
uint16_t getArraySize() const;
|
||||
|
||||
|
||||
|
||||
bool maskValue(uint32_t& a_value, const uint16_t a_size, QString& a_tooltip) const;
|
||||
|
||||
|
||||
uint16_t getMaxArraySize() const;
|
||||
|
||||
protected:
|
||||
|
||||
QString m_Type;
|
||||
|
||||
|
||||
uint16_t m_ArraySize;
|
||||
|
||||
|
||||
uint16_t m_MaxArraySize;
|
||||
|
||||
|
||||
int16_t m_FirstBit;
|
||||
|
||||
|
||||
int16_t m_LastBit;
|
||||
|
||||
|
||||
bool m_IsLast;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LogViewXdrValue.hpp"
|
||||
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
LogViewXdrValue::LogViewXdrValue(const QString& a_name, const int64_t a_value, const LogViewXdrElement::E_ElementKind a_kind)
|
||||
: LogViewXdrElement(a_name, a_kind, "LogViewXdrValue")
|
||||
, m_Value(a_value)
|
||||
{}
|
||||
|
||||
|
||||
|
||||
void LogViewXdrValue::dump() const
|
||||
{
|
||||
INFO_LOG(m_logger) << "Element[" << getName() << "]: kind=" << getKindName() << " value=" << getValue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
int64_t LogViewXdrValue::getValue() const
|
||||
{
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "LogViewXdrElement.hpp"
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
|
||||
class LogViewXdrValue final : public LogViewXdrElement
|
||||
{
|
||||
public:
|
||||
LogViewXdrValue(const QString& a_name, const int64_t a_value, const LogViewXdrElement::E_ElementKind a_kind);
|
||||
|
||||
void dump() const override;
|
||||
int64_t getValue() const;
|
||||
|
||||
protected:
|
||||
|
||||
int64_t m_Value;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=INFO, C
|
||||
log4j.rootLogger=INFO, F
|
||||
|
||||
log4j.appender.C=org.apache.log4j.ConsoleAppender
|
||||
|
||||
log4j.appender.F=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.F.File=${LOG4QT_LOGDIR}/${LOG4QT_USER}_LogView.log
|
||||
|
||||
log4j.appender.F.MaxFileSize=10MB
|
||||
# Keep one backup file
|
||||
log4j.appender.F.MaxBackupIndex=5
|
||||
|
||||
log4j.appender.C.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.F.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.C.layout.ConversionPattern=%-5p (%-20.20F:%04L) [%d{HH:mm:ss.SSS}] - %m%n
|
||||
log4j.appender.F.layout.ConversionPattern=%-5p (%-20.20F:%04L) [%d{HH:mm:ss.SSS}] - %m%n
|
||||
|
After Width: | Height: | Size: 287 B |
|
After Width: | Height: | Size: 191 B |
|
After Width: | Height: | Size: 586 B |
|
After Width: | Height: | Size: 534 B |
|
After Width: | Height: | Size: 275 B |
|
After Width: | Height: | Size: 288 B |
|
After Width: | Height: | Size: 188 B |
|
After Width: | Height: | Size: 801 B |
|
After Width: | Height: | Size: 382 B |
|
After Width: | Height: | Size: 278 B |
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 307 B |
|
After Width: | Height: | Size: 186 B |
|
After Width: | Height: | Size: 191 B |
|
After Width: | Height: | Size: 586 B |
|
After Width: | Height: | Size: 543 B |
@@ -0,0 +1,32 @@
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "LogView.";
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace N_LogView
|
||||
{
|
||||
typedef NGL::INGLLogger &LOGGER_T;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
zsksxd_tetraForLogView.x
|
||||
@@ -0,0 +1 @@
|
||||
zsksxd_tetraForLogView_guez.x
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include "AppComponent.hpp"
|
||||
|
||||
namespace N_AppComponent
|
||||
{
|
||||
|
||||
int32_t AppComponent::create(NGL::Settings *settings)
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
c->create(settings);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t AppComponent::destroy()
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
c->destroy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t AppComponent::init()
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
c->init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t AppComponent::deinit()
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
c->deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t AppComponent::start()
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
c->start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int32_t AppComponent::stop()
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
c->stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void AppComponent::addChild(IAppComponent *a_child, const QString &a_name)
|
||||
{
|
||||
if (a_child)
|
||||
{
|
||||
a_child->setName(a_name);
|
||||
m_Childs.push_back(a_child);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
IAppComponent *AppComponent::getChild(const QString &a_name)
|
||||
{
|
||||
for (IAppComponent *c : m_Childs)
|
||||
{
|
||||
if (a_name == c->getName())
|
||||
return c;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "IAppComponent.hpp"
|
||||
#include <PrtCnv/prtcnvlib_export.h>
|
||||
|
||||
namespace NGL {
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace N_AppComponent
|
||||
{
|
||||
class PRTCNVLIB_EXPORT AppComponent : public N_AppComponent::IAppComponent
|
||||
{
|
||||
public:
|
||||
AppComponent() = default;
|
||||
~AppComponent() = default;
|
||||
|
||||
|
||||
int32_t create(NGL::Settings *settings) override;
|
||||
int32_t deinit() override;
|
||||
int32_t destroy() override;
|
||||
int32_t init() override;
|
||||
int32_t start() override;
|
||||
int32_t stop() override;
|
||||
|
||||
protected:
|
||||
void addChild(IAppComponent* a_child, const QString& a_name = QString());
|
||||
IAppComponent* getChild(const QString& a_name);
|
||||
private:
|
||||
std::vector<IAppComponent*> m_Childs;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
|
||||
#ADD_SUBDIRECTORY(TetraTestServer)
|
||||
ADD_SUBDIRECTORY(LastTest)
|
||||
ADD_SUBDIRECTORY(LastTestAuswertung)
|
||||
|
||||
SET(PrtCnv_SRCS
|
||||
logger.h
|
||||
logger.cpp
|
||||
|
||||
AppComponent.cpp
|
||||
AppComponent.hpp
|
||||
IAppComponent.hpp
|
||||
PrtCnvApplication.cpp
|
||||
PrtCnvApplication.hpp
|
||||
PrtCnvBroadcastMgr.cpp
|
||||
PrtCnvBroadcastMgr.hpp
|
||||
PrtCnvCentralThread.cpp
|
||||
PrtCnvCentralThread.hpp
|
||||
PrtCnvDbThread.cpp
|
||||
PrtCnvDbThread.hpp
|
||||
PrtCnvInjectionSocket.cpp
|
||||
PrtCnvInjectionSocket.hpp
|
||||
PrtCnvInjectionThread.cpp
|
||||
PrtCnvInjectionThread.hpp
|
||||
PrtCnvMember.cpp
|
||||
PrtCnvMember.hpp
|
||||
PrtCnvRadioThread.cpp
|
||||
PrtCnvRadioThread.hpp
|
||||
PrtCnvRadioTrafficThread.cpp
|
||||
PrtCnvRadioTrafficThread.hpp
|
||||
PrtCnvSocketThread.cpp
|
||||
PrtCnvSocketThread.hpp
|
||||
PrtCnvStoredCentralTelegram.hpp
|
||||
PrtCnvStoredRadioTelegram.hpp
|
||||
PrtCnvStoredTelegram.hpp
|
||||
PrtCnvTelegramLogThread.cpp
|
||||
PrtCnvTelegramLogThread.hpp
|
||||
PrtCnvThread.cpp
|
||||
PrtCnvThread.hpp
|
||||
PrtCnvThreadStarter.cpp
|
||||
PrtCnvThreadStarter.hpp
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(AAR SV PrtCnvLib SHARED ${PrtCnv_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(PrtCnvLib
|
||||
PRIVATE
|
||||
ngldb
|
||||
nglsettings
|
||||
LtsUtilsCoreHeaderOnly
|
||||
Qt5::Sql
|
||||
Qt5::WebSockets
|
||||
PUBLIC
|
||||
CoPrtCnv
|
||||
Qt5::Core
|
||||
Qt5::Network
|
||||
NGLLogger
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(PrtCnvLib
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
|
||||
NGL_ADD_EXECUTABLE(AAR SV PrtCnv PrtCnvMain.cpp)
|
||||
NGL_TARGET_LINK_LIBRARIES(PrtCnv
|
||||
PrtCnvLib
|
||||
Qt5::Core
|
||||
LtsCommandLineParser
|
||||
nglcoreapplication
|
||||
)
|
||||
NGL_INSTALL_TARGET(PrtCnv)
|
||||
NGL_INSTALL(AAR SV FILES log4cxx_prtcnv.props DESTINATION bin)
|
||||
NGL_INSTALL(AAR SV FILES PrtCnv.dat.tts DESTINATION bin)
|
||||
@@ -0,0 +1,59 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QString>
|
||||
|
||||
namespace NGL {
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace N_AppComponent
|
||||
{
|
||||
class IAppComponent
|
||||
{
|
||||
public:
|
||||
IAppComponent() = default;
|
||||
virtual ~IAppComponent() = default;
|
||||
|
||||
virtual int32_t create(NGL::Settings *settings) = 0;
|
||||
|
||||
|
||||
virtual int32_t deinit() = 0;
|
||||
|
||||
|
||||
virtual int32_t destroy() = 0;
|
||||
|
||||
|
||||
virtual int32_t init() = 0;
|
||||
|
||||
|
||||
virtual int32_t start() = 0;
|
||||
|
||||
|
||||
virtual int32_t stop() = 0;
|
||||
|
||||
|
||||
inline const QString& getName() const
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
inline void setName(const QString& newVal)
|
||||
{
|
||||
m_Name = newVal;
|
||||
}
|
||||
protected:
|
||||
QString m_Name;
|
||||
};
|
||||
|
||||
}
|
||||