Prune the source tree to the Release 2 build closure
Keep only what the Release 2 scope (46 targets) compiles and the build pipeline needs, derived from the run-5 build.ninja closure (46 targets + transitive deps) and a header scan resolved against the real -I roots of the compile rules: - 14133 tracked files removed (1.25 GB), incl. include/ArcGIS (1.03 GB), include/rti stubs (identical copies of the external RTI headers), out-of-scope Lts/Application, Lts/Viewer, Lts/Services/*, Lts/Tools generators, src/, tests/, specs/, translations/, external/ - kept: the 46 scope modules + their transitive service deps, codegen inputs (.xml, .grantlee), doxygen/ (configure_file at configure time), include/GeographicLib (libGeographicLib.so linked from the source tree), the 12 referenced include/ stub headers, pipeline files (new_docker_build_release2.sh, rpmbuild/, jenkins-ci-rme/, cmake/) - 7 CMakeLists updated: drop add_subdirectory calls of the removed dirs (tests, translations, Lts/Plugins/ProjectDataManagement, qav, scripts, CommonUnitTestsPlaceholder, httq, LtsRestClient, LtsWebSocket, TopicEditorBase, ConnectDialog, StyleManager, Routing, DdsUnitTests, DdsUnitTestsPlaceholder, Light, Dark, Test, ExerciseManagement, ParticipantManagement, the 3 tools generators) Result: 2157 tracked files (was 16290).
This commit is contained in:
1 parent
2b1c3dc241
commit
7fc6f66649
14140 files changed
+8
-2803418
No files matched your search
@@ -1058,7 +1058,6 @@ IF(BUILD_ALL)
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF(BUILD_RPM)
|
IF(BUILD_RPM)
|
||||||
ADD_SUBDIRECTORY(scripts)
|
|
||||||
ELSE()
|
ELSE()
|
||||||
ADD_DEFINITIONS(-DLTS_DEBUG)
|
ADD_DEFINITIONS(-DLTS_DEBUG)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
@@ -1106,28 +1105,11 @@ NGL_ADD_SUBDIR_GUARDED(Z/src)
|
|||||||
# Services are included before plugins via Lts/CMakeLists.txt (LTS_SUBDIRS order)
|
# Services are included before plugins via Lts/CMakeLists.txt (LTS_SUBDIRS order)
|
||||||
NGL_ADD_SUBDIR_GUARDED(Lts)
|
NGL_ADD_SUBDIR_GUARDED(Lts)
|
||||||
|
|
||||||
# Add migration tests - skip when MIGRATE_MODULE targets specific Lts modules (tests need full codebase)
|
# TrainingAreaBase is included via Lts/Proxies when Lts is processed.
|
||||||
# MUST be after Lts configuration so tests can access Lts targets (LtsTimelineClassic, codegen_base, etc.)
|
# (Out-of-scope dirs tests/, translations/ and Lts/Plugins/ProjectDataManagement
|
||||||
if(NOT DEFINED MIGRATE_MODULE OR MIGRATE_MODULE STREQUAL "" OR MIGRATE_MODULE STREQUAL "tests")
|
# were removed from this branch; their add_subdirectory calls are gone with them.)
|
||||||
ADD_SUBDIRECTORY(tests)
|
|
||||||
else()
|
|
||||||
message(STATUS "MIGRATE_MODULE=${MIGRATE_MODULE} - skipping tests (need full codebase)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# TrainingAreaBase is included via Lts/Proxies when Lts is processed
|
|
||||||
# Special-case: when migrating TetraIF, also include ProjectDataManagement so generated headers
|
|
||||||
# and internal logger target are available in the same build tree for TetraIF dependents.
|
|
||||||
if(DEFINED MIGRATE_MODULE AND MIGRATE_MODULE STREQUAL "TetraIF")
|
|
||||||
message(STATUS "Including helper modules for TetraIF migration: Lts/Plugins/ProjectDataManagement")
|
|
||||||
# Services already included above when BUILD_RTI=ON
|
|
||||||
add_subdirectory(Lts/Plugins/ProjectDataManagement)
|
|
||||||
endif()
|
|
||||||
# at last, to make sure we get all targets in NGL_TS_TARGETS property
|
|
||||||
NGL_ADD_SUBDIR_GUARDED(translations)
|
|
||||||
#-----------------------------------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
# QAV analysis script dir (qav/) is not part of this branch.
|
||||||
OPTION(BUILD_QAV "Build script for local QAV analysis" OFF)
|
OPTION(BUILD_QAV "Build script for local QAV analysis" OFF)
|
||||||
IF (BUILD_QAV)
|
|
||||||
ADD_SUBDIRECTORY(qav)
|
|
||||||
ENDIF()
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Hanna Rathje, SLSE, 2017-12-14
|
|
||||||
#
|
|
||||||
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
SET(SRCS
|
|
||||||
aar_application.cpp
|
|
||||||
aar_application.h
|
|
||||||
databases_model.cpp
|
|
||||||
databases_model.h
|
|
||||||
logger.cpp
|
|
||||||
logger.h
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_WRAP_UI(SRCS aarApp.ui)
|
|
||||||
|
|
||||||
NGL_ADD_EXECUTABLE(AAR aarApp ${SRCS})
|
|
||||||
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(aarApp
|
|
||||||
${Qt6_Widgets}
|
|
||||||
Qt6::Core
|
|
||||||
nglapplication
|
|
||||||
ngldb
|
|
||||||
nglcoreapplication
|
|
||||||
ngltools
|
|
||||||
ngltranslator
|
|
||||||
nglwidgets
|
|
||||||
NGLLogger
|
|
||||||
LtsCommandLineParser
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
NGL_INSTALL_TARGET(aarApp)
|
|
||||||
NGL_INSTALL(AAR FILES log4cxx_aarApp.props DESTINATION bin)
|
|
||||||
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>AarApplication</class>
|
|
||||||
<widget class="QMainWindow" name="AarApplication">
|
|
||||||
<property name="windowModality">
|
|
||||||
<enum>Qt::WindowModal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>846</width>
|
|
||||||
<height>382</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Database administration</string>
|
|
||||||
</property>
|
|
||||||
<property name="statusTip">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="toolButtonStyle">
|
|
||||||
<enum>Qt::ToolButtonIconOnly</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tabShape">
|
|
||||||
<enum>QTabWidget::Rounded</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="centralWidget">
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Status:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblStatus">
|
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<weight>75</weight>
|
|
||||||
<bold>true</bold>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>No active database</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblDatabases">
|
|
||||||
<property name="text">
|
|
||||||
<string>Databases:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QTableView" name="tableViewDatabases">
|
|
||||||
<property name="alternatingRowColors">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="selectionMode">
|
|
||||||
<enum>QAbstractItemView::SingleSelection</enum>
|
|
||||||
</property>
|
|
||||||
<property name="selectionBehavior">
|
|
||||||
<enum>QAbstractItemView::SelectRows</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sortingEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<attribute name="verticalHeaderVisible">
|
|
||||||
<bool>false</bool>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pbActivateNetwork">
|
|
||||||
<property name="text">
|
|
||||||
<string>Activate network database</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pbActivate">
|
|
||||||
<property name="text">
|
|
||||||
<string>Activate local database</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pbRemove">
|
|
||||||
<property name="text">
|
|
||||||
<string>Remove database</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pbClose">
|
|
||||||
<property name="text">
|
|
||||||
<string>Close</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<action name="actionShow">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Show</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionStart">
|
|
||||||
<property name="text">
|
|
||||||
<string>&Start</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionStop">
|
|
||||||
<property name="text">
|
|
||||||
<string>St&op</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
</widget>
|
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
<slots>
|
|
||||||
<slot>oeffnenClicked()</slot>
|
|
||||||
</slots>
|
|
||||||
</ui>
|
|
||||||
@@ -1,502 +0,0 @@
|
|||||||
/*
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* <short description>
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Malte Schröder, SLSE, 2016-06-08
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "aar_application.h"
|
|
||||||
#include <utility>
|
|
||||||
#include "ui_aarApp.h"
|
|
||||||
#include "databases_model.h"
|
|
||||||
|
|
||||||
#include <ngldb/dbconnection.h>
|
|
||||||
#include <ngldb/nsqlquery.h>
|
|
||||||
#include <nglsettings/nglsettings_settings.h>
|
|
||||||
#include <ngltools/ngltools_filesystem.h>
|
|
||||||
|
|
||||||
#include <QtWidgets/QMessageBox>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QtWidgets/QMenu>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QtCore/QDir>
|
|
||||||
#include <QtCore/QThread>
|
|
||||||
#include <QScreen>
|
|
||||||
#include <QSqlError>
|
|
||||||
|
|
||||||
#define DEFAULT_DB "lts_ets_pro"
|
|
||||||
|
|
||||||
namespace AARApplication
|
|
||||||
{
|
|
||||||
|
|
||||||
AarApplication::AarApplication(QWidget *parent)
|
|
||||||
: QMainWindow(parent)
|
|
||||||
, m_ui(new Ui::AarApplication)
|
|
||||||
, m_stopping(false)
|
|
||||||
, m_proc(nullptr)
|
|
||||||
, m_progressDialog(nullptr)
|
|
||||||
, m_logger(getLogger("AarApplication"))
|
|
||||||
{
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
|
|
||||||
const QList<QScreen*> &screenList = QGuiApplication::screens();
|
|
||||||
m_widgets.reserve(screenList.size());
|
|
||||||
for (QScreen *s : std::as_const(screenList))
|
|
||||||
{
|
|
||||||
QWidget *w = new QWidget(); // no parent
|
|
||||||
w->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
|
||||||
w->setGeometry(s->geometry());
|
|
||||||
w->activateWindow();
|
|
||||||
w->show();
|
|
||||||
m_widgets.append(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_databasesModel = new DatabasesModel(this);
|
|
||||||
m_proxyModel = new DatabasesProxyModel(this);
|
|
||||||
m_proxyModel->setSourceModel(m_databasesModel);
|
|
||||||
m_ui->tableViewDatabases->setModel(m_proxyModel);
|
|
||||||
|
|
||||||
connect(m_ui->pbClose, &QPushButton::clicked, this, &AarApplication::onClosedClicked);
|
|
||||||
connect(m_ui->pbRemove, &QPushButton::clicked, this, &AarApplication::onRemoveClicked);
|
|
||||||
connect(m_ui->pbActivate, &QPushButton::clicked, this, &AarApplication::onActivateClicked);
|
|
||||||
connect(m_ui->pbActivateNetwork, &QPushButton::clicked, this, &AarApplication::onActivateNetworkClicked);
|
|
||||||
|
|
||||||
connect(m_ui->tableViewDatabases->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AarApplication::enaDisa);
|
|
||||||
|
|
||||||
setWindowTitle(QLatin1String("AarApplication"));
|
|
||||||
|
|
||||||
enaDisa();
|
|
||||||
|
|
||||||
m_progressDialog = new QProgressDialog(this);
|
|
||||||
|
|
||||||
m_progressDialog->setLabelText(tr("Stopping server software ..."));
|
|
||||||
m_progressDialog->setMinimum(0);
|
|
||||||
m_progressDialog->setMaximum(0);
|
|
||||||
m_progressDialog->show();
|
|
||||||
onStopApp();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
AarApplication::~AarApplication()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
delete m_databasesModel;
|
|
||||||
delete m_progressDialog;
|
|
||||||
|
|
||||||
for (QSqlDatabase db : std::as_const(m_dbMap))
|
|
||||||
db.close();
|
|
||||||
|
|
||||||
m_dbPostgres.close();
|
|
||||||
|
|
||||||
if (m_proc)
|
|
||||||
m_proc->deleteLater();
|
|
||||||
|
|
||||||
qDeleteAll(m_widgets);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AarApplication::init()
|
|
||||||
{
|
|
||||||
m_ui->lblStatus->setText(tr("No active database"));
|
|
||||||
|
|
||||||
m_dbPostgres = DBConnection::open(m_logger,
|
|
||||||
QStringLiteral("postgres"),
|
|
||||||
QStringLiteral("postgres"),
|
|
||||||
QStringLiteral("QPSQL"),
|
|
||||||
QStringLiteral("localhost"),
|
|
||||||
QStringLiteral("postgres"),
|
|
||||||
QString(),
|
|
||||||
QStringLiteral("localhost_postgres"));
|
|
||||||
|
|
||||||
if (!m_dbPostgres.open())
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error opening postgres database" << m_dbPostgres.lastError().databaseText();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSqlQuery q(m_dbPostgres);
|
|
||||||
|
|
||||||
QString stmt = QStringLiteral("SELECT datname FROM pg_database WHERE datname = '") + QStringLiteral(DEFAULT_DB) + QStringLiteral("'");
|
|
||||||
|
|
||||||
if (!q.execAndFetch(stmt))
|
|
||||||
{
|
|
||||||
NOTICE_LOG(m_logger) << "Database does not exist: " << DEFAULT_DB;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QSqlDatabase db_lts = DBConnection::open(m_logger,
|
|
||||||
QStringLiteral("ctc_sv"),
|
|
||||||
QStringLiteral("ctc11de"),
|
|
||||||
QStringLiteral("QPSQL"),
|
|
||||||
QStringLiteral("localhost"),
|
|
||||||
QStringLiteral(DEFAULT_DB),
|
|
||||||
QString(),
|
|
||||||
QStringLiteral("localhost_")+QStringLiteral(DEFAULT_DB));
|
|
||||||
|
|
||||||
if (!db_lts.open())
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error opening database " << DEFAULT_DB << " : "<< db_lts.lastError().databaseText();
|
|
||||||
m_dbPostgres.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSqlQuery ql(db_lts);
|
|
||||||
|
|
||||||
stmt = QStringLiteral("SELECT id FROM exm.exercise");
|
|
||||||
|
|
||||||
if (!ql.execAndFetch(stmt))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "No entry for exercise found in database " << DEFAULT_DB;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int dbId = ql.value(0).toInt();
|
|
||||||
db_lts.close();
|
|
||||||
|
|
||||||
QString dbName = QStringLiteral("lts_db_") + QString::number(dbId);
|
|
||||||
INFO_LOG(m_logger) << "New dbName for " << DEFAULT_DB << ": " << dbName;
|
|
||||||
|
|
||||||
stmt = QStringLiteral("ALTER DATABASE ") + QStringLiteral(DEFAULT_DB) + QStringLiteral(" RENAME TO ") + dbName;
|
|
||||||
|
|
||||||
if (!q.exec(stmt))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error renaming database " << DEFAULT_DB << " : " << db_lts.lastError().databaseText();
|
|
||||||
m_dbPostgres.close();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stmt = QStringLiteral("SELECT datname FROM pg_database WHERE datname ilike 'lts_db_%';");
|
|
||||||
|
|
||||||
if (!q.exec(stmt))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error while reading dbnames from database";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (q.next())
|
|
||||||
{
|
|
||||||
QString dbName = q.value(0).toString();
|
|
||||||
QSqlDatabase db = DBConnection::open(m_logger,
|
|
||||||
QStringLiteral("ctc_sv"),
|
|
||||||
QStringLiteral("ctc11de"),
|
|
||||||
QStringLiteral("QPSQL"),
|
|
||||||
QStringLiteral("localhost"),
|
|
||||||
dbName,
|
|
||||||
QString(),
|
|
||||||
QStringLiteral("localhost_") + dbName);
|
|
||||||
|
|
||||||
if (!db.open())
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error while opening database " << dbName << ", error: " << db.lastError().databaseText();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_databasesModel->initModel(db);
|
|
||||||
m_dbMap.insert(dbName, db);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ui->tableViewDatabases->resizeColumnsToContents();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onClosedClicked()
|
|
||||||
{
|
|
||||||
handleProcInit(QStringLiteral("/usr/bin/openbox"), {QStringLiteral("--exit")});
|
|
||||||
m_proc->start();
|
|
||||||
m_proc->waitForFinished();
|
|
||||||
QThread::sleep(2);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onRemoveClicked()
|
|
||||||
{
|
|
||||||
disableButtons();
|
|
||||||
|
|
||||||
m_databaseToRemove = m_databasesModel->getRowData(m_ui->tableViewDatabases->currentIndex().row());
|
|
||||||
|
|
||||||
QString strMsg = QStringLiteral("Do you really want to remove the database '%1'?").arg (m_databaseToRemove.dbName);
|
|
||||||
int result = QMessageBox::question(this, tr("Remove Database"), strMsg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
|
||||||
if (result == QMessageBox::No)
|
|
||||||
{
|
|
||||||
enableButtons();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "onRemoveClicked: dbName = " << m_databaseToRemove.dbName;
|
|
||||||
QSqlDatabase db = m_dbMap.value(m_databaseToRemove.dbName);
|
|
||||||
db.close();
|
|
||||||
|
|
||||||
const QStringList args({QStringLiteral("-U"),
|
|
||||||
QStringLiteral("postgres"),
|
|
||||||
QStringLiteral("-h"),
|
|
||||||
QStringLiteral("localhost"),
|
|
||||||
m_databaseToRemove.dbName
|
|
||||||
});
|
|
||||||
|
|
||||||
QString errStr;
|
|
||||||
const QString exePath = NGL::postgresExecutablePath(QStringLiteral("dropdb"), errStr);
|
|
||||||
if (!errStr.isEmpty())
|
|
||||||
WARNING_LOG(m_logger) << errStr;
|
|
||||||
|
|
||||||
handleProcInit(exePath, args);
|
|
||||||
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
||||||
this, &AarApplication::onDropDbFinished);
|
|
||||||
|
|
||||||
// start process
|
|
||||||
m_proc->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onActivateClicked()
|
|
||||||
{
|
|
||||||
const QString fileName = QStringLiteral("/shd/CTC/WS/lts-cc.conf.org");
|
|
||||||
|
|
||||||
WARNING_LOG(m_logger) << "FileName: " << fileName;
|
|
||||||
QFile ltsConfig(fileName);
|
|
||||||
|
|
||||||
if (ltsConfig.exists())
|
|
||||||
ltsConfig.rename(QStringLiteral("/shd/CTC/WS/lts-cc.conf.org"), QStringLiteral("/shd/CTC/WS/lts-cc.conf"));
|
|
||||||
|
|
||||||
Exercise ex = m_databasesModel->getRowData(m_ui->tableViewDatabases->currentIndex().row());
|
|
||||||
|
|
||||||
QString strMsg = tr("Do you really want to activate database '%1'?").arg(ex.name);
|
|
||||||
int result = QMessageBox::question(this, tr("Activate local database"), strMsg, QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
|
||||||
if (result == QMessageBox::No)
|
|
||||||
return;
|
|
||||||
|
|
||||||
INFO_LOG(m_logger) << "onActivateClicked: dbName = " << ex.dbName;
|
|
||||||
|
|
||||||
QSqlDatabase db = m_dbMap.value(ex.dbName);
|
|
||||||
db.close();
|
|
||||||
|
|
||||||
NSqlQuery q(m_dbPostgres);
|
|
||||||
|
|
||||||
QString stmt = QStringLiteral("ALTER DATABASE ") + ex.dbName + QStringLiteral(" RENAME TO ") + QStringLiteral(DEFAULT_DB);
|
|
||||||
|
|
||||||
if (!q.exec(stmt))
|
|
||||||
ERROR_LOG(m_logger) << "Error renaming " << ex.dbName << " to " << DEFAULT_DB << " "<< m_dbPostgres.lastError().databaseText();
|
|
||||||
else
|
|
||||||
INFO_LOG(m_logger) << "Database " << ex.dbName << " renamed to " << DEFAULT_DB;
|
|
||||||
|
|
||||||
QString status = ex.name + QStringLiteral(" (") + ex.dbName + QStringLiteral(") ") + tr("active");
|
|
||||||
m_ui->lblStatus->setText(status);
|
|
||||||
onStartApp();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onActivateNetworkClicked()
|
|
||||||
{
|
|
||||||
onStopApp();
|
|
||||||
//const QString fileName = QDir::homePath()+ QStringLiteral("/lts-cc.conf");
|
|
||||||
|
|
||||||
const QString fileName = QStringLiteral("/shd/CTC/WS") + QStringLiteral("/lts-cc.conf");
|
|
||||||
|
|
||||||
WARNING_LOG(m_logger) << "FileName: " << fileName;
|
|
||||||
QFile ltsConfig(fileName);
|
|
||||||
|
|
||||||
if (!ltsConfig.exists())
|
|
||||||
{
|
|
||||||
QMessageBox::critical(this, tr ("Activate network database"), tr("Network database active"), QMessageBox::Ok);
|
|
||||||
m_ui->lblStatus->setText(tr("Network database active"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ltsConfig.rename(QStringLiteral("/shd/CTC/WS/lts-cc.conf"), QStringLiteral("/shd/CTC/WS/lts-cc.conf.org"));
|
|
||||||
m_ui->lblStatus->setText(tr("Network database active"));
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::enaDisa()
|
|
||||||
{
|
|
||||||
if (!m_ui)
|
|
||||||
return;
|
|
||||||
int selected = m_ui->tableViewDatabases->selectionModel()->selectedRows().size();
|
|
||||||
|
|
||||||
m_ui->pbRemove->setEnabled(selected > 0);
|
|
||||||
m_ui->pbActivate->setEnabled(selected > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onDropDbFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
||||||
{
|
|
||||||
INFO_LOG(m_logger) << "onDropDbFinished: exitCode: " << exitCode << ", exitStatus: " << exitStatus;
|
|
||||||
|
|
||||||
static const QString s_title = tr("Remove Database");
|
|
||||||
static const QString s_msgFailure = tr("Removing database failed.");
|
|
||||||
static const QString s_msgSuccess = tr("Removing database successful.");
|
|
||||||
|
|
||||||
if (exitCode > 0)
|
|
||||||
{
|
|
||||||
const QString str = QString::fromLocal8Bit(m_proc->readAllStandardError()) + QLatin1Char('\n') +
|
|
||||||
QString::fromLocal8Bit(m_proc->readAllStandardOutput());
|
|
||||||
ERROR_LOG(m_logger) << "Cannot drop database: " << str;
|
|
||||||
QString msg = s_msgFailure;
|
|
||||||
QString db0 = QLatin1String("ERROR: database \"") + m_databaseToRemove.dbName + QLatin1String("\" does not exist");
|
|
||||||
if (!str.contains(db0))
|
|
||||||
msg += tr(" Database cannot be removed:\n%1.").arg(str);
|
|
||||||
QMessageBox::critical(this, s_title, msg, QMessageBox::Ok);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_databasesModel->onDataChanged(m_databaseToRemove, DataModification::eRemoved);
|
|
||||||
QMessageBox::information(this, s_title, s_msgSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
enableButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onErrorOccured(QProcess::ProcessError error)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "error: " << error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onStartApp()
|
|
||||||
{
|
|
||||||
handleProcInit(QStringLiteral("ps"), {QStringLiteral("aux")});
|
|
||||||
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
||||||
this, &AarApplication::onPsauxFinished);
|
|
||||||
m_proc->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AarApplication::onPsauxFinished()
|
|
||||||
{
|
|
||||||
enableButtons();
|
|
||||||
QByteArray output = m_proc->readAllStandardOutput();
|
|
||||||
|
|
||||||
if (output.contains("svcServiceManagement"))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "ServiceManagement already started";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Start svcServiceManagement";
|
|
||||||
handleProcInit(QCoreApplication::applicationDirPath() + QStringLiteral("/svcServiceManagement"), {QStringLiteral("-z")});
|
|
||||||
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
||||||
this, &AarApplication::onStartAppFinished);
|
|
||||||
m_proc->start();
|
|
||||||
m_proc->waitForFinished();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onStartAppFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
||||||
{
|
|
||||||
handleProcFinished(exitCode, exitStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onStopApp()
|
|
||||||
{
|
|
||||||
disableButtons();
|
|
||||||
handleProcInit(QStringLiteral("ps"), {QStringLiteral("aux")});
|
|
||||||
m_proc->start();
|
|
||||||
if (m_proc->waitForFinished())
|
|
||||||
onPsauxStopFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onPsauxStopFinished()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "IN onPsauxStopFinished";
|
|
||||||
enableButtons();
|
|
||||||
QByteArray output = m_proc->readAllStandardOutput();
|
|
||||||
|
|
||||||
if (output.contains("svcServiceManagement"))
|
|
||||||
{
|
|
||||||
if (m_stopping)
|
|
||||||
{
|
|
||||||
QThread::sleep(3);
|
|
||||||
onStopApp();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
ERROR_LOG(m_logger) << "ServiceManagement started - stopping";
|
|
||||||
|
|
||||||
handleProcInit(QCoreApplication::applicationDirPath() + QStringLiteral("/svcServiceManagement"), {QStringLiteral("-s")});
|
|
||||||
connect(m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
|
||||||
this, &AarApplication::onStopAppFinished);
|
|
||||||
m_proc->start();
|
|
||||||
m_stopping = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
INFO_LOG(m_logger) << "ServiceManagement already stopped";
|
|
||||||
m_stopping = false;
|
|
||||||
m_progressDialog->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_proc->waitForFinished();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::onStopAppFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
||||||
{
|
|
||||||
if (m_stopping)
|
|
||||||
onPsauxStopFinished();
|
|
||||||
|
|
||||||
handleProcFinished(exitCode, exitStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::handleProcInit(const QString &program, const QStringList &args)
|
|
||||||
{
|
|
||||||
if (m_proc)
|
|
||||||
{
|
|
||||||
m_proc->disconnect(this);
|
|
||||||
m_proc->deleteLater();
|
|
||||||
}
|
|
||||||
m_proc = new QProcess(this);
|
|
||||||
NOTICE_LOG(m_logger) << "Starting process '" << program << "' with args '"
|
|
||||||
<< args.join(QLatin1Char(' ')) << "'";
|
|
||||||
|
|
||||||
m_proc->setProgram(program);
|
|
||||||
m_proc->setArguments(args);
|
|
||||||
connect(m_proc, &QProcess::errorOccurred, this, &AarApplication::onErrorOccured);
|
|
||||||
disableButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AarApplication::handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
||||||
{
|
|
||||||
enableButtons();
|
|
||||||
|
|
||||||
if (!m_proc)
|
|
||||||
return;
|
|
||||||
if (exitCode != 0 || exitStatus != 0)
|
|
||||||
{
|
|
||||||
QByteArray out = m_proc->readAllStandardError();
|
|
||||||
if (!out.isEmpty())
|
|
||||||
out += '\n';
|
|
||||||
out += m_proc->readAllStandardOutput();
|
|
||||||
ERROR_LOG(m_logger) << "Process finished - exitCode: " << exitCode << ", exitStatus = " << exitStatus << ", " << out;
|
|
||||||
|
|
||||||
QMessageBox::critical(this,
|
|
||||||
tr ("Execute process"), tr("Error executing process, exitCode: %1, exitStatus: %2, output: %3")
|
|
||||||
.arg(exitCode).arg(exitStatus).arg(QString::fromLocal8Bit(out)),
|
|
||||||
QMessageBox::Ok);
|
|
||||||
}
|
|
||||||
m_proc->disconnect(this);
|
|
||||||
m_proc->deleteLater();
|
|
||||||
m_proc = nullptr;
|
|
||||||
|
|
||||||
if (m_progressDialog)
|
|
||||||
m_progressDialog->hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AarApplication::enaDisaButtons(bool bEnable)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
const QList<QPushButton*> l = findChildren<QPushButton*>();
|
|
||||||
for (QPushButton *pb : l)
|
|
||||||
pb->setEnabled(bEnable);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const QList<QAction*> l = findChildren<QAction*>();
|
|
||||||
for (QAction *a : l)
|
|
||||||
a->setEnabled(bEnable);
|
|
||||||
}
|
|
||||||
if (bEnable)
|
|
||||||
enaDisa();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AarApplication
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
/*
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* <short description>
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Malte Schröder, SLSE, 2016-06-08
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QtWidgets/QMainWindow>
|
|
||||||
#include <QtCore/QMap>
|
|
||||||
#include <QtGui/QStandardItemModel>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <QCloseEvent>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QProgressDialog>
|
|
||||||
#include <QtWidgets/QMenuBar>
|
|
||||||
#include <QSqlDatabase>
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "databases_model.h"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class AarApplication;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace AARApplication
|
|
||||||
{
|
|
||||||
class AarApplication : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AarApplication(QWidget *parent = nullptr);
|
|
||||||
~AarApplication();
|
|
||||||
|
|
||||||
bool init();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onClosedClicked();
|
|
||||||
void onRemoveClicked();
|
|
||||||
void onActivateClicked();
|
|
||||||
void onActivateNetworkClicked();
|
|
||||||
void onDropDbFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
||||||
void onPsauxFinished();
|
|
||||||
void onStartAppFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
||||||
void onPsauxStopFinished();
|
|
||||||
void onStopAppFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
||||||
void onErrorOccured(QProcess::ProcessError error);
|
|
||||||
void onStartApp();
|
|
||||||
void onStopApp();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void enaDisa();
|
|
||||||
void handleProcInit(const QString &program, const QStringList &args);
|
|
||||||
void handleProcFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
||||||
void disableButtons() { enaDisaButtons(false); }
|
|
||||||
void enableButtons() { enaDisaButtons(true); }
|
|
||||||
void enaDisaButtons(bool bEnable);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::AarApplication *m_ui;
|
|
||||||
DatabasesModel *m_databasesModel;
|
|
||||||
DatabasesProxyModel *m_proxyModel;
|
|
||||||
QMap<QString, QSqlDatabase> m_dbMap;
|
|
||||||
bool m_stopping;
|
|
||||||
Exercise m_databaseToRemove;
|
|
||||||
QProcess *m_proc;
|
|
||||||
QSqlDatabase m_dbPostgres;
|
|
||||||
QProgressDialog *m_progressDialog;
|
|
||||||
QVector<QWidget*> m_widgets;
|
|
||||||
|
|
||||||
LOGGER_T m_logger;
|
|
||||||
};
|
|
||||||
} // namespace AARApplication
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* PresentationManangement - Script Overview Dialog Model
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*
|
|
||||||
* Created by Mike Wille, SLSE, 2017-03-15
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "databases_model.h"
|
|
||||||
|
|
||||||
#include <ngltools/ngltools_dtg.h>
|
|
||||||
#include <ngldb/nsqlquery.h>
|
|
||||||
|
|
||||||
#include <QtCore/QDateTime>
|
|
||||||
#include <QPalette>
|
|
||||||
|
|
||||||
namespace AARApplication
|
|
||||||
{
|
|
||||||
|
|
||||||
DatabasesModel::DatabasesModel(QObject *parent)
|
|
||||||
: QAbstractTableModel(parent)
|
|
||||||
, m_logger(getLogger("DatabasesModel"))
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
m_vecData.clear();
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabasesModel::initModel(const QSqlDatabase &db)
|
|
||||||
{
|
|
||||||
NSqlQuery q(db);
|
|
||||||
|
|
||||||
QString stmt = QStringLiteral("SELECT id, name, begin_time, end_time, exercise_state_id FROM exm.exercise");
|
|
||||||
|
|
||||||
if (!q.prepare(stmt))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Preparing statement '" << stmt << "' failed.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!q.exec(stmt))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Executing statement '" << stmt << "' failed.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = 0;
|
|
||||||
while (q.next())
|
|
||||||
{
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "More than one exercise detected. There should be only one exercise per database.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exercise exercise;
|
|
||||||
exercise.id = q.value(0).toInt();
|
|
||||||
exercise.name = q.value(1).toString();
|
|
||||||
exercise.startTime = q.value(2).toLongLong();
|
|
||||||
exercise.endTime = q.value(3).toLongLong();
|
|
||||||
exercise.dbName = QStringLiteral("lts_db_") + QString::number(exercise.id);
|
|
||||||
exercise.stateId = q.value(4).toInt();
|
|
||||||
TRACE_LOG(m_logger) << "Found exercise with id=" << exercise.id << ", name=" << exercise.name << ", startTime="
|
|
||||||
<< exercise.startTime << ", endTime=" << exercise.endTime << ", dbName=" << exercise.dbName
|
|
||||||
<< ", stateId=" << exercise.stateId;
|
|
||||||
if (exercise.stateId != 6)
|
|
||||||
onDataChanged(exercise, DataModification::eAdded);
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
|
|
||||||
INFO_LOG(m_logger) << "initModel - #exercises: " << m_vecData.size();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QVariant DatabasesModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (role != Qt::DisplayRole || !index.isValid() || index.row() >= m_vecData.size())
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
const Exercise &e = m_vecData.at(index.row());
|
|
||||||
|
|
||||||
switch (index.column())
|
|
||||||
{
|
|
||||||
case Id:
|
|
||||||
return e.id;
|
|
||||||
case Name:
|
|
||||||
return QString(e.name);
|
|
||||||
case StartTime:
|
|
||||||
return DTG::toStringMSec(e.startTime);
|
|
||||||
case EndTime:
|
|
||||||
return DTG::toStringMSec(e.endTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
int DatabasesModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return parent.isValid() ? 0 : m_vecData.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int DatabasesModel::columnCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return parent.isValid() ? 0 : EndTime + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant DatabasesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
|
||||||
{
|
|
||||||
if (orientation == Qt::Horizontal
|
|
||||||
&& role == Qt::DisplayRole)
|
|
||||||
{
|
|
||||||
Columns col = static_cast<Columns>(section);
|
|
||||||
switch (col)
|
|
||||||
{
|
|
||||||
case Id:
|
|
||||||
return tr("Id");
|
|
||||||
case Name:
|
|
||||||
return tr("Name");
|
|
||||||
case StartTime:
|
|
||||||
return tr("Start Time");
|
|
||||||
case EndTime:
|
|
||||||
return tr("End Time");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return QAbstractTableModel::headerData(section, orientation, role);
|
|
||||||
}
|
|
||||||
|
|
||||||
Exercise DatabasesModel::getRowData(int row) const
|
|
||||||
{
|
|
||||||
if (row < 0 || row >= m_vecData.size())
|
|
||||||
return Exercise();
|
|
||||||
return m_vecData.at(row);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabasesModel::insertRow(const Exercise &item)
|
|
||||||
{
|
|
||||||
beginInsertRows(QModelIndex(), m_vecData.size(), m_vecData.size());
|
|
||||||
m_vecData.append(item);
|
|
||||||
endInsertRows();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabasesModel::removeRow(const int &row)
|
|
||||||
{
|
|
||||||
beginRemoveRows(QModelIndex(), row, row);
|
|
||||||
m_vecData.remove(row);
|
|
||||||
endRemoveRows();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DatabasesModel::onDataChanged(const Exercise &data, DataModification modType)
|
|
||||||
{
|
|
||||||
int row = -1;
|
|
||||||
switch (modType)
|
|
||||||
{
|
|
||||||
case DataModification::eAdded:
|
|
||||||
row = m_vecData.size();
|
|
||||||
if (insertRow(data))
|
|
||||||
emit dataChanged(index(row, Columns::Id), index(row, Columns::EndTime));
|
|
||||||
return;
|
|
||||||
|
|
||||||
case DataModification::eModified:
|
|
||||||
row = m_vecData.indexOf(data);
|
|
||||||
if (row != -1)
|
|
||||||
{
|
|
||||||
m_vecData[row] = data;
|
|
||||||
emit dataChanged(index(row, Columns::Id), index(row, Columns::EndTime));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case DataModification::eRemoved:
|
|
||||||
row = m_vecData.indexOf(data);
|
|
||||||
if (row != -1)
|
|
||||||
if (removeRow(row))
|
|
||||||
emit dataChanged(index(std::min<qsizetype>(row, m_vecData.size() - 1), Columns::Id), index(m_vecData.size()-1, Columns::EndTime));
|
|
||||||
return;
|
|
||||||
} // switch
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DatabasesProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
|
||||||
{
|
|
||||||
m_sourceModel = qobject_cast<DatabasesModel*>(sourceModel);
|
|
||||||
QSortFilterProxyModel::setSourceModel(sourceModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DatabasesProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
|
||||||
{
|
|
||||||
if (!m_sourceModel ||
|
|
||||||
source_left.column() != source_right.column() ||
|
|
||||||
!source_left.isValid() ||
|
|
||||||
!source_right.isValid())
|
|
||||||
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
|
||||||
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
|
|
||||||
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
|
|
||||||
switch (source_left.column())
|
|
||||||
{
|
|
||||||
case DatabasesModel::StartTime:
|
|
||||||
return dataLeft.startTime < dataRight.startTime;
|
|
||||||
case DatabasesModel::EndTime:
|
|
||||||
return dataLeft.endTime < dataRight.endTime;
|
|
||||||
case DatabasesModel::Id:
|
|
||||||
case DatabasesModel::Name:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return QSortFilterProxyModel::lessThan(source_left, source_right);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace AARApplication
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* PresentationManangement - Script Overview Dialog Model
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*
|
|
||||||
* Created by Mike Wille, SLSE, 2017-03-15
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#include <LtsUtils/LtsUtilsCore/data_modification_enum.h>
|
|
||||||
|
|
||||||
#include <QtCore/QAbstractTableModel>
|
|
||||||
#include <QtCore/QSortFilterProxyModel>
|
|
||||||
|
|
||||||
|
|
||||||
class QSqlDatabase;
|
|
||||||
|
|
||||||
namespace AARApplication
|
|
||||||
{
|
|
||||||
|
|
||||||
struct Exercise
|
|
||||||
{
|
|
||||||
qint32 id = 0;
|
|
||||||
QString name;
|
|
||||||
QString dbName;
|
|
||||||
qint64 startTime = 0;
|
|
||||||
qint64 endTime = 0;
|
|
||||||
qint32 stateId = 0;
|
|
||||||
|
|
||||||
bool operator == (const Exercise &other) const { return id == other.id; }
|
|
||||||
bool operator != (const Exercise &other) const { return id != other.id; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DatabasesModel
|
|
||||||
//
|
|
||||||
class DatabasesModel : public QAbstractTableModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Columns
|
|
||||||
{
|
|
||||||
Id = 0,
|
|
||||||
Name,
|
|
||||||
StartTime,
|
|
||||||
EndTime
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit DatabasesModel(QObject *parent = nullptr);
|
|
||||||
~DatabasesModel() = default;
|
|
||||||
|
|
||||||
bool initModel(const QSqlDatabase &db);
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex &, int) const override final;
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const override final;
|
|
||||||
int columnCount(const QModelIndex &parent) const override final;
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override final;
|
|
||||||
Exercise getRowData(int row) const;
|
|
||||||
bool insertRow(const Exercise &item);
|
|
||||||
bool removeRow(const int &row);
|
|
||||||
|
|
||||||
friend class DatabasesProxyModel;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void onDataChanged(const Exercise &data, DataModification modType);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVector<Exercise> m_vecData;
|
|
||||||
LOGGER_T m_logger;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// DatabasesProxyModel
|
|
||||||
//
|
|
||||||
class DatabasesProxyModel final : public QSortFilterProxyModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
using QSortFilterProxyModel::QSortFilterProxyModel;
|
|
||||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
DatabasesModel *m_sourceModel = nullptr;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
log4j.reset=true
|
|
||||||
log4j.rootLogger=WARN, file
|
|
||||||
|
|
||||||
# DbAdministration
|
|
||||||
###########################################################
|
|
||||||
|
|
||||||
#log4j.logger.DbAdministration=DEBUG
|
|
||||||
|
|
||||||
# File
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.file=Lts::RollingFileAppender
|
|
||||||
log4j.appender.file.MaxFileSize=1MB
|
|
||||||
log4j.appender.file.MaxBackupIndex=9
|
|
||||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
|
||||||
|
|
||||||
|
|
||||||
# Appnd_Console
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
|
||||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
|
||||||
|
|
||||||
|
|
||||||
# Appnd_Syslog
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
|
||||||
log4j.appender.syslog.Threshold=ERROR
|
|
||||||
log4j.appender.syslog.SysLogHost=localhost
|
|
||||||
log4j.appender.syslog.Facility=LOCAL7
|
|
||||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
|
||||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
|
||||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
|
||||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################
|
|
||||||
###########################################################
|
|
||||||
###########################################################
|
|
||||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
|
||||||
# TRACE,
|
|
||||||
# DEBUG,
|
|
||||||
# INFO,
|
|
||||||
# WARN,
|
|
||||||
# ERROR
|
|
||||||
# FATAL
|
|
||||||
#
|
|
||||||
# d = date/time
|
|
||||||
# p = priority (Level)
|
|
||||||
# c = category/channel
|
|
||||||
# m = message
|
|
||||||
# F = file
|
|
||||||
# L = line
|
|
||||||
# n = platform dependent line separator character or characters.
|
|
||||||
# ....
|
|
||||||
#
|
|
||||||
# Examples for console:
|
|
||||||
# a)
|
|
||||||
# %d %p %c #%m# (%.50F:%L)%n
|
|
||||||
# date/time
|
|
||||||
# priority
|
|
||||||
# category/channel
|
|
||||||
# #message#
|
|
||||||
# (Maximal 50Character des Filename von rechts:Line)
|
|
||||||
# line separator
|
|
||||||
#
|
|
||||||
# b)
|
|
||||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
|
||||||
# date/time
|
|
||||||
# (Maximal 15Character des Filename von rechts:Line)
|
|
||||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
|
||||||
# category/channel
|
|
||||||
# message
|
|
||||||
# line separator
|
|
||||||
#
|
|
||||||
# Examples for files:
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Building Config - logging facility
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
namespace AARApplication
|
|
||||||
{
|
|
||||||
|
|
||||||
LOGGER_T getLogger(const char *name)
|
|
||||||
{
|
|
||||||
static const char ns[] = "DBA.";
|
|
||||||
std::string loggerName;
|
|
||||||
const size_t len = strlen(name);
|
|
||||||
loggerName.reserve(sizeof(ns) + len);
|
|
||||||
loggerName.append(ns, sizeof(ns) - 1);
|
|
||||||
loggerName.append(name, len);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
|
||||||
getNGLLogger(loggerName);
|
|
||||||
}
|
|
||||||
catch (const std::exception &ex)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace AARApplication
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Logging for Evaluations
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace AARApplication
|
|
||||||
{
|
|
||||||
typedef NGL::INGLLogger &LOGGER_T;
|
|
||||||
|
|
||||||
LOGGER_T getLogger(const char *name);
|
|
||||||
inline LOGGER_T getLogger(const QString &loggerName)
|
|
||||||
{
|
|
||||||
return getLogger(loggerName.toUtf8().constData());
|
|
||||||
}
|
|
||||||
} // namespace AARApplication
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* <short description>
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Malte Schröder, SLSE, 2016-06-08
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "aar_application.h"
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include <nglapplication/nglapplication.h>
|
|
||||||
#include <nglapplication/nglcoreapplication.h>
|
|
||||||
#include <ngltranslator/ngltranslator.h>
|
|
||||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
|
||||||
|
|
||||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CmdLineParser()
|
|
||||||
: LtsCommandLineParser(ProvideCommandLineParameterOptions::None)
|
|
||||||
{
|
|
||||||
addOption({{QStringLiteral("l"), QStringLiteral("lang")},
|
|
||||||
QStringLiteral("Language iso code to use (de_DE, en_GB, en_US)"),
|
|
||||||
QStringLiteral("<locale iso code>")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
QString langIsoCode() const { return value(QStringLiteral("l")); }
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
int retval = -1;
|
|
||||||
bool bHeadless = false;
|
|
||||||
for (int i = 1; i < argc; ++i)
|
|
||||||
{
|
|
||||||
if (strcmp(argv[i], "-e") == 0)
|
|
||||||
{
|
|
||||||
bHeadless = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QScopedPointer<QCoreApplication> app;
|
|
||||||
app.reset(bHeadless ? dynamic_cast<QCoreApplication*>(new NGLCoreApplication(argc, argv))
|
|
||||||
: dynamic_cast<QCoreApplication*>(new NGLApplication(argc, argv)));
|
|
||||||
QCoreApplication::setApplicationName(QLatin1String("AarApplication"));
|
|
||||||
QCoreApplication::setOrganizationName(QLatin1String("RME"));
|
|
||||||
|
|
||||||
// Qt::AA_UseHighDpiPixmaps: no-op since Qt6 (high-DPI pixmaps are always enabled)
|
|
||||||
|
|
||||||
|
|
||||||
NGL::LoggerHandler *lh = dynamic_cast<NGL::LoggerHandler*>(app.data());
|
|
||||||
lh->createLogger("AarApp", "log4cxx_aarApp.props");
|
|
||||||
NGL::INGLLogger &logger = lh->baseLogger();
|
|
||||||
|
|
||||||
// Parse Options
|
|
||||||
CmdLineParser options;
|
|
||||||
if (!options.init())
|
|
||||||
return retval;
|
|
||||||
|
|
||||||
// Set Translation
|
|
||||||
QString langIsoCode = options.langIsoCode();
|
|
||||||
if (langIsoCode.isEmpty())
|
|
||||||
langIsoCode = QLocale::system().name();
|
|
||||||
NGL::setTranslationLocale(langIsoCode.toLatin1());
|
|
||||||
|
|
||||||
AARApplication::AarApplication * w = new AARApplication::AarApplication;
|
|
||||||
if (!w->init())
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
STARTUP_LOG(logger);
|
|
||||||
w->show();
|
|
||||||
QGuiApplication::setQuitOnLastWindowClosed(true);
|
|
||||||
retval = QCoreApplication::exec();
|
|
||||||
|
|
||||||
SHUTDOWN_LOG(logger);
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(AarApp)
|
|
||||||
ADD_SUBDIRECTORY(OpApp)
|
|
||||||
# ADD_SUBDIRECTORY(THP) # Disabled: VLC dependency not available
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
SET(LOG4CXX_PROPS_FILE log4cxx_opapp.props)
|
|
||||||
|
|
||||||
SET(mwt_SRCS
|
|
||||||
main.cpp
|
|
||||||
${LOG4CXX_PROPS_FILE}
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
SET(JBN ${JENKINS_BUILD_NUMBER})
|
|
||||||
IF (NOT JENKINS_BUILD_NUMBER)
|
|
||||||
SET(JBN "0")
|
|
||||||
ENDIF()
|
|
||||||
SET(OPAPP_VERSION_INFO "${LTS_VERSION_MAJOR}, ${LTS_VERSION_MINOR}, ${JBN}, ${LTS_VERSION_PATCH}")
|
|
||||||
CONFIGURE_FILE(opapp.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/opapp.rc)
|
|
||||||
LIST(APPEND mwt_SRCS ${CMAKE_CURRENT_BINARY_DIR}/opapp.rc)
|
|
||||||
ENDIF()
|
|
||||||
NGL_ADD_APP_ICON(mwt_SRCS)
|
|
||||||
|
|
||||||
IF(BUILD_RPM)
|
|
||||||
NGL_ADD_EXECUTABLE(WS OperatorApplication WIN32 ${mwt_SRCS})
|
|
||||||
ELSE()
|
|
||||||
NGL_ADD_EXECUTABLE(WS OperatorApplication ${mwt_SRCS})
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(OperatorApplication
|
|
||||||
$<IF:$<TARGET_EXISTS:ArcGISQt5Hack>,ArcGISQt5Hack,> # make sure it's loaded *before* libEsriCommonQt.so (guard: only linked when the SituationMap viewer is built, matching CentralEffectSimulation)
|
|
||||||
${Qt6_Widgets}
|
|
||||||
Qt6::Network
|
|
||||||
nglapplication
|
|
||||||
LtsCommandLineParser
|
|
||||||
NGLLogger
|
|
||||||
LtsSession
|
|
||||||
LtsPluginLoader
|
|
||||||
LtsAppDescriptor
|
|
||||||
LtsAppManager
|
|
||||||
LtsSessionData
|
|
||||||
LtsUtilsSettings
|
|
||||||
ngltranslator
|
|
||||||
nglsettings
|
|
||||||
LtsProjectionWorkstation
|
|
||||||
LtsMultiMonitor # TODO: rm if -m is out
|
|
||||||
LtsUtilsGuiConnectDialog # to set timeout if -v is set
|
|
||||||
LtsUtilsGuiStyleManager
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
NGL_INSTALL_TARGET(OperatorApplication)
|
|
||||||
|
|
||||||
NGL_INSTALL(FILES WS ${LOG4CXX_PROPS_FILE} DESTINATION "bin")
|
|
||||||
@@ -1,537 +0,0 @@
|
|||||||
# Created by Mike Wille, SLSE, 2016-08-08
|
|
||||||
log4j.reset=true
|
|
||||||
|
|
||||||
log4j.rootLogger=WARN, file
|
|
||||||
|
|
||||||
# LtsSession
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.LtsSession.TopicLockHandler=INFO
|
|
||||||
#log4j.logger.LtsWidget.LtsDialog=INFO
|
|
||||||
|
|
||||||
|
|
||||||
# SituationReplayManagement SRM
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.SRM=DEBUG
|
|
||||||
|
|
||||||
# Schnittstelle Adpter Adler SAA
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.SAA.SAAInterfaceGuiPlugin=DEBUG
|
|
||||||
#log4j.logger.SAA.SaaDialogModel=DEBUG
|
|
||||||
#log4j.logger.SAA.CustomViewSaa=DEBUG
|
|
||||||
#log4j.logger.SAA.SaaChooser=DEBUG
|
|
||||||
|
|
||||||
# FileManagement FLM
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.AVM=DEBUG
|
|
||||||
#log4j.logger.FLM.Plugins.Data=INFO
|
|
||||||
#log4j.logger.FLM.Plugins.Gui.Explorer=INFO
|
|
||||||
#log4j.logger.FLM.Plugins.Gui.FlmCombobox=INFO
|
|
||||||
#log4j.logger.FLM.FileManagementDialog=DEBUG
|
|
||||||
#log4j.logger.FLM.DialogModelFolder=INFO
|
|
||||||
#log4j.logger.FLM.DialogEditFolder=INFO
|
|
||||||
#log4j.logger.FLM.DialogModelFile=INFO
|
|
||||||
#log4j.logger.FLM.FileContentEditDialog=DEBUG
|
|
||||||
#log4j.logger.FLM.FileContentPreviewDialog=DEBUG
|
|
||||||
#log4j.logger.FLM.SetAttributesDialog=INFO
|
|
||||||
#log4j.logger.FLM.HQReportModel=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
# FilterManagement FLT
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.FLT.AesDisplayFilterImpl=DEBUG
|
|
||||||
#log4j.logger.FLT.BuildingComponentSettingsImpl=TRACE
|
|
||||||
#log4j.logger.FLT.BuildingComponentFilterDialog=TRACE
|
|
||||||
#log4j.logger.FLT.BuildingComponentSettingsWidget=TRACE
|
|
||||||
#log4j.logger.FLT.SymbolAppearanceSettings=DEBUG
|
|
||||||
#log4j.logger.FLT.SymbolAppearanceDialog=INFO
|
|
||||||
#log4j.logger.FLT.SymbolAppearanceWidget=DEBUG
|
|
||||||
|
|
||||||
#log4j.logger.FLT.FilterChangeDialog=INFO
|
|
||||||
|
|
||||||
# CodificationManagement COD
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.COD.Plugins.Gui.CodificationDataImpl=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationDataOverviewDialog=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationDataOverviewModel=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationDataTableView=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationDataTableEditView=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationDataTableView=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationCSVExport=DEBUG
|
|
||||||
#log4j.logger.COD.CodificationCSVImport=DEBUG
|
|
||||||
#log4j.logger.COD.NumeralCodeTableModel=DEBUG
|
|
||||||
#log4j.logger.COD.AuthenticationCodeTableModel=DEBUG
|
|
||||||
#log4j.logger.COD.LogisticalTermsModel=DEBUG
|
|
||||||
#log4j.logger.COD.PhraseTableModel= DEBUG
|
|
||||||
#log4j.logger.COD.CodeTableEditDelegate=DEBUG
|
|
||||||
#log4j.logger.COD.AssignCodificationDataTable=DEBUG
|
|
||||||
|
|
||||||
# AlarmManagement Info
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.ALM.Config=DEBUG
|
|
||||||
#log4j.logger.ALM.Model=DEBUG
|
|
||||||
#log4j.logger.ALM.Dialog=DEBUG
|
|
||||||
|
|
||||||
# InfrastructureManagement ISM
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.ISM.ApproachingPointsDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.ApproachingPointsDialogModel=DEBUG
|
|
||||||
#log4j.logger.ISM.AssetFilterDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.AssetListDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.AssetListDialogModel=DEBUG
|
|
||||||
#log4j.logger.ISM.AudioVideoConfigPlugin=DEBUG
|
|
||||||
#log4j.logger.ISM.BuildingMountPointDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.BuildingMountPointModel=DEBUG
|
|
||||||
#log4j.logger.ISM.CustomViewSchedule=DEBUG
|
|
||||||
#log4j.logger.ISM.DdsSelector=DEBUG
|
|
||||||
#log4j.logger.ISM.EditApproachingPointDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.EditAssetDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.ExerciseAssignmentDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.ExerciseAssignmentDialogModel=DEBUG
|
|
||||||
#log4j.logger.ISM.ForeignDataInterface=DEBUG
|
|
||||||
#log4j.logger.ISM.InfrastructureManagement=DEBUG
|
|
||||||
#log4j.logger.ISM.MountingPointInfoDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.MountingPointListDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.MountingPointListDialogModel=DEBUG
|
|
||||||
#log4j.logger.ISM.NewPlanDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.OverviewDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.OverviewDialogModel=DEBUG
|
|
||||||
|
|
||||||
#log4j.logger.ISM.OverviewMountingPointListDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.ViewMountingPointListModel=DEBUG
|
|
||||||
|
|
||||||
#log4j.logger.ISM.PlanChooser=DEBUG
|
|
||||||
#log4j.logger.ISM.PlanDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.PlanDialogModel=DEBUG
|
|
||||||
#log4j.logger.ISM.PlanEditDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.PlanTimeLineDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.PlanTimeLineModel=DEBUG
|
|
||||||
#log4j.logger.ISM.Plugins.Gui.IsmCombobox=DEBUG
|
|
||||||
#log4j.logger.ISM.ResourceManagement=DEBUG
|
|
||||||
#log4j.logger.ISM.SetPropertiesDialog=DEBUG
|
|
||||||
#log4j.logger.ISM.SetRecordingDialog=DEBUG
|
|
||||||
|
|
||||||
# AreaEffectSimulation Info
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.AES.AESInfo=DEBUG
|
|
||||||
#log4j.logger.AES.AESInfoDialog=DEBUG
|
|
||||||
|
|
||||||
# generated using ctc_find_getlogger.sh
|
|
||||||
#log4j.logger.AES.AesGuiBase=DEBUG
|
|
||||||
#log4j.logger.AES.AESInfo=DEBUG
|
|
||||||
#log4j.logger.AES.AESInfoDialog=DEBUG
|
|
||||||
#log4j.logger.AES.AesItemList=DEBUG
|
|
||||||
#log4j.logger.AES.ChargeAdministration=DEBUG
|
|
||||||
#log4j.logger.AES.ChargeAdministrationList=DEBUG
|
|
||||||
#log4j.logger.AES.DangerArea.AesItemInfo=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.Aes.Borderline=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.AirSupport=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.BcContamination=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.BorderlineImpl=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.ChargeAdministration=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.DangerArea=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.Explosion=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.FunctionalArea=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.GasPipe=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.MineArea=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.MineCorridor=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.MineSingleVirtual=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.NContamination=DEBUG
|
|
||||||
#log4j.logger.AES.Plugins.Gui.TechnicalArea=DEBUG
|
|
||||||
|
|
||||||
#log4j.logger.AES.BCContaminationEdit=DEBUG
|
|
||||||
#log4j.logger.AES.BoobyTrapEdit=DEBUG
|
|
||||||
#log4j.logger.AES.BorderlineEdit=DEBUG
|
|
||||||
#log4j.logger.AES.DangerAreaEdit=DEBUG
|
|
||||||
#log4j.logger.AES.ExplosionEdit=DEBUG
|
|
||||||
### setExplosionsEdit to ERROR (WARN "zValue is very small, set to 100")
|
|
||||||
log4j.logger.AES.ExplosionsEdit=ERROR
|
|
||||||
#log4j.logger.AES.FunctionalAreaEdit=DEBUG
|
|
||||||
#log4j.logger.AES.GasPipeEdit=DEBUG
|
|
||||||
#log4j.logger.AES.MineAreaEdit=DEBUG
|
|
||||||
#log4j.logger.AES.MineCorridorEdit=DEBUG
|
|
||||||
#log4j.logger.AES.NContaminationEdit=DEBUG
|
|
||||||
#log4j.logger.AES.OffRouteMineEdit=DEBUG
|
|
||||||
#log4j.logger.AES.TechnicalAreaEdit=DEBUG
|
|
||||||
|
|
||||||
# in context ExplosionCluster / Artillery suppress warnings of TrajectoryGenerator, TrajectoryGeneratorVulcano
|
|
||||||
log4j.logger.AES.TrajectoryGenerator=ERROR
|
|
||||||
log4j.logger.AES.TrajectoryGeneratorVulcano=ERROR
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# AdvancedSymbolgy
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.AdvSymbology=INFO
|
|
||||||
#log4j.logger.AdvSymbology.FlmSubscriber=DEBUG
|
|
||||||
# FlmSubscriber.ReFetch should be on INFO to be able check the occurance of ReFetching
|
|
||||||
#log4j.logger.AdvSymbology.FlmSubscriber.ReFetch=INFO
|
|
||||||
#log4j.logger.AdvSymbology.FlmSymbolProxy=DEBUG
|
|
||||||
#log4j.logger.AdvSymbology.EsriDictionaryProcessor=INFO
|
|
||||||
#log4j.logger.AdvSymbology.SidcBuilder=INFO
|
|
||||||
#log4j.logger.AdvSymbology.PropertyResult=INFO
|
|
||||||
#log4j.logger.AdvSymbology.PropertyResultWatcher=INFO
|
|
||||||
#log4j.logger.AdvSymbology.SymbolResult=INFO
|
|
||||||
#log4j.logger.AdvSymbology.SymbolResultWatcher=INFO
|
|
||||||
#log4j.logger.AdvSymbology.SymbolDictionary=INFO
|
|
||||||
#log4j.logger.AdvSymbology.SymbolDictionaryImpl=INFO
|
|
||||||
|
|
||||||
# AdvancedSymbolgy - Plugin
|
|
||||||
#log4j.logger.AdvSymbology.FlmSubscriber=INFO
|
|
||||||
#log4j.logger.AdvSymbology.FlmSymbolProxy=INFO
|
|
||||||
|
|
||||||
|
|
||||||
# Building-Viewer
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.BDV=DEBUG
|
|
||||||
#Common
|
|
||||||
#log4j.logger.BDV.BuildingManager=DEBUG
|
|
||||||
#log4j.logger.BDV.BuildingViewerDdsController=DEBUG
|
|
||||||
#log4j.logger.BDV.BgViewerControllerSingleton=DEBUG
|
|
||||||
#log4j.logger.BDV.BuildingViewerDdsController=DEBUG
|
|
||||||
#log4j.logger.BDV.CommunicationInterface=DEBUG
|
|
||||||
#GUI
|
|
||||||
#log4j.logger.BDV.BuildingViewer::BuildingEdit=DEBUG
|
|
||||||
#log4j.logger.BDV.BgViewerDataView=DEBUG
|
|
||||||
#log4j.logger.BDV.ThreadVideoExporter=DEBUG
|
|
||||||
#log4j.logger.BDV.ReplayHandler=DEBUG
|
|
||||||
#log4j.logger.BDV.BdvPluginProvider=DEBUG
|
|
||||||
#log4j.logger.BDV.BgViewerDataViewDialog=DEBUG
|
|
||||||
#log4j.logger.BDV.TopicReplayInterface=DEBUG
|
|
||||||
#Plugin
|
|
||||||
#log4j.logger.BDV.InterfaceImpl=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
# Building
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.BLD.BldInfo=DEBUG
|
|
||||||
#log4j.logger.BLD.BldInfoDialog=DEBUG
|
|
||||||
#log4j.logger.BLD.BuildingConfigDialog=DEBUG
|
|
||||||
|
|
||||||
# TakeHomePackageManager
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.TPM.ExportedScriptsModel=DEBUG
|
|
||||||
|
|
||||||
# Script Editor
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.ScriptTimelineDialog.JournalDialog=DEBUG
|
|
||||||
#log4j.logger.ScriptTimelineDialog.ScriptTimelineDialog=DEBUG
|
|
||||||
#log4j.logger.ScriptTimelineDialog.ScriptModel=DEBUG
|
|
||||||
#log4j.logger.ScriptTimelineDialog.Plugins.Gui.Pre.ScriptTimeline=DEBUG
|
|
||||||
#log4j.logger.ScriptTimelineDialog.StoryboardDialog=DEBUG
|
|
||||||
#log4j.logger.PRE.ScreenRecorder=DEBUG
|
|
||||||
#log4j.logger.PRE.TopicRecorder=DEBUG
|
|
||||||
|
|
||||||
# SituationMap
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.SituationMap=INFO
|
|
||||||
|
|
||||||
### rethink SituationMap.Plugins.Gui.SitMap
|
|
||||||
#log4j.logger.SituationMap.Plugins.Gui.SitMap=INFO
|
|
||||||
#log4j.logger.SituationMap.SituationMapInit=INFO
|
|
||||||
#log4j.logger.SituationMap.MapInitializer=INFO
|
|
||||||
#log4j.logger.SituationMap.ThatPartyIdToColorFunctor=INFO
|
|
||||||
#log4j.logger.SituationMap.RegisterAppHandler=INFO
|
|
||||||
|
|
||||||
# SituationMap-AdapterDds:
|
|
||||||
#log4j.logger.SituationMap.AdapterDds=INFO
|
|
||||||
#log4j.logger.SituationMap.EmergencyCallToMap=INFO
|
|
||||||
#log4j.logger.SituationMap.MovementTrack=INFO
|
|
||||||
#log4j.logger.SituationMap.MovementTrackManager=INFO
|
|
||||||
#log4j.logger.SituationMap.Building2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.BuildingOwnership=INFO
|
|
||||||
#log4j.logger.SituationMap.BCContamination2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.ExplosionSingle2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.ExplosionArea2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.ExplosionCluster2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.ExplosionCluster2SituationMap.update=INFO
|
|
||||||
#log4j.logger.SituationMap.GuezIed2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.Participant2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.HitlineInfo2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.MineArea2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.MsePointToMap=INFO
|
|
||||||
#log4j.logger.SituationMap.MseBridgeToMap=INFO
|
|
||||||
#log4j.logger.SituationMap.MountingPointToMap=INFO
|
|
||||||
#log4j.logger.SituationMap.SoundAreaToMap=INFO
|
|
||||||
#log4j.logger.SituationMap.AerialOrdnance2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.BoobyTrap2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.OffRoute2SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.ChargeEffectToMap=INFO
|
|
||||||
|
|
||||||
# SituationMap-Core
|
|
||||||
#log4j.logger.SituationMap=INFO
|
|
||||||
#log4j.logger.SituationMap.MapImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.MapSettings=INFO
|
|
||||||
#log4j.logger.SituationMap.MapInitializer=INFO
|
|
||||||
#log4j.logger.SituationMap.JumpPoints=INFO
|
|
||||||
#log4j.logger.SituationMap.JumpPointWidget=TRACE
|
|
||||||
#log4j.logger.SituationMap.LayerFactoryImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.LayerControl=INFO
|
|
||||||
#log4j.logger.SituationMap.LogicalLayer=INFO
|
|
||||||
#log4j.logger.SituationMap.CoordTranslationFunctorImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.CoordTranslationThread=INFO
|
|
||||||
#log4j.logger.SituationMap.PositionsTranslated=INFO
|
|
||||||
#log4j.logger.SituationMap.GridImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.ObjectFactory=INFO
|
|
||||||
#log4j.logger.SituationMap.IdGenerator=INFO
|
|
||||||
#log4j.logger.SituationMap.ObjectContainer=INFO
|
|
||||||
#log4j.logger.SituationMap.ObjectContainerCTC=INFO
|
|
||||||
#log4j.logger.SituationMap.OverlayHandlerImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.OverviewMapHandlerImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.OverviewMap=INFO
|
|
||||||
#log4j.logger.SituationMap.PixelBasedTextBoxHandlerImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.ViewshedImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.ViewshedBase=INFO
|
|
||||||
|
|
||||||
# SituationMap-AbstractMapObject's
|
|
||||||
#log4j.logger.SituationMap.AbstractMapObjectImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.AbstractEffectSimulationImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.OriginTranslated=INFO
|
|
||||||
#log4j.logger.SituationMap.PositionsTranslated=INFO
|
|
||||||
#log4j.logger.SituationMap.AbstractMultiPointMapObjectImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.AbstractSinglePointMapObjectImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.BasicPathObjectImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.PathContainer=INFO
|
|
||||||
#log4j.logger.SituationMap.IndicationContainer=INFO
|
|
||||||
|
|
||||||
#log4j.logger.SituationMap.PolygonImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.PolylineImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.TextImpl=INFO
|
|
||||||
|
|
||||||
#log4j.logger.SituationMap.AreaFireImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.BiologicalAgentImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.BuildingOutlineImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.ChemicalAgentImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.DangerAreaImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.FunctionalAreaImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.GeoImageImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.HitLineImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.ObjectIndicatorImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.MineImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.MineFieldImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.NineLinerImpl=TRACE
|
|
||||||
#log4j.logger.SituationMap.NuclearAgentImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.ParticipantImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.SingleFireImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.CubeImpl=INFO
|
|
||||||
#log4j.logger.SituationMap.VirtualMineImpl=INFO
|
|
||||||
|
|
||||||
#log4j.logger.SituationMap.AbstractGraphicalObject=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectAttributes=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectEllipse=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectPath=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectMultiPath=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectPictureMarker=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectRange=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectRendererAttributes=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectSceneMarker=INFO
|
|
||||||
#log4j.logger.SituationMap.GraphicalObjectText=INFO
|
|
||||||
#log4j.logger.SituationMap.TacticalAppearance=INFO
|
|
||||||
|
|
||||||
|
|
||||||
#log4j.logger.SituationMap.ElevationMapManager=DEBUG
|
|
||||||
#log4j.logger.SituationMap.ElevationMap=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# SituationMap-Widgets
|
|
||||||
#log4j.logger.SituationMap.MapWidgetControl=INFO
|
|
||||||
#log4j.logger.SituationMap.LayerControlDialog=INFO
|
|
||||||
#log4j.logger.SituationMap.ConfigureMapUrls=INFO
|
|
||||||
|
|
||||||
# TargetManagement TGT
|
|
||||||
###########################################################
|
|
||||||
# SVC
|
|
||||||
#log4j.logger.TGT.DdsHandler=INFO
|
|
||||||
#log4j.logger.TGT.HandlerTargetConfig=INFO
|
|
||||||
# SVC-L400
|
|
||||||
#log4j.logger.TGT.HandlerShootbackArea=INFO
|
|
||||||
#log4j.logger.TGT.HandlerShootbackTarget=INFO
|
|
||||||
#log4j.logger.TGT.HandlerTargetAreaAssignment=INFO
|
|
||||||
#log4j.logger.TGT.ObjectShootbackArea=INFO
|
|
||||||
#log4j.logger.TGT.ObjectShootbackTarget=INFO
|
|
||||||
#log4j.logger.TGT.ObjectTargetAreaAssignment=INFO
|
|
||||||
#log4j.logger.TGT.ShootbackController=INFO
|
|
||||||
# PLUGIN-L400
|
|
||||||
#log4j.logger.Plugins.Gui.Tgt.Target=INFO
|
|
||||||
#log4j.logger.TGT.ParticipantHandler=INFO
|
|
||||||
#log4j.logger.TGT.AreaDialog=INFO
|
|
||||||
#log4j.logger.TGT.AreaEdit=INFO
|
|
||||||
#log4j.logger.TGT.AreaModel=INFO
|
|
||||||
#log4j.logger.TGT.AssignmentParticipantModel=INFO
|
|
||||||
#log4j.logger.TGT.AssignmentDialog=INFO
|
|
||||||
#log4j.logger.TGT.AssignmentEditDialog=INFO
|
|
||||||
#log4j.logger.TGT.ShootbackTargetEdit=INFO
|
|
||||||
#log4j.logger.TGT.TargetPartDialog=INFO
|
|
||||||
#log4j.logger.TGT.TargetParticipantModel=INFO
|
|
||||||
|
|
||||||
|
|
||||||
# MeteoDataManagement MDM
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.MDM.MeteoDataManagementDialog=INFO
|
|
||||||
#log4j.logger.MDM.MeteoDataManagementEdit=INFO
|
|
||||||
#log4j.logger.MDM.MeteoDataModel=INFO
|
|
||||||
#log4j.logger.MDM.InterfaceImpl.MeteoData=INFO
|
|
||||||
|
|
||||||
# Messaging MSG
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.MSG.MessagingDialog=INFO
|
|
||||||
#log4j.logger.MSG.MessagingModel=INFO
|
|
||||||
|
|
||||||
# AudioVideoManagement AVM
|
|
||||||
###########################################################
|
|
||||||
# AVM AudioSettings
|
|
||||||
#log4j.logger.AVM.AudioSettingsDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.AudioSettingsAvailStreamsModel=DEBUG
|
|
||||||
#log4j.logger.AVM.AudioSettingsUsedStreamsModel=DEBUG
|
|
||||||
|
|
||||||
# AVM TopicEditor
|
|
||||||
#log4j.logger.AVM.AvmSequenceModel=DEBUG
|
|
||||||
|
|
||||||
# AVM AVMenuEdit
|
|
||||||
#log4j.logger.AVM.Plugins.Gui.Avm.MenuEdit=DEBUG
|
|
||||||
#log4j.logger.AVM.AvailableStreamsModel=DEBUG
|
|
||||||
#log4j.logger.AVM.UsedStreamsModel=DEBUG
|
|
||||||
#log4j.logger.AVM.ChooseMenu=DEBUG
|
|
||||||
#log4j.logger.AVM.AudioVideoManagementEdit=DEBUG
|
|
||||||
#log4j.logger.AVM.AudioVideoManagementDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.MenuViewModel=DEBUG
|
|
||||||
#log4j.logger.AVM.NewMenu=DEBUG
|
|
||||||
|
|
||||||
# AVM CNR
|
|
||||||
#log4j.logger.AVM.Plugins.Gui.Avm.CombatNetRadio=DEBUG
|
|
||||||
#log4j.logger.AVM.CombatNetRadioDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.CombatNetRadioDialogModel=DEBUG
|
|
||||||
#log4j.logger.AVM.EditCombatNetRadioDialog=DEBUG
|
|
||||||
|
|
||||||
# AVM CNR FrequencyPlanning
|
|
||||||
#log4j.logger.AVM.Plugins.Gui.Avm.CombatNetRadio=DEBUG
|
|
||||||
#log4j.logger.AVM.FrequencyPlanningDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.FrequencyPlanningDialogModel=DEBUG
|
|
||||||
#log4j.logger.AVM.InitFrequencyPlanningDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.EditFrequencyPlanningDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.EditFrequencyPlanningDataModel=DEBUG
|
|
||||||
#log4j.logger.AVM.EditFrequencyPlanningResourceDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.EditFrequencyPlanningResourceDataModel=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
# AVM Eloka
|
|
||||||
#log4j.logger.AVM.Plugins.Gui.avm.Eloka=DEBUG
|
|
||||||
#log4j.logger.AVM.ElokaDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.ElokaEditDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.ElokaModel=DEBUG
|
|
||||||
|
|
||||||
# AVM MobileVideoSystem
|
|
||||||
#log4j.logger.AVM.Plugins.Gui.Avm.MobileVideoSystem=DEBUG
|
|
||||||
#log4j.logger.AVM.MvsDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.EditVideoTeamDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.MvsModel=DEBUG
|
|
||||||
#log4j.logger.AVM.MvsVideoTeamDialog=DEBUG
|
|
||||||
|
|
||||||
# AVM TVC
|
|
||||||
#log4j.logger.AVM.Plugins.Gui.Avm.CombatNetRadio=DEBUG
|
|
||||||
#log4j.logger.AVM.TrainingVoiceCommunicationDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.EditTrainingVoiceCommunicationDialog=DEBUG
|
|
||||||
#log4j.logger.AVM.TrainingVoiceCommunicationDialogModel=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# OPM
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.OPM.Plugins.Gui.Opm=INFO
|
|
||||||
#log4j.logger.OPM.Plugins.Gui.Opm.Edit=INFO
|
|
||||||
#log4j.logger.OPM.Plugins.Gui.Opm.Overview=INFO
|
|
||||||
#log4j.logger.OPM.Plugins.Gui.Opm.OpmCombobox=INFO
|
|
||||||
#log4j.logger.OPM.Plugins.Gui.Opm.Settings=INFO
|
|
||||||
#log4j.logger.OPM.Plugins.Gui.Opm.SettingsDialog=INFO
|
|
||||||
#log4j.logger.OPM.LoginDialog=INFO
|
|
||||||
#log4j.logger.OPM.SettingsGroup=DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
# PWS
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.PWS.LtsProjetionWorkstation=INFO
|
|
||||||
#log4j.logger.PWS.ControlDialog=INFO
|
|
||||||
|
|
||||||
# Online Help
|
|
||||||
#log4j.logger.OLH.onlineHelp=INFO
|
|
||||||
|
|
||||||
# ServiceMonitor
|
|
||||||
###########################################################
|
|
||||||
#log4j.logger.ServiceMonitorDialog=INFO
|
|
||||||
#log4j.logger.ServiceMonitorBiteModel=INFO
|
|
||||||
#log4j.logger.ServiceMonitorManipulationModel=INFO
|
|
||||||
#log4j.logger.BasePlayerModel=DEBUG
|
|
||||||
#log4j.logger.PartyEquipmentCheckDialog=DEBUG
|
|
||||||
#log4j.logger.SingleServiceEquipmentCheckDialog=DEBUG
|
|
||||||
|
|
||||||
# Appnd_File
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.file=Lts::RollingFileAppender
|
|
||||||
log4j.appender.file.MaxFileSize=100MB
|
|
||||||
log4j.appender.file.MaxBackupIndex=9
|
|
||||||
#log4j.appender.file.file=${LOG4QT_LOGDIR}/${LOG4QT_USER}_OpApp.log
|
|
||||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
|
||||||
|
|
||||||
|
|
||||||
# Appnd_Console
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
|
||||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.stdout.layout.ConversionPattern= %d %-5p %c{1} |#| %m (%-.30F:%L) %n
|
|
||||||
|
|
||||||
#log4j.appender.stdout.layout.ConversionPattern= %d %-5p %-30c |#| %m (%-.30F:%L) %n
|
|
||||||
|
|
||||||
|
|
||||||
# Appnd_Syslog
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
|
||||||
log4j.appender.syslog.Threshold=ERROR
|
|
||||||
log4j.appender.syslog.SysLogHost=localhost
|
|
||||||
log4j.appender.syslog.Facility=LOCAL7
|
|
||||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
|
||||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
|
||||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
|
||||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
|
||||||
|
|
||||||
|
|
||||||
###########################################################
|
|
||||||
###########################################################
|
|
||||||
###########################################################
|
|
||||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
|
||||||
# TRACE,
|
|
||||||
# DEBUG,
|
|
||||||
# INFO,
|
|
||||||
# WARN,
|
|
||||||
# ERROR
|
|
||||||
# FATAL
|
|
||||||
#
|
|
||||||
# d = date/time
|
|
||||||
# p = priority (Level)
|
|
||||||
# c = category/channel
|
|
||||||
# m = message
|
|
||||||
# F = file
|
|
||||||
# L = line
|
|
||||||
# n = platform dependent line separator character or characters.
|
|
||||||
# ....
|
|
||||||
#
|
|
||||||
# Examples for console:
|
|
||||||
# a)
|
|
||||||
# %d %p %c #%m# (%.50F:%L)%n
|
|
||||||
# date/time
|
|
||||||
# priority
|
|
||||||
# category/channel
|
|
||||||
# #message#
|
|
||||||
# (Maximal 50Character des Filename von rechts:Line)
|
|
||||||
# line separator
|
|
||||||
#
|
|
||||||
# b)
|
|
||||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
|
||||||
# date/time
|
|
||||||
# (Maximal 15Character des Filename von rechts:Line)
|
|
||||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
|
||||||
# category/channel
|
|
||||||
# message
|
|
||||||
# line separator
|
|
||||||
#
|
|
||||||
@@ -1,529 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* main for OperatorApplication
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <LtsSession/lts_session.h>
|
|
||||||
#include <LtsSession/lts_session_manager.h>
|
|
||||||
#include <LtsAppManager/lts_app_manager.h>
|
|
||||||
#include <LtsPluginManager/lts_plugin_loader.h>
|
|
||||||
#include <LtsSession/lts_session_data.h>
|
|
||||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
|
||||||
#include <LtsMultiMonitor/lts_multi_monitor.h>
|
|
||||||
#include <StyleManager/style_manager.h>
|
|
||||||
#include <LtsWidgets/lts_global_wait_dialog.h>
|
|
||||||
#include <LtsWidgets/lts_splash.h>
|
|
||||||
#include <LtsWidgets/lts_combo_box.h>
|
|
||||||
#include <LtsProjectionWorkstation/lts_projection_workstation.h>
|
|
||||||
#include <LtsUtilsSettings/settings.h>
|
|
||||||
#include <nglapplication/nglapplication.h>
|
|
||||||
#include <nglapplication/nglloggerhandler.h>
|
|
||||||
#include <nglsettings/nglsettings_settings.h>
|
|
||||||
#include <ngltranslator/ngltranslator.h>
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include <rti/config/Logger.hpp>
|
|
||||||
|
|
||||||
#include <QtGui/QPixmap>
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QtCore/QDir>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtWidgets/QMessageBox>
|
|
||||||
#include <QSurfaceFormat>
|
|
||||||
#include <QScrollerProperties>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QNetworkProxy>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QInputDevice>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
|
|
||||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CmdLineParser()
|
|
||||||
: LtsCommandLineParser(ProvideCommandLineParameterOptions(CreateDomainIdFromIp | DomainId | ExerciseId | TcpConnectionUrl))
|
|
||||||
{
|
|
||||||
addOption({{QStringLiteral("a"), QStringLiteral("application")},
|
|
||||||
QStringLiteral("Specify the initial application to start (Default: Situation [Demo / Dev - otherwise NOT SPECIFIED => starts AppChooser]"), QStringLiteral("Application"),
|
|
||||||
QStringLiteral("Situation")
|
|
||||||
}); // TODO: remove default on release
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("b"), QStringLiteral("basePlugin")},
|
|
||||||
QStringLiteral("Base Project Plugin Iid to start the application with (Default: <not specified>)"), QStringLiteral("Base Project Plugin Iid"),
|
|
||||||
QString()
|
|
||||||
}); // TODO: remove default on release
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("s"), QStringLiteral("stylePlugin")},
|
|
||||||
QStringLiteral("Style Plugin to start the application with (Default: rme.light)"), QStringLiteral("Style Plugin Iid"),
|
|
||||||
QStringLiteral("rme.light")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("u"), QStringLiteral("username")},
|
|
||||||
QStringLiteral("Preset Username to skip login (also specify -p !)"),
|
|
||||||
QStringLiteral("username")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("x"), QStringLiteral("tabletmode")},
|
|
||||||
QStringLiteral("Enforce Tablet Mode"),
|
|
||||||
QStringLiteral("false")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("w"), QStringLiteral("workstationmode")},
|
|
||||||
QStringLiteral("Enforce Workstation Mode"),
|
|
||||||
QStringLiteral("false")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("q"), QStringLiteral("qos_file")},
|
|
||||||
QStringLiteral("Define QoS Profile "),
|
|
||||||
QStringLiteral("qos_file")
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("p"), QStringLiteral("password")},
|
|
||||||
QStringLiteral("Preset Password to skip login (also specify -u !)"),
|
|
||||||
QStringLiteral("password")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("k"), QStringLiteral("skipScreen")},
|
|
||||||
QStringLiteral("Tell the Multi Monitor mode to not put anything on the screen with id n (example: 1 (skips entire screen 1)) - or on sub screen 0 or 1 (left or right) for ultra wide screens (example: 1.1 (skips the right side of screen 1)) (Default: (none))"),
|
|
||||||
QStringLiteral("screen id"),
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("m"), QStringLiteral("multi-monitor-mode")},
|
|
||||||
QStringLiteral("Use the Multi Monitor mode to place Base Layouts on Screens in Fullscreen")
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
addOption({QStringLiteral("dbgmmm"),
|
|
||||||
QStringLiteral("Start the multi-monitor-mode with reduced size for use on development maschines")
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("r"), QStringLiteral("replayId")},
|
|
||||||
QStringLiteral("Default: -1"),
|
|
||||||
QStringLiteral("Replay ID"),
|
|
||||||
QStringLiteral("-1")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({{QStringLiteral("l"), QStringLiteral("lang")},
|
|
||||||
QStringLiteral("Language iso code to use (de_DE, en_GB, en_US)"),
|
|
||||||
QStringLiteral("<locale iso code>")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({QStringLiteral("ignore-plugins"),
|
|
||||||
QStringLiteral("Ignore these plugins, which otherwise would be loaded, "
|
|
||||||
"specified by apps.json of the selected Base Plugin. "
|
|
||||||
"Example: \"--ignore-plugins data:avm,data:bdv,gui:avm\""),
|
|
||||||
QStringLiteral("ignore-plugins") // <= value
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({QStringLiteral("projection"),
|
|
||||||
QStringLiteral("Application is started on an Projection Workstation."),
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({QStringLiteral("check-requirements"),
|
|
||||||
QStringLiteral("Lets the Plugin Loader check if every App's requirements are met before starting"),
|
|
||||||
});
|
|
||||||
addOption({QStringLiteral("enable-experimental-web-platform-features"),
|
|
||||||
QString(),
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({QStringLiteral("script"),
|
|
||||||
QStringLiteral("Id of a script. The script has to exist in the given exercise."),
|
|
||||||
QStringLiteral("ScriptId"),
|
|
||||||
QStringLiteral("0")
|
|
||||||
});
|
|
||||||
|
|
||||||
addOption({QStringLiteral("place-script-screens"),
|
|
||||||
QStringLiteral("Let the screen 1 and screen 2 of the script-editor be placed automatically on startup.")
|
|
||||||
});
|
|
||||||
|
|
||||||
m_additionalHelpStr =
|
|
||||||
QStringLiteral("\n\n\e[33m example OWS : %1 -m -a0 -d1 -b legatus -t EXCTDS01:7400 -l de_DE \n\n\e[0m").arg(QCoreApplication::arguments().at(0));
|
|
||||||
|
|
||||||
// fprintf(stdout, "\n\n\e[33m example OWS : %s -m -a0 -d1 -b legatus -t EXCTDS01:7400 -l de_DE \n\n\e[0m", QCoreApplication::arguments().at(0).toLatin1().data());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QString operatorName() const { return value(QStringLiteral("u")); }
|
|
||||||
QString password() const { return value(QStringLiteral("p")); }
|
|
||||||
int replayId() const { return value(QStringLiteral("r")).toInt(); }
|
|
||||||
QString projectPluginIid() const { return value(QStringLiteral("b")); }
|
|
||||||
QString stylePluginIid() const { return value(QStringLiteral("s")); }
|
|
||||||
int applicationId() const { bool idk = false; int id = value(QStringLiteral("a")).toInt(&idk); if (!idk) { return -1; } return id; }
|
|
||||||
bool multiMonitorMode() const { return isSet(QStringLiteral("m")); }
|
|
||||||
bool isProjectionWorkstation() const { return isSet(QStringLiteral("projection")); }
|
|
||||||
bool isForcedTabletMode() const { return isSet(QStringLiteral("x")); }
|
|
||||||
bool isForcedWSMode() const { return isSet(QStringLiteral("w")); }
|
|
||||||
QString langIsoCode() const { return value(QStringLiteral("l")); }
|
|
||||||
QStringList ignoredPlugins() const { return value(QStringLiteral("ignore-plugins")).split(QLatin1Char(','), Qt::SkipEmptyParts); }
|
|
||||||
bool checkRequirements() const { return isSet(QStringLiteral("check-requirements")); }
|
|
||||||
QString skipScreen() const { return value(QStringLiteral("k")); }
|
|
||||||
QString qosFile() const { return value(QStringLiteral("q")).size() > 0 ? value(QStringLiteral("q")) : QString(); }
|
|
||||||
int scriptId() const { return value(QStringLiteral("script")).toInt(); }
|
|
||||||
bool placeScriptScreens() const { return isSet(QStringLiteral("place-script-screens")); }
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
bool debugMultiMonitorMode() const { return isSet(QStringLiteral("dbgmmm")); }
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
int main(int argc, char **argv) // TODO: json strings to lower
|
|
||||||
{
|
|
||||||
// (legacy: qsrand(time(nullptr));) — the Qt5 global RNG (qrand/qsrand) does not exist in Qt6.
|
|
||||||
// QRandomGenerator::global() is auto-seeded (non-deterministically) by Qt, and calling ->seed()
|
|
||||||
// on the global/system generator aborts in Qt 6.10 ("Attempted to overwrite a QRandomGenerator to
|
|
||||||
// system() or global()"), so no explicit seed is needed here.
|
|
||||||
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
|
|
||||||
|
|
||||||
QScrollerProperties props;
|
|
||||||
props.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
|
|
||||||
props.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QScrollerProperties::OvershootAlwaysOff);
|
|
||||||
|
|
||||||
QScrollerProperties::setDefaultScrollerProperties(props);
|
|
||||||
|
|
||||||
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
|
||||||
//LtsApp app(argc, argv);
|
|
||||||
NGLApplication app(argc, argv);
|
|
||||||
app.createLogger("opApp");
|
|
||||||
QApplication::setQuitOnLastWindowClosed(false); // we are cool enough to handle it ourselves 8)
|
|
||||||
// Qt::AA_UseHighDpiPixmaps: no-op since Qt6 (high-DPI pixmaps are always enabled)
|
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy()); // do NOT use proxies anywhere!
|
|
||||||
|
|
||||||
NGL::LoggerHandler *lh = NGL::LoggerHandler::getLoggerHandler();
|
|
||||||
if (lh)
|
|
||||||
{
|
|
||||||
const QByteArray postfix = lh->loggerNamePostfix().toLocal8Bit() + "_dds_";
|
|
||||||
const QByteArray prefix = lh->loggerNamePrefix().toLocal8Bit();
|
|
||||||
|
|
||||||
rti::config::Logger &ddsLogger = rti::config::Logger::instance();
|
|
||||||
//ddsLogger.output_file(fdopen(STDOUT_FILENO, "w"));
|
|
||||||
ddsLogger.output_file_set(postfix.data(), prefix.data(), 10 * 1024 * 1024, 10);
|
|
||||||
ddsLogger.verbosity(rti::config::Verbosity_def::WARNING);
|
|
||||||
//ddsLogger.verbosity_by_category(rti::config::LogCategory_def::COMMUNICATION, rti::config::Verbosity_def::STATUS_ALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: replace all exit(x) with qApp.quit() and an error msg
|
|
||||||
|
|
||||||
LtsWidgets::LtsGlobalWaitDialog::getInstance()->setVisible(false); // avoid wait screen, we have the splash for this reason!
|
|
||||||
|
|
||||||
#ifdef __linux__
|
|
||||||
// svcSituationRep - pgrep/pkill length limitation
|
|
||||||
QProcess::startDetached(QLatin1String("pkill -9 svcSituationRep")); // kill it!
|
|
||||||
QProcess::startDetached(QLatin1String("pkill -9 ffmpeg")); // otherwise a stray ffmpeg may record until the the disk is full
|
|
||||||
#elif _WIN32
|
|
||||||
QProcess::startDetached(QLatin1String("taskkill /im svcSituationReplay /f"));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Parse Options
|
|
||||||
CmdLineParser options;
|
|
||||||
if (!options.init())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Set Translation
|
|
||||||
|
|
||||||
QString langIsoCode = options.langIsoCode();
|
|
||||||
if (langIsoCode.isEmpty())
|
|
||||||
langIsoCode = QLocale::system().name();
|
|
||||||
NGL::setTranslationLocale(langIsoCode.toLatin1());
|
|
||||||
|
|
||||||
|
|
||||||
// Set Style
|
|
||||||
QString stylePluginName = options.stylePluginIid();
|
|
||||||
if (stylePluginName.isEmpty())
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "No Style Plugin Iid specified - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// .. to keep some compatibility to old resource structure TODO: rm !
|
|
||||||
QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/style/icons/")));
|
|
||||||
QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/style/"))); // FIXME: does qt check for recursion ??
|
|
||||||
|
|
||||||
|
|
||||||
LtsUtils::StyleManager::getInstance()->loadStyle(stylePluginName);
|
|
||||||
|
|
||||||
|
|
||||||
// Load Plugins
|
|
||||||
LtsPluginManager::LtsPluginLoader *pluginLoader = LtsPluginManager::LtsPluginLoader::getInstance();
|
|
||||||
|
|
||||||
QString projectPluginName = options.projectPluginIid();
|
|
||||||
|
|
||||||
if (projectPluginName.isEmpty())
|
|
||||||
{
|
|
||||||
bool k;
|
|
||||||
projectPluginName = QInputDialog::getText(nullptr,
|
|
||||||
QCoreApplication::tr("No Project Plugin specified"),
|
|
||||||
QCoreApplication::tr("Please specify a Project Plugin:"), QLineEdit::Normal,
|
|
||||||
QString(), &k); // blocking, no event loop needed
|
|
||||||
|
|
||||||
if (!k || projectPluginName.isEmpty())
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "No Project Plugin Iid specified - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load project plugin
|
|
||||||
if (!pluginLoader->loadPlugins(LtsPluginManager::PluginType::PROJECT, nullptr, {projectPluginName}))
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Error loading Project Plugin - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsUtils::ProjectSettings::initFromFile(QStringLiteral(":project/project_settings.json"));
|
|
||||||
|
|
||||||
// Setup Application
|
|
||||||
if (options.multiMonitorMode())
|
|
||||||
LtsMultiMonitor::LtsMultiMonitor::getInstance()->setEnableMultiMonitorMode();
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
if (options.debugMultiMonitorMode())
|
|
||||||
LtsMultiMonitor::LtsMultiMonitor::getInstance()->setDebugMultiMonitorMode();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// show splash
|
|
||||||
LtsWidgets::Splash::getInstance()->show();
|
|
||||||
|
|
||||||
LtsAppDescriptor::App applicationId = LtsAppDescriptor::LtsAppDescriptor::appFromInteger(options.applicationId());
|
|
||||||
int exerciseId = options.exerciseId(); // -1 = invalid, 0 = admin, >0 = exercise
|
|
||||||
int replayId = options.replayId(); // -1 = invalid, TODO: comment doku
|
|
||||||
int scriptId = options.scriptId(); // <0 = invalid, 0 = default = ignore, >0 script
|
|
||||||
QString operatorName = options.operatorName();
|
|
||||||
QString password = options.password();
|
|
||||||
QStringList qos_file = QStringList(options.qosFile());
|
|
||||||
|
|
||||||
// TODO: log4cxx/NGLLlogger does not flush here !! messages not seen !
|
|
||||||
|
|
||||||
if (scriptId < 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Given scriptId " << scriptId << " is invalid - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptId > 0 && applicationId != LtsAppDescriptor::App::Scripts)
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "ScriptId set but given app is not Scripts - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptId > 0 && exerciseId < 1)
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "ScriptId set but no exercise is given - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scriptId > 0 && exerciseId > 0 && applicationId == LtsAppDescriptor::App::Scripts)
|
|
||||||
{
|
|
||||||
LtsSessionData::LtsSessionData::getInstance()->setScriptId(scriptId);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.placeScriptScreens() && applicationId != LtsAppDescriptor::App::Scripts)
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "PlaceScriptScreensn is set but given app is not Scripts - abort.";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsSessionData::LtsSessionData::getInstance()->setPlaceScriptScreens(options.placeScriptScreens());
|
|
||||||
|
|
||||||
if (operatorName.isEmpty() != password.isEmpty()) // check for xor and warn user
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Specify -u if -p is specified & vise versa - abort.";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.domainId() < 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Invalid configuration for domainId (" << options.domainId() << ") from LtsConfig - abort.";
|
|
||||||
QMessageBox::critical(nullptr, QCoreApplication::tr("Invalid Domain Id"), QCoreApplication::tr("Domain #%1 is not valid - abort.").arg(options.domainId()));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
LtsSessionData::LtsSessionData *sessionData = LtsSessionData::LtsSessionData::getInstance();
|
|
||||||
|
|
||||||
sessionData->setDomainIdPreset(options.domainId());
|
|
||||||
sessionData->setRequestedAppId(applicationId);
|
|
||||||
|
|
||||||
if (options.useTcpConnection())
|
|
||||||
sessionData->setTcpConnectionUrl(options.tcpConnectionUrl());
|
|
||||||
|
|
||||||
if (options.checkRequirements())
|
|
||||||
sessionData->setDebugFlagValue(QStringLiteral("PluginManager.CheckAppRequirements"), true);
|
|
||||||
|
|
||||||
// load JSON app description file
|
|
||||||
QFile appsFile(QStringLiteral(":project/apps.json")); // TODO: convert Json => Binary Json
|
|
||||||
|
|
||||||
if (!appsFile.open(QFile::ReadOnly))
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Could not read App Description File";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList lastErrors;
|
|
||||||
QString loginPluginIid;
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescriptionVector appDescs = LtsAppDescriptor::LtsAppDescriptor::getAppDescriptionVector(appsFile.readAll(),
|
|
||||||
lastErrors,
|
|
||||||
options.ignoredPlugins(),
|
|
||||||
loginPluginIid);
|
|
||||||
|
|
||||||
if (loginPluginIid.isEmpty())
|
|
||||||
loginPluginIid = QStringLiteral("opm.login");
|
|
||||||
|
|
||||||
QString skipScreen = options.skipScreen();
|
|
||||||
|
|
||||||
int skipScreenId = -1;
|
|
||||||
int skipSubScreenId = -1;
|
|
||||||
|
|
||||||
if (!skipScreen.isEmpty())
|
|
||||||
{
|
|
||||||
QStringList skipScreenList(skipScreen.split(QLatin1Char('.'), Qt::SkipEmptyParts));
|
|
||||||
|
|
||||||
int skipScreenListCount = skipScreenList.count();
|
|
||||||
|
|
||||||
if (skipScreenListCount > 2)
|
|
||||||
{
|
|
||||||
qWarning() << "invalid skip screen syntax:" << skipScreen;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipScreenListCount > 0)
|
|
||||||
{
|
|
||||||
bool k = false;
|
|
||||||
skipScreenId = skipScreenList.at(0).toInt(&k);
|
|
||||||
|
|
||||||
if (!k)
|
|
||||||
{
|
|
||||||
qWarning() << "invalid skip screen syntax:" << skipScreen;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skipScreenListCount > 1)
|
|
||||||
{
|
|
||||||
bool k = false;
|
|
||||||
skipSubScreenId = skipScreenList.at(1).toInt(&k);
|
|
||||||
|
|
||||||
if (!k)
|
|
||||||
{
|
|
||||||
qWarning() << "invalid skip screen syntax:" << skipScreen;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsMultiMonitor::LtsMultiMonitor::getInstance()->setSkipScreen(skipScreenId, skipSubScreenId);
|
|
||||||
|
|
||||||
appsFile.close();
|
|
||||||
|
|
||||||
if (!lastErrors.isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox::critical(nullptr, QString(), lastErrors.join(QStringLiteral("\r\n\r\n")));
|
|
||||||
// TODO: log precise msg !!
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(options.isForcedTabletMode())
|
|
||||||
sessionData->setAsTablet();
|
|
||||||
else if (options.isForcedWSMode())
|
|
||||||
sessionData->setAsTablet(false);
|
|
||||||
else if (std::any_of(QInputDevice::devices().cbegin(), QInputDevice::devices().cend(),
|
|
||||||
[](const QInputDevice *dev) { return dev && dev->type() == QInputDevice::DeviceType::TouchScreen; }))
|
|
||||||
sessionData->setAsTablet();
|
|
||||||
LtsWidgets::LtsComboBox::setUseSelectionDialog(sessionData->isTablet());
|
|
||||||
|
|
||||||
LtsAppManager::LtsAppManager *appManager = LtsAppManager::LtsAppManager::getInstance();
|
|
||||||
appManager->setAvailableApps(appDescs);
|
|
||||||
|
|
||||||
|
|
||||||
// Projection Specific Setup
|
|
||||||
if (options.isProjectionWorkstation())
|
|
||||||
{
|
|
||||||
if (operatorName.isEmpty() && password.isEmpty())
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Projection-User & Password has to be specified when --projection option is active!";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
applicationId = LtsAppDescriptor::App::Situation;
|
|
||||||
|
|
||||||
LtsProjectionWorkstation::LtsProjectionWorkstation::getInstance()->setProjectionOperatorPreset(operatorName, password);
|
|
||||||
}
|
|
||||||
// Normal Setup
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (applicationId == LtsAppDescriptor::App::Login)
|
|
||||||
INFO_LOG(app.baseLogger()) << "No Application specified - starting with App Chooser.";
|
|
||||||
|
|
||||||
// TODO: replayid can not life without exerciseId
|
|
||||||
if (exerciseId >= 0 && replayId >= 0) // do not set both!
|
|
||||||
{
|
|
||||||
ERROR_LOG(app.baseLogger()) << "Use either -e (exercise) or -r (replay) - abort.";
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!operatorName.isEmpty() && !password.isEmpty())
|
|
||||||
{
|
|
||||||
sessionData->setOperatorPreset(operatorName, password); // if -u and -p (no Login window !)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exerciseId == 0) // Admin Session was requested explicitly
|
|
||||||
{
|
|
||||||
//sessionManager->setGlobalSessionVisible();
|
|
||||||
sessionData->setPartitionPreset(exerciseId, IDL::PartitionType::Global);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!qos_file.isEmpty()) // use defined qos file
|
|
||||||
{
|
|
||||||
//sessionManager->setGlobalSessionVisible();
|
|
||||||
DEBUG_LOG(app.baseLogger()) << "QOS -> using new file" << qos_file.join(QStringLiteral(","));
|
|
||||||
sessionData->setQosFile(qos_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exerciseId > 0) // non Admin => Exercise
|
|
||||||
sessionData->setPartitionPreset(exerciseId, IDL::PartitionType::Exercise);
|
|
||||||
|
|
||||||
if (replayId >= 0) // Replay
|
|
||||||
sessionData->setPartitionPreset(replayId, IDL::PartitionType::Replay);
|
|
||||||
}
|
|
||||||
|
|
||||||
appManager->setLoginPluginIid(loginPluginIid);
|
|
||||||
appManager->setMainApp(applicationId);
|
|
||||||
if (applicationId == LtsAppDescriptor::App::ThpSituationReplay)
|
|
||||||
{
|
|
||||||
LtsSessionData::LtsSessionData::getInstance()->setVisibleParties({});
|
|
||||||
LtsSessionData::LtsSessionData::getInstance()->setOperatorRights({-1});
|
|
||||||
QTimer::singleShot(0, appManager, [qos_file, appManager]()
|
|
||||||
{
|
|
||||||
LtsSession::DdsConnectionParams params;
|
|
||||||
params.domainId = 1;
|
|
||||||
params.exerciseId = 2;
|
|
||||||
params.partitionId = 2;
|
|
||||||
if (!qos_file.isEmpty())
|
|
||||||
params.qos_file = qos_file;
|
|
||||||
|
|
||||||
params.partitionType = IDL::PartitionType::Replay;
|
|
||||||
appManager->createApp(LtsAppDescriptor::App::Situation, params, {}, false, true);
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
appManager->showLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Startup Application
|
|
||||||
STARTUP_LOG(app.baseLogger());
|
|
||||||
int iRet = app.exec();
|
|
||||||
SHUTDOWN_LOG(app.baseLogger());
|
|
||||||
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#include <WINVER.H>
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION @OPAPP_VERSION_INFO@
|
|
||||||
PRODUCTVERSION @OPAPP_VERSION_INFO@
|
|
||||||
FILEFLAGSMASK 0x0L
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
FILEOS VOS_NT_WINDOWS32
|
|
||||||
FILETYPE VFT_APP
|
|
||||||
FILESUBTYPE VFT2_UNKNOWN
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040704b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "Rheinmetall Electronics GmbH"
|
|
||||||
VALUE "FileDescription", "Operator Application (64bit)"
|
|
||||||
VALUE "FileVersion", "@OPAPP_VERSION_INFO@"
|
|
||||||
VALUE "InternalName", "OpApp"
|
|
||||||
VALUE "LegalCopyright", "Copyright © 2018 Rheinmetall Electronics GmbH. Alle Rechte vorbehalten"
|
|
||||||
VALUE "OriginalFilename", "OperatorApplication.exe"
|
|
||||||
VALUE "ProductName", "Operator Application"
|
|
||||||
VALUE "ProductVersion", "@OPAPP_VERSION_INFO@"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x407, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
#
|
|
||||||
# THP-Viewer
|
|
||||||
#
|
|
||||||
ADD_SUBDIRECTORY(THP-Starter)
|
|
||||||
FIND_PACKAGE(VLC REQUIRED)
|
|
||||||
|
|
||||||
SET(thp_viewer_SRCS
|
|
||||||
main.cpp
|
|
||||||
thp_plugin_provider.cpp
|
|
||||||
thp_plugin_provider.h
|
|
||||||
thp_situation_filter_interface_impl.cpp
|
|
||||||
thp_situation_filter_interface_impl.h
|
|
||||||
thp_viewer.cpp
|
|
||||||
thp_viewer.h
|
|
||||||
|
|
||||||
thpwidgets/thp_audio_video_widget.cpp
|
|
||||||
thpwidgets/thp_audio_video_widget.h
|
|
||||||
thpwidgets/thp_audio_video_widget_p.h
|
|
||||||
thpwidgets/thp_building_settings.cpp
|
|
||||||
thpwidgets/thp_building_settings.h
|
|
||||||
thpwidgets/thp_building_widget.cpp
|
|
||||||
thpwidgets/thp_building_widget.h
|
|
||||||
thpwidgets/thp_html_widget.cpp
|
|
||||||
thpwidgets/thp_html_widget.h
|
|
||||||
thpwidgets/thp_pdf_widget.cpp
|
|
||||||
thpwidgets/thp_pdf_widget.h
|
|
||||||
thpwidgets/thp_situation_building_base.h
|
|
||||||
thpwidgets/thp_situation_building_base.cpp
|
|
||||||
thpwidgets/thp_situation_filter_aes.cpp
|
|
||||||
thpwidgets/thp_situation_filter_aes.h
|
|
||||||
thpwidgets/thp_situation_filter_building_components.cpp
|
|
||||||
thpwidgets/thp_situation_filter_building_components.h
|
|
||||||
thpwidgets/thp_situation_filter_collapse_expand.cpp
|
|
||||||
thpwidgets/thp_situation_filter_collapse_expand.h
|
|
||||||
thpwidgets/thp_situation_filter_symbol_appearance.cpp
|
|
||||||
thpwidgets/thp_situation_filter_symbol_appearance.h
|
|
||||||
thpwidgets/thp_situation_filter_types.cpp
|
|
||||||
thpwidgets/thp_situation_filter_types.h
|
|
||||||
thpwidgets/thp_situation_widget.cpp
|
|
||||||
thpwidgets/thp_situation_widget.h
|
|
||||||
thpwidgets/thp_zoom_slider.cpp
|
|
||||||
thpwidgets/thp_zoom_slider.h
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_WRAP_UI(thp_viewer_SRCS
|
|
||||||
thp_viewer.ui
|
|
||||||
thpwidgets/thp_audio_video_widget.ui
|
|
||||||
thpwidgets/thp_building_settings.ui
|
|
||||||
thpwidgets/thp_html_widget.ui
|
|
||||||
thpwidgets/thp_pdf_widget.ui
|
|
||||||
thpwidgets/thp_situation_building_base.ui
|
|
||||||
)
|
|
||||||
IF(WIN32)
|
|
||||||
SET(JBN ${JENKINS_BUILD_NUMBER})
|
|
||||||
IF (NOT JENKINS_BUILD_NUMBER)
|
|
||||||
SET(JBN "0")
|
|
||||||
ENDIF()
|
|
||||||
SET(THP_VERSION_INFO "${LTS_VERSION_MAJOR}, ${LTS_VERSION_MINOR}, ${JBN}, ${LTS_VERSION_PATCH}")
|
|
||||||
CONFIGURE_FILE(thp_viewer.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/thp_viewer.rc)
|
|
||||||
LIST(APPEND thp_viewer_SRCS ${CMAKE_CURRENT_BINARY_DIR}/thp_viewer.rc)
|
|
||||||
ENDIF(WIN32)
|
|
||||||
NGL_ADD_APP_ICON(thp_viewer_SRCS)
|
|
||||||
|
|
||||||
NGL_ADD_EXECUTABLE(WS thp_viewer WIN32 ${thp_viewer_SRCS})
|
|
||||||
NGL_INSTALL_TARGET(thp_viewer)
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(thp_viewer
|
|
||||||
PRIVATE
|
|
||||||
${VLC_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
NGL_TARGET_COMPILE_DEFINITIONS(thp_viewer
|
|
||||||
PRIVATE
|
|
||||||
${VLC_DEFINES}
|
|
||||||
)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(thp_viewer
|
|
||||||
$<IF:$<TARGET_EXISTS:ArcGISQt5Hack>,ArcGISQt5Hack,> # make sure it's loaded *before* libEsriCommonQt.so (guard: only linked when the SituationMap viewer is built, matching CentralEffectSimulation)
|
|
||||||
|
|
||||||
${VLC_LIBRARIES}
|
|
||||||
Qt6::Core
|
|
||||||
Qt6::Gui
|
|
||||||
Qt6::PrintSupport
|
|
||||||
Qt6::Svg
|
|
||||||
Qt6::WebEngineCore
|
|
||||||
Qt6::WebEngineWidgets
|
|
||||||
Qt6::Widgets
|
|
||||||
Qt6::Xml
|
|
||||||
|
|
||||||
RmeLightStyleQrc
|
|
||||||
|
|
||||||
AsbData
|
|
||||||
AsbForeignDataPluginThp
|
|
||||||
BuildingViewerCommon
|
|
||||||
FltAesGuiCommon
|
|
||||||
FltAesWidget
|
|
||||||
FltBldgCmpntWidget
|
|
||||||
FltParticipantWidget
|
|
||||||
IsmDataPluginThp
|
|
||||||
LtsCoordTrans
|
|
||||||
LtsCommandLineParser
|
|
||||||
NGLLogger
|
|
||||||
nglsingleapplication
|
|
||||||
ngltools
|
|
||||||
ngltranslator
|
|
||||||
nglwidgets
|
|
||||||
PdmComboBoxGui
|
|
||||||
PpmComboBoxGui
|
|
||||||
SitmapDds
|
|
||||||
SituationReplaySqlite
|
|
||||||
|
|
||||||
svcFlmCommon
|
|
||||||
|
|
||||||
svcAesClient
|
|
||||||
svcBldClient
|
|
||||||
svcCesClient
|
|
||||||
svcGimClient
|
|
||||||
svcIsmClient
|
|
||||||
svcPpmClient
|
|
||||||
svcPdmClient
|
|
||||||
svcAlmClient
|
|
||||||
)
|
|
||||||
IF(WIN32)
|
|
||||||
# NGL_INSTALL(WS FILES autorun.inf DESTINATION bin)
|
|
||||||
# NGL_INSTALL(WS FILES readme.win32.en_US.txt DESTINATION bin)
|
|
||||||
# NGL_INSTALL(WS FILES readme.win32.de_DE.txt DESTINATION bin)
|
|
||||||
ENDIF()
|
|
||||||
NGL_INSTALL(WS FILES log4cxx_thp_viewer.props DESTINATION bin)
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(SitMapReplayTest)
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
#
|
|
||||||
# Hinweise für das THP
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
N. Thoden, 12.03.2020
|
|
||||||
|
|
||||||
Das TakeHomePackage (für Windows) besteht aus 3 Komponenten:
|
|
||||||
============================================================
|
|
||||||
|
|
||||||
1) den THP-Viewer / THP-Starter
|
|
||||||
(inkl. Qt ; ohne MSVCRuntime, z.B. msvcr120.dll, in C:\Windows\system32 !?)
|
|
||||||
http://jenkins-master.sl.defence-elec.de:8080/job/ahtc_OC-Tablet/
|
|
||||||
thp.tgz
|
|
||||||
2) die Kartendaten
|
|
||||||
(evtl. für den Datenträger reduziert in Bezug auf die Speichergröße)
|
|
||||||
3) die Topic-Daten (Video, Audio, DB-Abzug...)
|
|
||||||
|
|
||||||
|
|
||||||
Woher kommt was?
|
|
||||||
================
|
|
||||||
1) Der THP-Viewer / THP-Starter
|
|
||||||
Kann aus der CI-Umgebung (Jenkins) heruntergeladen werden (thp.tgz)
|
|
||||||
Am besten mit 7Zip entpackt werden:
|
|
||||||
(tgz -> gepackt und anschliessend komprimiert)
|
|
||||||
- Per Kontext-Menue "entpacken nach hier"
|
|
||||||
- die resultierende Datei "thp' "entpacken nach thp~".
|
|
||||||
Dann sollte ein Verzeichnis "thp" MIT diversen Unterverzeichnissen entstehen.
|
|
||||||
|
|
||||||
Das THP-Verzeichnis wird auf jeder Workstation im Ordner /opt/THP als Quelle für den USB-Datentraeger bereitgestellt.
|
|
||||||
|
|
||||||
2) Diese werden manuell für das THP bereitgestellt (meist als tpk-Datei).
|
|
||||||
|
|
||||||
3) Die Topic-Daten werden in der OpApp mit "Präsentation exportieren" erzeugt.
|
|
||||||
Sie werden unter /tmp/THP-Export generiert.
|
|
||||||
|
|
||||||
|
|
||||||
Woher kommt das Verzeichnis 'Maps'?
|
|
||||||
===================================
|
|
||||||
Der Verzeichnisname 'Maps' ist fest und darf nicht verändert werden.
|
|
||||||
Es müssen die für das Medium (CD, DVD, Stick..) passenden Basiskarten/Kartendaten hinein.
|
|
||||||
Das sind also z.B.
|
|
||||||
- 2020-03-03_UaeAerial_32639_Lvl6.tpk
|
|
||||||
- 2020-03-03_UaeAerial_WebMerc_Lvl15.tpk
|
|
||||||
- 2020-03-03_UaeTopo_32639_Lvl6.tpk
|
|
||||||
- 2020-03-03_UaeTopo_WebMerc_Lvl15.tpk
|
|
||||||
- AHTC_utm_dgm_surface_wgs84.tif
|
|
||||||
|
|
||||||
Das layerMapping.json hat nun die Aufgabe, diese (für das Übungsgebiet) spezifischen
|
|
||||||
Dateinamen zu abstrahieren.
|
|
||||||
Die bei der Ausführung des THPs geforderten Basiskarten (Annahme: eine Topo und zwei Aerial)
|
|
||||||
können mit Hilfe der layerMapping.json auf eine geringere Anzahl Dateien gemappt werden.
|
|
||||||
|
|
||||||
Basiskarten: Mapping per layerMapping.json
|
|
||||||
in der WS-App: Dateien in Dir 'Maps'
|
|
||||||
-------------- ---------------------
|
|
||||||
- Aerial2 -> 2020-03-03_UaeAerial_32639_Lvl6.tpk
|
|
||||||
- Aerial1 -> 2020-03-03_UaeAerial_32639_Lvl6.tpk
|
|
||||||
- Topo -> 2020-03-03_UaeTopo_32639_Lvl6.tpk
|
|
||||||
|
|
||||||
Best Practise:
|
|
||||||
Daher ergibt es Sinn, eine layerMapping.json in dem Verzeichnis 'Maps' vorzubereiten
|
|
||||||
und beim Zusammengefügen in die darüberliegende Dateiebene zu kopieren.
|
|
||||||
|
|
||||||
|
|
||||||
Wie müssen die 3 Komponenten zusammengefügt werden?
|
|
||||||
===================================================
|
|
||||||
|
|
||||||
Device:
|
|
||||||
- Excersise_6
|
|
||||||
- 1 <- Übungsdaten (Komponenten 3)
|
|
||||||
- ...
|
|
||||||
- index.html <- Übungsdaten (Komponenten 3)
|
|
||||||
- ... <- Übungsdaten (Komponenten 3)
|
|
||||||
|
|
||||||
- Maps <- Kartendaten (Komponenten 2)
|
|
||||||
- *.tpk
|
|
||||||
- [layerMapping.json] <- Sonderfall AHTC 03/2020: Diese Datei in
|
|
||||||
die darüberliegende Ebenen verschieben.
|
|
||||||
- layerMapping.json <- Übungsdaten (Komponenten 2/3)
|
|
||||||
(generiert, Sonderfall AHTC 03/2020:
|
|
||||||
aus 'Maps' hierher transferieren)
|
|
||||||
|
|
||||||
- thp <- thp (Komponenten 1)
|
|
||||||
- resources <- thp (Komponenten 1), hat mal gefehlt)
|
|
||||||
- thv_viewer.exe <- thp (Komponenten 1)
|
|
||||||
- vc.redist.x64.exe <- thp (Komponenten 1), für MSVCRuntime
|
|
||||||
- thp_starter.exe <- thp (Komponenten 1)
|
|
||||||
- autorun.inf <- thp (Komponenten 1)
|
|
||||||
- [wappen.png] <- thp (Komponenten 1 oder 3) optional !?
|
|
||||||
|
|
||||||
|
|
||||||
Logfiles zuir Fehlersuche
|
|
||||||
=========================
|
|
||||||
Ein Logfile befindet sich unter ~Benutzer\AppData\Local\Temp\.
|
|
||||||
Bsp: C:\User\thoden\AppData\Local\Temp\thoden_thp.log
|
|
||||||
C:\User\thoden\AppData\Local\Temp\thoden_thp.log.1
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#
|
|
||||||
# SitMapReplayTest
|
|
||||||
#
|
|
||||||
SET(SRPTEST_SRCS
|
|
||||||
srp_main.cpp
|
|
||||||
srp_main_window.cpp
|
|
||||||
srp_main_window.h
|
|
||||||
../thp_plugin_provider.cpp
|
|
||||||
../thp_plugin_provider.h
|
|
||||||
../thp_situation_filter_interface_impl.cpp
|
|
||||||
../thp_situation_filter_interface_impl.h
|
|
||||||
)
|
|
||||||
NGL_WRAP_UI(SRPTEST_SRCS
|
|
||||||
srp_main_window.ui
|
|
||||||
)
|
|
||||||
NGL_ADD_EXECUTABLE(WS SitMapReplayTest ${SRPTEST_SRCS})
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(SitMapReplayTest
|
|
||||||
SituationReplaySqlite
|
|
||||||
|
|
||||||
ddsconnector
|
|
||||||
Qt6::Core
|
|
||||||
nglapplication
|
|
||||||
SitmapDds
|
|
||||||
|
|
||||||
AsbForeignDataPluginThp
|
|
||||||
BuildingViewerCommon
|
|
||||||
FltAesGuiCommon
|
|
||||||
IsmDataPluginThp
|
|
||||||
|
|
||||||
svcFlmCommon
|
|
||||||
|
|
||||||
svcAesClient
|
|
||||||
svcBldClient
|
|
||||||
svcCesClient
|
|
||||||
svcGimClient
|
|
||||||
svcIsmClient
|
|
||||||
svcPpmClient
|
|
||||||
svcPdmClient
|
|
||||||
)
|
|
||||||
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Main for SitMapReplayTest
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <nglapplication/nglapplication.h>
|
|
||||||
#include <DDS/DDSConnector/dds_connector.h>
|
|
||||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
|
||||||
#include <QNetworkProxy>
|
|
||||||
#include <SituationReplay/main_handler_sqlite.h>
|
|
||||||
#include <SituationMap/situation_map_init.h>
|
|
||||||
#include <SituationMap/Utils/movement_track_manager.h>
|
|
||||||
#include "../thp_plugin_provider.h"
|
|
||||||
#include "srp_main_window.h"
|
|
||||||
#include "ui_srp_main_window.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
|
||||||
NGLApplication app(argc, argv);
|
|
||||||
app.createLogger("SRP");
|
|
||||||
// Qt::AA_UseHighDpiPixmaps: no-op since Qt6 (high-DPI pixmaps are always enabled)
|
|
||||||
|
|
||||||
SituationReplay::ConnectionParams connParams;
|
|
||||||
connParams.domainId = 1;
|
|
||||||
connParams.partitionId = 1;
|
|
||||||
std::shared_ptr<SituationReplay::MainHandlerSqlite> srpMainHandler(new SituationReplay::MainHandlerSqlite);
|
|
||||||
if (!srpMainHandler->initDds(connParams))
|
|
||||||
return 1;
|
|
||||||
// TODO: fixme or trash me
|
|
||||||
SituationReplay::ReplayInformation ri;
|
|
||||||
ri.databaseFilePath = QStringLiteral("dump.sqlite");
|
|
||||||
ri.replayConfigPath = QStringLiteral("dump.json");
|
|
||||||
if (!srpMainHandler->initDb(ri, {}, {}))
|
|
||||||
return 2;
|
|
||||||
|
|
||||||
std::shared_ptr<DDSConnector::DdsConnector> ddsConn = srpMainHandler->ddsReplay();
|
|
||||||
THP::SitMapPluginProvider *pp = new THP::SitMapPluginProvider;
|
|
||||||
pp->init(ddsConn);
|
|
||||||
|
|
||||||
SituationMap::SituationMapInit *smi = new SituationMap::SituationMapInit(nullptr);
|
|
||||||
smi->initPluginProvider(pp);
|
|
||||||
|
|
||||||
QPointer<SituationMap::MovementTrackManager> movementTrackMgr =
|
|
||||||
QPointer<SituationMap::MovementTrackManager>(new SituationMap::MovementTrackManager(smi));
|
|
||||||
|
|
||||||
smi->initAdapter(movementTrackMgr, false);
|
|
||||||
smi->initMap(true, SituationMap::Mode::Mode_2D);
|
|
||||||
|
|
||||||
SituationReplay::MainWindow *mw = new SituationReplay::MainWindow(smi, srpMainHandler->handlerSrp());
|
|
||||||
mw->show();
|
|
||||||
|
|
||||||
int ret = app.exec();
|
|
||||||
|
|
||||||
delete mw;
|
|
||||||
delete smi;
|
|
||||||
delete pp;
|
|
||||||
ddsConn.reset();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* MainWindow for SitMapReplayTest
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "srp_main_window.h"
|
|
||||||
#include "ui_srp_main_window.h"
|
|
||||||
#include <SituationMap/situation_map_init.h>
|
|
||||||
#include <SituationReplay/handler_situation_replay_sqlite.h>
|
|
||||||
|
|
||||||
namespace SituationReplay
|
|
||||||
{
|
|
||||||
MainWindow::MainWindow(SituationMap::SituationMapInit *sitMap,
|
|
||||||
const std::shared_ptr<HandlerSituationReplaySqlite> &srpHandler,
|
|
||||||
QWidget *parent)
|
|
||||||
: QMainWindow(parent)
|
|
||||||
, m_srpHandler(srpHandler)
|
|
||||||
, m_ui(new Ui::SrpMainWindow)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
setCentralWidget(sitMap->getWidget());
|
|
||||||
connect(m_ui->actionStart_Replay, &QAction::triggered, this, &MainWindow::onStartReplay);
|
|
||||||
connect(m_ui->actionStop_Replay, &QAction::triggered, this, &MainWindow::onStopReplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onStartReplay()
|
|
||||||
{
|
|
||||||
const qint64 begin = (time(nullptr) - 60 * 60 * 30) * 1000;
|
|
||||||
const qint64 end = 0;
|
|
||||||
const double pace = 1;
|
|
||||||
m_srpHandler->onStartReplayRequest(begin, end, pace);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::onStopReplay()
|
|
||||||
{
|
|
||||||
m_srpHandler->onStopReplayRequest();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* MainWindow for SitMapReplayTest
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class SrpMainWindow;
|
|
||||||
}
|
|
||||||
namespace SituationMap
|
|
||||||
{
|
|
||||||
class SituationMapInit;
|
|
||||||
}
|
|
||||||
namespace SituationReplay
|
|
||||||
{
|
|
||||||
class HandlerSituationReplaySqlite;
|
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
MainWindow(SituationMap::SituationMapInit *sitMap,
|
|
||||||
const std::shared_ptr<HandlerSituationReplaySqlite> &srpHandler,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
~MainWindow();
|
|
||||||
protected slots:
|
|
||||||
void onStartReplay();
|
|
||||||
void onStopReplay();
|
|
||||||
private:
|
|
||||||
std::shared_ptr<HandlerSituationReplaySqlite> m_srpHandler;
|
|
||||||
Ui::SrpMainWindow *m_ui;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-49
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>SrpMainWindow</class>
|
|
||||||
<widget class="QMainWindow" name="SrpMainWindow">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>800</width>
|
|
||||||
<height>600</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>MainWindow</string>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="centralwidget"/>
|
|
||||||
<widget class="QMenuBar" name="menubar">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>800</width>
|
|
||||||
<height>29</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<widget class="QMenu" name="menuFile">
|
|
||||||
<property name="title">
|
|
||||||
<string>Fi&le</string>
|
|
||||||
</property>
|
|
||||||
<addaction name="actionStart_Replay"/>
|
|
||||||
<addaction name="actionStop_Replay"/>
|
|
||||||
</widget>
|
|
||||||
<addaction name="menuFile"/>
|
|
||||||
</widget>
|
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
|
||||||
<action name="actionStart_Replay">
|
|
||||||
<property name="text">
|
|
||||||
<string>Start Replay</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="actionStop_Replay">
|
|
||||||
<property name="text">
|
|
||||||
<string>Stop Replay</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
# static msvc runtime
|
|
||||||
FOREACH(flag_var
|
|
||||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
|
||||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
|
||||||
IF(${flag_var} MATCHES "/MD")
|
|
||||||
STRING(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
|
||||||
ENDIF()
|
|
||||||
ENDFOREACH()
|
|
||||||
SET(THP_ICO "${CMAKE_SOURCE_DIR}/Lts/Common/LtsWidgets/resources/rde_icon_256.ico")
|
|
||||||
CONFIGURE_FILE(thp_starter.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/thp_starter.rc)
|
|
||||||
|
|
||||||
NGL_ADD_EXECUTABLE(WS thp_starter WIN32 thp_starter.cpp ${CMAKE_CURRENT_BINARY_DIR}/thp_starter.rc)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(thp_starter user32.lib opengl32.lib gdi32.lib)
|
|
||||||
NGL_INSTALL_TARGET(thp_starter)
|
|
||||||
ENDIF(WIN32)
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Small wrapper to automatically start thp_viewer
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
#include <gl/gl.h>
|
|
||||||
#include <gl/glu.h>
|
|
||||||
|
|
||||||
static void* getGLExtensionFuncPtr(const char *funcName, const char *fallbackFuncName)
|
|
||||||
{
|
|
||||||
void* ptr = wglGetProcAddress(funcName);
|
|
||||||
if (ptr)
|
|
||||||
return ptr;
|
|
||||||
return wglGetProcAddress(fallbackFuncName);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int checkOpenGL(HWND hWnd)
|
|
||||||
{
|
|
||||||
HDC hDC = GetDC( hWnd );
|
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
|
||||||
ZeroMemory( &pfd, sizeof( pfd ) );
|
|
||||||
pfd.nSize = sizeof( pfd );
|
|
||||||
pfd.nVersion = 1;
|
|
||||||
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
|
|
||||||
PFD_SUPPORT_OPENGL |
|
|
||||||
PFD_DOUBLEBUFFER |
|
|
||||||
PFD_SWAP_EXCHANGE;
|
|
||||||
pfd.iPixelType = PFD_TYPE_RGBA;
|
|
||||||
pfd.cColorBits = 32;
|
|
||||||
pfd.cRedBits = 8;
|
|
||||||
pfd.cGreenBits = 8;
|
|
||||||
pfd.cBlueBits = 8;
|
|
||||||
pfd.cAlphaBits = 8;
|
|
||||||
pfd.cDepthBits = 0;
|
|
||||||
pfd.iLayerType = PFD_MAIN_PLANE;
|
|
||||||
int iFormat = ChoosePixelFormat( hDC, &pfd );
|
|
||||||
if( !SetPixelFormat( hDC, iFormat, &pfd ) ) {
|
|
||||||
DWORD dw = GetLastError();
|
|
||||||
int ret = MessageBox(NULL,
|
|
||||||
L"Your system does not support some mandatory OpenGL Functions.\nThe THP-Viewer may not display all things correct!\nDo you really want to start the THP-viewer?",
|
|
||||||
L"THP-Viewer startup",
|
|
||||||
MB_ICONWARNING|MB_YESNO);
|
|
||||||
if(ret == IDNO) {
|
|
||||||
ReleaseDC( hWnd, hDC );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HGLRC hRC = wglCreateContext( hDC );
|
|
||||||
|
|
||||||
DWORD dw = wglMakeCurrent( hDC, hRC );
|
|
||||||
void *_glCompressedTexImage2D = getGLExtensionFuncPtr( "glCompressedTexImage2D", "glCompressedTexImage2DARB" );
|
|
||||||
if(!_glCompressedTexImage2D) {
|
|
||||||
int ret = MessageBox(NULL,
|
|
||||||
L"Your system does not support the mandatory OpenGL Function glCompressedTexImage2D.\nThe THP-Viewer may not display all things correct!\nDo you really want to start the THP-viewer?",
|
|
||||||
L"THP-Viewer startup",
|
|
||||||
MB_ICONWARNING|MB_YESNO);
|
|
||||||
if(ret == IDNO) {
|
|
||||||
wglDeleteContext( hRC );
|
|
||||||
ReleaseDC( hWnd, hDC );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wglDeleteContext( hRC );
|
|
||||||
ReleaseDC( hWnd, hDC );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int startThpViewer(HINSTANCE hInstance)
|
|
||||||
{
|
|
||||||
TCHAR fn[MAX_PATH*10];
|
|
||||||
DWORD len = GetModuleFileName(hInstance, fn, sizeof(fn));
|
|
||||||
|
|
||||||
for(int i = len - 1; i >= 0; --i) {
|
|
||||||
if(fn[i] == '\\')
|
|
||||||
break;
|
|
||||||
fn[i] = '\0';
|
|
||||||
}
|
|
||||||
wcscat(fn, L"thp\\thp_viewer.exe");
|
|
||||||
|
|
||||||
STARTUPINFO si; ZeroMemory(&si, sizeof(si));
|
|
||||||
PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi));
|
|
||||||
si.cb = sizeof(si);
|
|
||||||
|
|
||||||
DWORD ret = CreateProcess(fn,
|
|
||||||
NULL, // lpCommandLine
|
|
||||||
NULL, // lpProcessAttributes
|
|
||||||
NULL, // lpThreadAttributes
|
|
||||||
NULL, // bInheritHandles
|
|
||||||
0, // dwCreationFlags
|
|
||||||
NULL, // lpEnvironment
|
|
||||||
NULL, // lpCurrentDirectory
|
|
||||||
&si, // lpStartupInfo
|
|
||||||
&pi); // lpProcessInformation
|
|
||||||
|
|
||||||
if(ret == 0) {
|
|
||||||
MessageBox(NULL,
|
|
||||||
L"Error starting the THP-Viewer!",
|
|
||||||
L"THP-Viewer startup",
|
|
||||||
MB_ICONWARNING|MB_OK);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
// Wait until child process exits.
|
|
||||||
WaitForSingleObject( pi.hProcess, INFINITE );
|
|
||||||
|
|
||||||
// Close process and thread handles.
|
|
||||||
CloseHandle( pi.hProcess );
|
|
||||||
CloseHandle( pi.hThread );
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
return DefWindowProc( hWnd, message, wParam, lParam );
|
|
||||||
}
|
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|
||||||
LPSTR lpCmdLine, int nCmdShow)
|
|
||||||
{
|
|
||||||
WNDCLASS wc;
|
|
||||||
ZeroMemory( &wc, sizeof(wc) );
|
|
||||||
// register window class
|
|
||||||
wc.style = CS_OWNDC;
|
|
||||||
wc.lpfnWndProc = WndProc;
|
|
||||||
wc.hInstance = hInstance;
|
|
||||||
wc.lpszClassName = L"THP_Viewer_startup";
|
|
||||||
RegisterClass( &wc );
|
|
||||||
|
|
||||||
// create main window
|
|
||||||
HWND hWnd = CreateWindow(L"THP_Viewer_startup",
|
|
||||||
L"THP-Viewer startup",
|
|
||||||
WS_CAPTION | WS_POPUPWINDOW,
|
|
||||||
0, 0, 256, 256,
|
|
||||||
NULL, NULL, hInstance, NULL );
|
|
||||||
|
|
||||||
int iRet = checkOpenGL(hWnd);
|
|
||||||
if(iRet != 0)
|
|
||||||
return iRet;
|
|
||||||
return startThpViewer(hInstance);
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
IDI_ICON1 ICON DISCARDABLE "@THP_ICO@"
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[autorun]
|
|
||||||
OPEN=thp\bin\thp_viewer.exe
|
|
||||||
ICON=thp\bin\thp_viewer.exe,0
|
|
||||||
SHELL=readit
|
|
||||||
SHELL\readit="THP-Viewer starten"
|
|
||||||
SHELL\readit\command=thp\bin\thp_viewer.exe
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
log4j.reset=true
|
|
||||||
log4j.rootLogger=WARN, file
|
|
||||||
|
|
||||||
#log4j.logger.GDW=WARN
|
|
||||||
#log4j.logger.GDW_CTC=WARN
|
|
||||||
#log4j.logger.KALA=WARN
|
|
||||||
#
|
|
||||||
# THP
|
|
||||||
#
|
|
||||||
#log4j.logger.THP=WARN
|
|
||||||
#log4j.logger.THP.AudioVideoWidget=WARN
|
|
||||||
#log4j.logger.THP.PlanFilter=WARN
|
|
||||||
#log4j.logger.THP.SymbolLoaderThread=WARN
|
|
||||||
#log4j.logger.THP.SHMFileHandler=WARN
|
|
||||||
|
|
||||||
# Appender
|
|
||||||
############
|
|
||||||
log4j.appender.file=Lts::RollingFileAppender
|
|
||||||
log4j.appender.file.MaxFileSize=1MB
|
|
||||||
log4j.appender.file.MaxBackupIndex=9
|
|
||||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
|
||||||
|
|
||||||
# Appnd_Console
|
|
||||||
###########################################################
|
|
||||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
|
||||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
|
||||||
log4j.appender.stdout.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Main entry for thp viewer
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#include <nglapplication/nglsingleapplication.h>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QNetworkProxy>
|
|
||||||
#include <QSplashScreen>
|
|
||||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
|
||||||
|
|
||||||
#include "thp_viewer.h"
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include <ngltranslator/ngltranslator.h>
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
# include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class CmdLineParser : public LtsCommandLineParser::LtsCommandLineParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CmdLineParser()
|
|
||||||
: LtsCommandLineParser(ProvideCommandLineParameterOptions::None)
|
|
||||||
{
|
|
||||||
addOption({{QStringLiteral("l"), QStringLiteral("lang")},
|
|
||||||
QStringLiteral("Language iso code to use (de_DE, en_GB, en_US)"),
|
|
||||||
QStringLiteral("<locale iso code>")
|
|
||||||
});
|
|
||||||
addOption({{QStringLiteral("t"), QStringLiteral("alwaysontop")},
|
|
||||||
QStringLiteral("Set as always on top window")
|
|
||||||
});
|
|
||||||
}
|
|
||||||
bool useAsAlwaysOnTop() const
|
|
||||||
{
|
|
||||||
return isSet(QStringLiteral("t"));
|
|
||||||
}
|
|
||||||
QString langIsoCode() const { return value(QStringLiteral("l")); }
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
|
||||||
|
|
||||||
NGLSingleApplication app(argc, argv);
|
|
||||||
app.createLogger("THP", "log4cxx_thp_viewer.props");
|
|
||||||
app.setOrganizationName(QStringLiteral("RME"));
|
|
||||||
app.setApplicationName(QStringLiteral("thp_viewer"));
|
|
||||||
// Qt::AA_UseHighDpiPixmaps: no-op since Qt6 (high-DPI pixmaps are always enabled)
|
|
||||||
|
|
||||||
QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/style/")));
|
|
||||||
Q_INIT_RESOURCE(rme_light_style);
|
|
||||||
|
|
||||||
// Parse Options
|
|
||||||
CmdLineParser options;
|
|
||||||
if (!options.init())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// Set Translation
|
|
||||||
QString langIsoCode = options.langIsoCode();
|
|
||||||
if (langIsoCode.isEmpty())
|
|
||||||
langIsoCode = QLocale::system().name();
|
|
||||||
NGL::setTranslationLocale(langIsoCode.toLatin1());
|
|
||||||
|
|
||||||
//check for optional alyways on top flag
|
|
||||||
bool alwaysOnTop = options.useAsAlwaysOnTop();
|
|
||||||
|
|
||||||
QString index;
|
|
||||||
const QStringList args = options.positionalArguments();
|
|
||||||
|
|
||||||
// QString searchDir = QCoreApplication::applicationDirPath();
|
|
||||||
QString searchDir(QDir::currentPath());
|
|
||||||
|
|
||||||
if (args.count() == 1)
|
|
||||||
{
|
|
||||||
QFileInfo fi(args.first());
|
|
||||||
if (fi.isDir())
|
|
||||||
searchDir = fi.absolutePath();
|
|
||||||
else
|
|
||||||
index = fi.absoluteFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index.isEmpty())
|
|
||||||
{
|
|
||||||
const auto indexFiles = { QStringLiteral("index_%1.html").arg(langIsoCode),
|
|
||||||
QStringLiteral("index.html") };
|
|
||||||
for (const QString &indexFile : indexFiles)
|
|
||||||
{
|
|
||||||
QDir d(searchDir);
|
|
||||||
index = d.absoluteFilePath(indexFile);
|
|
||||||
while (!d.exists(index))
|
|
||||||
{
|
|
||||||
if (!d.cdUp())
|
|
||||||
break;
|
|
||||||
index = d.absoluteFilePath(indexFile);
|
|
||||||
}
|
|
||||||
if (d.exists(index))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfo fi(index);
|
|
||||||
QString basePath = fi.path() + QLatin1Char('/');
|
|
||||||
if (!fi.exists() || !fi.isFile())
|
|
||||||
{
|
|
||||||
fprintf(stderr, "%s <path_to_html> basePath=%s\n", argv[0], basePath.toStdString().c_str());
|
|
||||||
QMessageBox::critical(nullptr,
|
|
||||||
QObject::tr("File missing"),
|
|
||||||
QObject::tr("Could not find a valid index.html - aborting"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
index = fi.absoluteFilePath();
|
|
||||||
|
|
||||||
if (app.sendMessage(index))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
int ret = 1;
|
|
||||||
{
|
|
||||||
QString splashfile = basePath;
|
|
||||||
static const auto extension = {QStringLiteral("gif"),
|
|
||||||
QStringLiteral("jpg"),
|
|
||||||
QStringLiteral("png")};
|
|
||||||
for (const auto &ext : extension)
|
|
||||||
{
|
|
||||||
const QString fn = splashfile + QStringLiteral("/wappen.") + ext;
|
|
||||||
if (!QFile::exists(fn))
|
|
||||||
continue;
|
|
||||||
splashfile = fn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QPixmap splashPixmap(splashfile);
|
|
||||||
QSplashScreen splash((splashPixmap));
|
|
||||||
if (!splashPixmap.isNull())
|
|
||||||
splash.show();
|
|
||||||
|
|
||||||
#ifdef BUILD_STATIC_LIBRARIES
|
|
||||||
Q_INIT_RESOURCE(libsymbol);
|
|
||||||
Q_INIT_RESOURCE(nglresources);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NGL::ThpViewer view(QUrl::fromLocalFile(index));
|
|
||||||
if (alwaysOnTop)
|
|
||||||
{
|
|
||||||
view.setWindowFlag(Qt::WindowStaysOnTopHint, true);
|
|
||||||
view.setWindowFlag(Qt::WindowMinimizeButtonHint, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!view.init())
|
|
||||||
return ret;
|
|
||||||
view.center();
|
|
||||||
|
|
||||||
QObject::connect(&app, &NGLSingleApplication::messageReceived,
|
|
||||||
&view, &NGL::ThpViewer::onNewThp);
|
|
||||||
view.show();
|
|
||||||
splash.finish(&view);
|
|
||||||
|
|
||||||
ret = app.exec();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Plugin Provider for standalone SRP / THP
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
#include <AreaEffectSimulation/aes_dtc.h>
|
|
||||||
#include <AdvancedSymbology/Data/asb_foreign_interface_impl.h>
|
|
||||||
#include <Buildings/bld_dtc.h>
|
|
||||||
#include <CentralEffectSimulation/ces_dtc.h>
|
|
||||||
#include <GuezIedManagement/gim_dtc.h>
|
|
||||||
#include <InfrastructureManagement/ism_dtc.h>
|
|
||||||
#include <InfrastructureManagement/Data/ism_foreign_data_plugin.h>
|
|
||||||
#include <ParticipantManagement/ppm_dtc.h>
|
|
||||||
#include <ProjectDataManagement/pdm_dtc.h>
|
|
||||||
#include <DDS/DDSConnector/dds_connector.h>
|
|
||||||
|
|
||||||
#include "thp_situation_filter_interface_impl.h"
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
QString SitMapPluginProvider::toString() const
|
|
||||||
{
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SitMapPluginProvider::init(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector)
|
|
||||||
{
|
|
||||||
m_ddsConnector = ddsConnector;
|
|
||||||
|
|
||||||
m_buildingPluginProvider = std::make_shared<BuildingPluginProvider>();
|
|
||||||
|
|
||||||
m_aesDtc = AreaEffectSimulation::Interface::Dtc::create(ddsConnector);
|
|
||||||
m_aesDtc->enableAll();
|
|
||||||
m_bldDtc = Buildings::Interface::Dtc::create(ddsConnector);
|
|
||||||
m_bldDtc->enableAll();
|
|
||||||
m_cesDtc = CentralEffectSimulation::Interface::Dtc::create(ddsConnector);
|
|
||||||
m_cesDtc->enableAll();
|
|
||||||
m_gimDtc = GuezIedManagement::Interface::Dtc::create(ddsConnector);
|
|
||||||
m_gimDtc->enableAll();
|
|
||||||
// m_ismDtc = InfrastructureManagement::Interface::Dtc::create(ddsConnector);
|
|
||||||
// m_ismDtc->enableAll();
|
|
||||||
// m_ismForeign = std::make_shared<InfrastructureManagement::ForeignInterfaceImpl>(m_ismDtc);
|
|
||||||
m_ppmDtc = ParticipantManagement::Interface::Dtc::create(ddsConnector);
|
|
||||||
m_ppmDtc->enableAll();
|
|
||||||
m_pdmDtc = ProjectDataManagement::Interface::Dtc::create(ddsConnector);
|
|
||||||
m_pdmDtc->enableAll();
|
|
||||||
|
|
||||||
// needs m_ppmDtc
|
|
||||||
m_fltParticipantIfc = std::make_shared<FilterManagement::ThpFilterInterfaceImpl>(m_ppmDtc);
|
|
||||||
m_fltAesIfc = std::make_shared<FilterManagement::ThpFilterInterfaceImpl>(m_ppmDtc);
|
|
||||||
m_fltBuildingComponentIfc = std::make_shared<FilterManagement::ThpFilterInterfaceImpl>(m_ppmDtc);
|
|
||||||
// m_fltParticipantIfc = m_fltAesIfc; // Not sure, lets try
|
|
||||||
|
|
||||||
return m_buildingPluginProvider->init(ddsConnector, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool BuildingPluginProvider::init(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector,
|
|
||||||
SitMapPluginProvider *smPluginProvider)
|
|
||||||
{
|
|
||||||
Q_ASSERT(smPluginProvider);
|
|
||||||
m_smPluginProvider = smPluginProvider;
|
|
||||||
connect(m_smPluginProvider, &SitMapPluginProvider::partitionTimeChanged,
|
|
||||||
this, &BuildingPluginProvider::partitionTimeChanged);
|
|
||||||
|
|
||||||
m_connectionParams.domainId = ddsConnector->getDomainId();
|
|
||||||
m_connectionParams.partitionId = ddsConnector->getPartitionId();
|
|
||||||
m_connectionParams.exerciseId = ddsConnector->getPartitionId();
|
|
||||||
m_connectionParams.tcpConnectionUrl = ddsConnector->getTcpConnectionUrl();
|
|
||||||
|
|
||||||
m_asbIfc = std::make_shared<AdvancedSymbology::ForeignInterfaceImpl>(m_smPluginProvider->ppmDtc(),
|
|
||||||
m_smPluginProvider->aesDtc(),
|
|
||||||
m_smPluginProvider->gimDtc());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> SitMapPluginProvider::ismDataIfc() const
|
|
||||||
{
|
|
||||||
if (!m_ismForeign)
|
|
||||||
m_ismForeign = std::make_shared<InfrastructureManagement::ForeignInterfaceImpl>(ismDtc());
|
|
||||||
|
|
||||||
return m_ismForeign;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> SitMapPluginProvider::ismDtc() const
|
|
||||||
{
|
|
||||||
if (!m_ismDtc)
|
|
||||||
{
|
|
||||||
m_ismDtc = InfrastructureManagement::Interface::Dtc::create(m_ddsConnector);
|
|
||||||
m_ismDtc->enableAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_ismDtc;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Plugin Provider for standalone SRP / THP
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SituationMap/AdapterDds/plugin_provider.h>
|
|
||||||
#include <BuildingViewer/Common/bdv_plugin_provider.h>
|
|
||||||
#include <AlarmManagement/alm_info_gui_plugin_interface.h>
|
|
||||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
||||||
#include <LtsSession/lts_session_data_dds.h>
|
|
||||||
#include <QVector>
|
|
||||||
|
|
||||||
namespace DDSConnector
|
|
||||||
{
|
|
||||||
class DdsConnector;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class BuildingPluginProvider;
|
|
||||||
class SitMapPluginProvider final : public SituationMap::PluginProvider
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
using SituationMap::PluginProvider::PluginProvider;
|
|
||||||
|
|
||||||
QString toString() const override;
|
|
||||||
|
|
||||||
bool init(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector);
|
|
||||||
|
|
||||||
void emitPartitionTimeChanged(qint64 curTime) { m_curPartitionTime = curTime; emit partitionTimeChanged(curTime); }
|
|
||||||
|
|
||||||
void setExerciseId(int exerciseId) { m_exerciseId = exerciseId; }
|
|
||||||
int exerciseId() const override { return m_exerciseId; }
|
|
||||||
bool isSessionValid() const override { return true; }
|
|
||||||
qint64 partitionTime() const override { return m_curPartitionTime; }
|
|
||||||
int partitionId() const override { return -1; }
|
|
||||||
int operatorId() const override { return 42; }
|
|
||||||
LtsAppDescriptor::App appId() const override { return LtsAppDescriptor::App::ThpSituationReplay; }
|
|
||||||
|
|
||||||
bool isVisibleParty(int) const override { return true; }
|
|
||||||
QString workspaceId() const override { return {}; }
|
|
||||||
bool isReplayPartition() const override { return false; }
|
|
||||||
|
|
||||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> aesDtc() const override { return m_aesDtc; }
|
|
||||||
std::shared_ptr<AreaEffectSimulation::ForeignInfoGuiInterface> aesInfoIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<AlarmManagement::Interface::Dtc> almDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<AlarmManagement::Interface::Ftc> almFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<AlarmManagement::ForeignInfoGuiInterface> almInfoIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<AssetManagement::Interface::Dtc> asmDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<AssetManagement::Interface::Ftc> asmFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<Buildings::Interface::Dtc> bldDtc() const override { return m_bldDtc; }
|
|
||||||
std::shared_ptr<Buildings::Interface::Ftc> bldFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<Buildings::ForeignInfoGuiInterface> bldInfoIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<CentralEffectSimulation::Interface::Dtc> cesDtc() const override { return m_cesDtc; }
|
|
||||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<ExerciseManagement::Interface::Ftc> exmFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<FilterManagement::Interface::Dtc> fltDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<FilterManagement::Interface::Ftc> fltFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> fltParticipantIfc() const override { return m_fltParticipantIfc; }
|
|
||||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> fltAesIfc() const override { return m_fltAesIfc; }
|
|
||||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> fltBuildingComponentIfc() const override { return m_fltBuildingComponentIfc; }
|
|
||||||
std::shared_ptr<GuezIedManagement::Interface::Dtc> gimDtc() const override { return m_gimDtc; }
|
|
||||||
std::shared_ptr<GuezIedManagement::ForeignGuiInterface> gimIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<GuezNasat::Interface::Dtc> gnaDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<GuezNasat::ForeignGuiInterface> gnaIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc() const override;
|
|
||||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> ismDataIfc() const override;
|
|
||||||
std::shared_ptr<InfrastructureManagement::ForeignResourceManagementGuiInterface> ismGuiIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<OperatorManagement::Interface::Dtc> opmDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<OperatorManagement::Interface::Ftc> opmFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc() const override { return m_ppmDtc; }
|
|
||||||
std::shared_ptr<ParticipantManagement::Interface::Ftc> ppmFtc() const override { return {}; }
|
|
||||||
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> ppmParticipantInfoIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc() const override { return m_pdmDtc; }
|
|
||||||
std::shared_ptr<SituationReplay::Interface::Dtc> srpDtc() const override { return m_srpDtc; }
|
|
||||||
std::shared_ptr<OcSituationClient::ForeignParticipantInfoGuiInterface> ocParticipantInfoIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<ServiceMonitor::ForeignGuiInterface> smoServiceMonitorIfc() const override { return {}; }
|
|
||||||
std::shared_ptr<TargetManagement::Interface::Dtc> tgtDtc() const override { return {}; }
|
|
||||||
std::shared_ptr<ComponentMonitor::Interface::Dtc> cmoDtc() const override { return {}; }
|
|
||||||
|
|
||||||
// for BuildingPluginProvider
|
|
||||||
BuildingPluginProvider *buildingPluginProvider() { return m_buildingPluginProvider.get(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
|
|
||||||
std::shared_ptr<Buildings::Interface::Dtc> m_bldDtc;
|
|
||||||
std::shared_ptr<CentralEffectSimulation::Interface::Dtc> m_cesDtc;
|
|
||||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
|
||||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
|
|
||||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
|
|
||||||
std::shared_ptr<GuezIedManagement::Interface::Dtc> m_gimDtc;
|
|
||||||
mutable std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
|
||||||
mutable std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_ismForeign;
|
|
||||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
|
||||||
std::shared_ptr<SituationReplay::Interface::Dtc> m_srpDtc;
|
|
||||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_pdmDtc;
|
|
||||||
|
|
||||||
qint64 m_curPartitionTime = 0;
|
|
||||||
int m_exerciseId = 0;
|
|
||||||
|
|
||||||
std::shared_ptr<BuildingPluginProvider> m_buildingPluginProvider;
|
|
||||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BuildingPluginProvider final : public BuildingViewer::PluginProvider
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
using BuildingViewer::PluginProvider::PluginProvider;
|
|
||||||
|
|
||||||
BuildingPluginProvider() = default;
|
|
||||||
|
|
||||||
QString toString() const override { return m_smPluginProvider->toString(); }
|
|
||||||
|
|
||||||
bool init(const std::shared_ptr<DDSConnector::DdsConnector> &ddsConnector,
|
|
||||||
SitMapPluginProvider *smPluginProvider);
|
|
||||||
|
|
||||||
void emitPartitionTimeChanged(qint64 curTime) { m_smPluginProvider->emitPartitionTimeChanged(curTime); }
|
|
||||||
|
|
||||||
int exerciseId() const override { return m_smPluginProvider->exerciseId(); }
|
|
||||||
qint64 partitionTime() const override { return m_smPluginProvider->partitionTime(); }
|
|
||||||
bool isReplayPartition() const override { return false; }
|
|
||||||
bool isVisibleParty(int partyId) const override { return m_smPluginProvider->isVisibleParty(partyId); }
|
|
||||||
LtsSession::DdsConnectionParams connParams() const override { return m_connectionParams; }
|
|
||||||
|
|
||||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asbIfc() const override { return m_asbIfc; }
|
|
||||||
std::shared_ptr<AudioVideoManagement::ForeignDataInterface> avmDataIfc() const override { return nullptr; } // optional
|
|
||||||
std::shared_ptr<Buildings::Interface::Dtc> bldDtc() const override { return m_smPluginProvider->bldDtc(); }
|
|
||||||
std::shared_ptr<Buildings::ForeignInfoGuiInterface> bldInfoIfc() const override { return m_smPluginProvider->bldInfoIfc(); } // optional
|
|
||||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc() const override { return m_smPluginProvider->ismDtc(); }
|
|
||||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> ismDataIfc() const override { return m_smPluginProvider->ismDataIfc(); }
|
|
||||||
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> aesDtc() const override { return m_smPluginProvider->aesDtc(); } // optional
|
|
||||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc() const override { return m_smPluginProvider->ppmDtc(); } // optional
|
|
||||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> pdmDtc() const override { return m_smPluginProvider->pdmDtc(); } // optional
|
|
||||||
std::shared_ptr<SituationReplay::Interface::Dtc> srpDtc() const override { return m_smPluginProvider->srpDtc(); } // optional
|
|
||||||
std::shared_ptr<ParticipantManagement::ForeignParticipantInfoGuiInterface> ppmParticipantInfoIfc() const override { return m_smPluginProvider->ppmParticipantInfoIfc(); } // optional
|
|
||||||
|
|
||||||
private:
|
|
||||||
SitMapPluginProvider *m_smPluginProvider{nullptr};
|
|
||||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asbIfc;
|
|
||||||
LtsSession::DdsConnectionParams m_connectionParams;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Simple implmentation of FilterHandling for THP
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_filter_interface_impl.h"
|
|
||||||
#include <FilterManagement/Gui/Aes/Common/symbol_appearance_settings_impl.h>
|
|
||||||
#include <FilterManagement/Gui/Aes/Common/aes_display_filter_impl.h>
|
|
||||||
#include <FilterManagement/Gui/Aes/Common/building_cmpnt_settings_impl.h>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
ThpFilterInterfaceImpl::ThpFilterInterfaceImpl(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtcPpm)
|
|
||||||
: m_fltSymbols(std::make_shared<SymbolAppearanceSettingsImpl>(dtcPpm))
|
|
||||||
, m_fltAes(std::make_shared<AesDisplayFilterImpl>())
|
|
||||||
, m_fltBuildingComponentSettings(std::make_shared<BuildingComponentSettingsImpl>())
|
|
||||||
{
|
|
||||||
m_fltAes->setVisiblePartiesCheck([](int) -> bool { return true; });
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SymbolAppearanceSettings> ThpFilterInterfaceImpl::symbolAppearanceForOperator(int operatorId, const QString &context)
|
|
||||||
{
|
|
||||||
Q_UNUSED(operatorId);
|
|
||||||
Q_UNUSED(context);
|
|
||||||
return m_fltSymbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<AesDisplayFilter> ThpFilterInterfaceImpl::aesFilterForOperator(int operatorId, const QString &context)
|
|
||||||
{
|
|
||||||
Q_UNUSED(operatorId);
|
|
||||||
Q_UNUSED(context);
|
|
||||||
return m_fltAes;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<BuildingComponentSettings> ThpFilterInterfaceImpl::buildingComponentSettingsForOperator(int operatorId, const QString &context)
|
|
||||||
{
|
|
||||||
Q_UNUSED(operatorId);
|
|
||||||
Q_UNUSED(context);
|
|
||||||
return m_fltBuildingComponentSettings;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-40
@@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Simple implmentation of FilterHandling for THP
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
|
||||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
|
||||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
|
||||||
#include <ParticipantManagement/ppm_dtc.h>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class ThpFilterInterfaceImpl : public ForeignFltParticipantGuiInterface,
|
|
||||||
public ForeignAesGuiInterface,
|
|
||||||
public ForeignFltBuildingComponentGuiInterface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit ThpFilterInterfaceImpl(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtcPpm);
|
|
||||||
|
|
||||||
// from Participant
|
|
||||||
std::shared_ptr<SymbolAppearanceSettings> symbolAppearanceForOperator(int operatorId, const QString &context) override;
|
|
||||||
|
|
||||||
// from Aes
|
|
||||||
std::shared_ptr<AesDisplayFilter> aesFilterForOperator(int operatorId, const QString &context) override;
|
|
||||||
|
|
||||||
// from BuildingComponent
|
|
||||||
std::shared_ptr<BuildingComponentSettings> buildingComponentSettingsForOperator(int operatorId, const QString &context) override;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<SymbolAppearanceSettings> m_fltSymbols;
|
|
||||||
std::shared_ptr<AesDisplayFilter> m_fltAes;
|
|
||||||
std::shared_ptr<BuildingComponentSettings> m_fltBuildingComponentSettings;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,686 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Main thp viewer widget
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#include "thp_viewer.h"
|
|
||||||
#include "ui_thp_viewer.h"
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QPrintDialog>
|
|
||||||
#include <QPrinter>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QTextDocument>
|
|
||||||
#include <QScreen>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QDomElement>
|
|
||||||
#include <QDomDocument>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QRect>
|
|
||||||
#include <QSize>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QDir>
|
|
||||||
|
|
||||||
#include <ngltranslator/ngltranslator.h>
|
|
||||||
#include <ngltools/ngltools_dtg.h>
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
namespace NGL
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* ThpViewer base class
|
|
||||||
*/
|
|
||||||
ThpViewer::ThpViewer(const QUrl &url, QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, ui(new Ui::thpViewer)
|
|
||||||
, m_scaleFactor(1.0)
|
|
||||||
, m_homeLink(url)
|
|
||||||
, m_homePath(QFileInfo(m_homeLink.toLocalFile()).absolutePath())
|
|
||||||
, m_trainingName(QString())
|
|
||||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("ThpViewer"))
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
ui->audioWidget->setAV(true);
|
|
||||||
ui->videoWidget->setAV(false);
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO
|
|
||||||
if (!conffile.isEmpty())
|
|
||||||
{
|
|
||||||
QSettings thpsettings(conffile, QSettings::IniFormat, this);
|
|
||||||
|
|
||||||
// needed?
|
|
||||||
const char timeZone = thpsettings.value(QStringLiteral("Time/Timezone"), QStringLiteral("Z")).toString().at(0).toLatin1();
|
|
||||||
DTG::setTimezone(timeZone, true);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
QString basedir(url.toLocalFile());
|
|
||||||
basedir = basedir.left(basedir.lastIndexOf(QLatin1Char('/')));
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "url: " << url.toString() << " basedir: " << basedir;
|
|
||||||
|
|
||||||
QFont f = ui->mainLabel->font();
|
|
||||||
f.setBold(true);
|
|
||||||
f.setPointSizeF(f.pointSizeF() * 1.2);
|
|
||||||
ui->mainLabel->setFont(f);
|
|
||||||
|
|
||||||
connect(ui->closeButton, &QToolButton::clicked, this, &ThpViewer::close);
|
|
||||||
connect(ui->backButton, &QToolButton::clicked, this, &ThpViewer::onBack);
|
|
||||||
connect(ui->homeButton, &QToolButton::clicked, this, &ThpViewer::onHome);
|
|
||||||
connect(ui->helpButton, &QToolButton::clicked, this, &ThpViewer::onHelp);
|
|
||||||
connect(ui->printButton, &QToolButton::clicked, this, &ThpViewer::onPrint);
|
|
||||||
connect(ui->fullScreenButton, &QToolButton::clicked, this, &ThpViewer::onFullScreen);
|
|
||||||
connect(ui->htmlWidget, &THP::HtmlWidget::linkClicked, this, &ThpViewer::onLinkClicked);
|
|
||||||
connect(ui->htmlWidget, &THP::HtmlWidget::urlChanged, this, &ThpViewer::onUrlChanged);
|
|
||||||
connect(ui->htmlWidget, &THP::HtmlWidget::titleChanged, this, &ThpViewer::onTitleChanged);
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(false);
|
|
||||||
ui->helpButton->setVisible(false); // Help disabled for now
|
|
||||||
#ifndef Q_WS_WIN
|
|
||||||
setWindowIcon(QIcon(QStringLiteral(":icons/16x16/rde.ico")));
|
|
||||||
#endif
|
|
||||||
setWindowTitle(tr("Combat Training Center"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ThpViewer::~ThpViewer()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThpViewer::init()
|
|
||||||
{
|
|
||||||
QFile file(m_homePath + QStringLiteral("/data.json"));
|
|
||||||
int exerciseId = 0;
|
|
||||||
if (file.exists() && file.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
const auto obj = QJsonDocument::fromJson(file.readAll()).object();
|
|
||||||
exerciseId = obj.value(QLatin1String("exerciseId")).toInt();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
QFile file2(m_homePath + QStringLiteral("/../data.json"));
|
|
||||||
if (file2.exists() && file2.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
const auto obj = QJsonDocument::fromJson(file2.readAll()).object();
|
|
||||||
exerciseId = obj.value(QLatin1String("exerciseId")).toInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG_LOG(m_logger) << "Use EXERCISE" << exerciseId;
|
|
||||||
|
|
||||||
if (!ui->situationWidget->init(m_homePath, exerciseId))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Could not init situation widget - abort";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!ui->buildingWidget->init(ui->situationWidget->replayHandler(),
|
|
||||||
ui->situationWidget->pluginProvider()->buildingPluginProvider(),
|
|
||||||
m_homePath))
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Could not init situation widget - abort";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
onZoomChanged();
|
|
||||||
onLinkClicked(m_homeLink);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::center()
|
|
||||||
{
|
|
||||||
QRect rect = QGuiApplication::primaryScreen()->availableGeometry();
|
|
||||||
// 80 %
|
|
||||||
int width = rect.width() * 4 / 5;
|
|
||||||
int height = rect.height() * 4 / 5;
|
|
||||||
int x = rect.width() / 2 - width / 2;
|
|
||||||
int y = rect.height() / 2 - height / 2;
|
|
||||||
resize(width, height);
|
|
||||||
move(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::closeEvent(QCloseEvent *event)
|
|
||||||
{
|
|
||||||
// explicit delete those two widgets here, otherwise we may get in trouble
|
|
||||||
// on windows when the app is closed with the 'X' button from the window frame
|
|
||||||
delete ui->buildingWidget;
|
|
||||||
ui->buildingWidget = nullptr;
|
|
||||||
delete ui->situationWidget;
|
|
||||||
ui->situationWidget = nullptr;
|
|
||||||
QWidget::closeEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onNewThp(const QString &index)
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "onNewThp: " << index;
|
|
||||||
|
|
||||||
if (index.isEmpty())
|
|
||||||
return;
|
|
||||||
m_homeLink = QUrl::fromLocalFile(index);
|
|
||||||
m_homePath = QFileInfo(m_homeLink.toLocalFile()).absolutePath();
|
|
||||||
DEBUG_LOG(m_logger) << "home: " << m_homeLink.toString();
|
|
||||||
onLinkClicked(m_homeLink);
|
|
||||||
ui->backButton->setEnabled(false);
|
|
||||||
this->raise();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onTitleChanged(const QString &title)
|
|
||||||
{
|
|
||||||
if (title.endsWith(QLatin1String("html")) ||
|
|
||||||
title.endsWith(QLatin1String("html#!/")))
|
|
||||||
return;
|
|
||||||
if (m_trainingName.isEmpty())
|
|
||||||
m_trainingName = title;
|
|
||||||
ui->mainLabel->setText(m_trainingName == title ? m_trainingName : QStringLiteral("%1 - %2").arg(m_trainingName, title));
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::keyPressEvent(QKeyEvent *e)
|
|
||||||
{
|
|
||||||
switch (e->key())
|
|
||||||
{
|
|
||||||
case Qt::Key_Backspace:
|
|
||||||
onBack();
|
|
||||||
break;
|
|
||||||
case Qt::Key_Plus:
|
|
||||||
if (ui->stackedWidget->isVisible() && ui->stackedWidget->currentWidget() == ui->situationWidget)
|
|
||||||
return;
|
|
||||||
if (m_scaleFactor < 10)
|
|
||||||
{
|
|
||||||
m_scaleFactor *= 1.5;
|
|
||||||
onZoomChanged();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_M:
|
|
||||||
{
|
|
||||||
if (QApplication::queryKeyboardModifiers() == Qt::ControlModifier)
|
|
||||||
onLinkClicked(QUrl::fromLocalFile(QDir::currentPath() + QStringLiteral("/") + QInputDialog::getText(this, {}, QStringLiteral("href_local"))));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Qt::Key_Minus:
|
|
||||||
if (ui->stackedWidget->isVisible() && ui->stackedWidget->currentWidget() == ui->situationWidget)
|
|
||||||
return;
|
|
||||||
if (m_scaleFactor > 0.05)
|
|
||||||
{
|
|
||||||
m_scaleFactor /= 1.5;
|
|
||||||
onZoomChanged();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt::Key_F1:
|
|
||||||
onHelp();
|
|
||||||
break;
|
|
||||||
case Qt::Key_Escape:
|
|
||||||
if (isFullScreen())
|
|
||||||
onFullScreen();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
QWidget::keyPressEvent(e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onHelp()
|
|
||||||
{
|
|
||||||
QFileInfo f(QStringLiteral("%1/../DATA/help/%2/help.html").arg(QCoreApplication::applicationDirPath(), QString::fromLatin1(NGL::translationLocale())));
|
|
||||||
if (f.exists())
|
|
||||||
onLinkClicked(QUrl::fromLocalFile(f.absoluteFilePath())); // TODO Pfad anpassen!
|
|
||||||
else
|
|
||||||
{
|
|
||||||
f.setFile(qApp->applicationDirPath() + QStringLiteral("/../DATA/help/en_US/help.html")); // TODO Pfad anpassen!
|
|
||||||
if (f.exists())
|
|
||||||
onLinkClicked(QUrl::fromLocalFile(f.absoluteFilePath()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onZoomChanged()
|
|
||||||
{
|
|
||||||
ui->pdfWidget->setZoomFactor(m_scaleFactor);
|
|
||||||
ui->htmlWidget->setZoomFactor(m_scaleFactor);
|
|
||||||
|
|
||||||
// double zoom = ( int ) ( m_scaleFactor * 100. + 0.5 );
|
|
||||||
// ui->statusbar->showMessage ( tr ( "zoom: %1 %" ).arg ( zoom ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onLinkClicked(const QUrl &url)
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "url: " << url.toString();
|
|
||||||
|
|
||||||
const QString path = url.path();
|
|
||||||
const QString lpath = path.toLower();
|
|
||||||
|
|
||||||
// Use QStringView for efficient string operations
|
|
||||||
const QStringView ext = QStringView{lpath}.split(QLatin1Char('.')).last();
|
|
||||||
const QStringView ext2Chars = ext.left(2);
|
|
||||||
|
|
||||||
ui->audioWidget->stop();
|
|
||||||
ui->videoWidget->stop();
|
|
||||||
// Video-only
|
|
||||||
if (lpath.endsWith(QLatin1String("video.pls")) ||
|
|
||||||
ext == QLatin1String("mpg") ||
|
|
||||||
ext == QLatin1String("avi") ||
|
|
||||||
ext == QLatin1String("ogg"))
|
|
||||||
{
|
|
||||||
ui->videoWidget->play(url);
|
|
||||||
|
|
||||||
ui->stackedWidget->hide();
|
|
||||||
ui->videoWidget->show();
|
|
||||||
ui->audioWidget->hide();
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(true);
|
|
||||||
// Audio-only
|
|
||||||
}
|
|
||||||
else if (lpath.endsWith(QLatin1String("audio.pls")) ||
|
|
||||||
ext == QLatin1String("mp3"))
|
|
||||||
{
|
|
||||||
ui->audioWidget->play(url);
|
|
||||||
|
|
||||||
// Ermitteln der Groesse des AudioWidgets
|
|
||||||
QSize sizeAudio = ui->audioWidget->sizeHint();
|
|
||||||
QSize sizeStack = ui->stackedWidget->sizeHint();
|
|
||||||
sizeStack -= sizeAudio;
|
|
||||||
QList<int> l;
|
|
||||||
l << sizeStack.height() << sizeAudio.height();
|
|
||||||
ui->splitter_1->setSizes(l);
|
|
||||||
|
|
||||||
ui->stackedWidget->show(); // hier können wir html mit anzeigen
|
|
||||||
ui->videoWidget->hide();
|
|
||||||
ui->audioWidget->show();
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(true);
|
|
||||||
// PDF-only
|
|
||||||
}
|
|
||||||
else if (ext == QLatin1String("pdf"))
|
|
||||||
{
|
|
||||||
if (ui->pdfWidget->showPDF(url))
|
|
||||||
{
|
|
||||||
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->pdfWidget);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
ui->pdfWidget->resizePdfToWidth();
|
|
||||||
ui->videoWidget->hide();
|
|
||||||
ui->audioWidget->hide();
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QMessageBox::warning(this,
|
|
||||||
tr("Opening PDF file"),
|
|
||||||
tr("Can not open PDF file %1 - missing or corrupt file!").arg(url.toString()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (lpath.endsWith(QLatin1String("sitmap.json"), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
|
|
||||||
// 2D oder 3D ?
|
|
||||||
{
|
|
||||||
NOTICE_LOG(m_logger) << LOGFUNCTION << " lpath = '" << lpath << "'";
|
|
||||||
// peek into <lpath>/sitreplay.json:
|
|
||||||
|
|
||||||
QFileInfo fi(path);
|
|
||||||
const QString basePath = fi.absolutePath();
|
|
||||||
const QString replayConfigFile = basePath + QDir::separator() + QStringLiteral("sitreplay.json"); // aka replayConfigPath
|
|
||||||
NOTICE_LOG(m_logger) << LOGFUNCTION << " replayConfigFile = '" << replayConfigFile << "'";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lage-only
|
|
||||||
QString localFile = url.toLocalFile();
|
|
||||||
QString basePath = localFile;
|
|
||||||
int idx = basePath.lastIndexOf(QLatin1Char('/'));
|
|
||||||
idx = basePath.lastIndexOf(QLatin1Char('/'), idx - 1);
|
|
||||||
if (idx >= 0)
|
|
||||||
basePath.chop(basePath.size() - idx - 1);
|
|
||||||
|
|
||||||
ui->situationWidget->showSituation(url.toLocalFile(),
|
|
||||||
basePath);
|
|
||||||
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->situationWidget);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
ui->videoWidget->hide();
|
|
||||||
ui->audioWidget->hide();
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(true);
|
|
||||||
}
|
|
||||||
else if (lpath.endsWith(QLatin1String("buildingViewer.json"), Qt::CaseInsensitive))
|
|
||||||
{
|
|
||||||
// BuildingViewer-only
|
|
||||||
QString localFile = url.toLocalFile();
|
|
||||||
QString basePath = localFile;
|
|
||||||
int idx = basePath.lastIndexOf(QLatin1Char('/'));
|
|
||||||
idx = basePath.lastIndexOf(QLatin1Char('/'), idx - 1);
|
|
||||||
if (idx >= 0)
|
|
||||||
basePath.chop(basePath.size() - idx - 1);
|
|
||||||
ui->buildingWidget->showSituation(url.toLocalFile(),
|
|
||||||
basePath);
|
|
||||||
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->buildingWidget);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
ui->videoWidget->hide();
|
|
||||||
ui->audioWidget->hide();
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(true);
|
|
||||||
}
|
|
||||||
else if (ext == QLatin1String("html") &&
|
|
||||||
QStringView{lpath}.mid(lpath.lastIndexOf(QLatin1Char('/')) + 1).startsWith(QLatin1String("combined_")))
|
|
||||||
{
|
|
||||||
// Kombiniert
|
|
||||||
QHash<QString, QUrl> urls = getCombinedPlaybackDetails(url);
|
|
||||||
|
|
||||||
if (urls.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (urls.contains(QLatin1String("audio")))
|
|
||||||
{
|
|
||||||
ui->audioWidget->show();
|
|
||||||
ui->audioWidget->play(urls[QLatin1String("audio")]);
|
|
||||||
}
|
|
||||||
if (urls.contains(QLatin1String("video")))
|
|
||||||
{
|
|
||||||
ui->videoWidget->show();
|
|
||||||
ui->videoWidget->play(urls[QLatin1String("video")]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Einer von dreien:
|
|
||||||
if (urls.contains(QLatin1String("pdf")))
|
|
||||||
{
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->pdfWidget);
|
|
||||||
ui->pdfWidget->showPDF(urls[QLatin1String("pdf")]);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
}
|
|
||||||
else if (urls.contains(QLatin1String("html")))
|
|
||||||
{
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->htmlWidget);
|
|
||||||
ui->htmlWidget->showHTML(urls[QLatin1String("html")]);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
}
|
|
||||||
else if (urls.contains(QLatin1String("jpg")))
|
|
||||||
{
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->htmlWidget);
|
|
||||||
ui->htmlWidget->showHTML(urls[QLatin1String("jpg")]);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
}
|
|
||||||
else if (urls.contains(QLatin1String("png")))
|
|
||||||
{
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->htmlWidget);
|
|
||||||
ui->htmlWidget->showHTML(urls[QLatin1String("png")]);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ui->stackedWidget->hide();
|
|
||||||
ui->backButton->setEnabled(true);
|
|
||||||
}
|
|
||||||
else if (ext2Chars == QLatin1String("do") ||
|
|
||||||
ext2Chars == QLatin1String("xl") ||
|
|
||||||
ext2Chars == QLatin1String("pp"))
|
|
||||||
QDesktopServices::openUrl(url);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Trying to open url: " << url.toString();
|
|
||||||
ui->htmlWidget->showHTML(url);
|
|
||||||
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->htmlWidget);
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
ui->videoWidget->hide();
|
|
||||||
ui->audioWidget->hide();
|
|
||||||
|
|
||||||
ui->backButton->setEnabled(url != m_homeLink);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/********************************************************************************************
|
|
||||||
* Parsed eine HTML-Dateinach allen Links, die sich direkt unterhalb des BODY-Tags befinden
|
|
||||||
* und liefert die entsprechenden Link-URLs zurück, wenn diese das Tag ID besitzen.
|
|
||||||
*
|
|
||||||
* Von der aufrufenden Funktion derzeit ausgewertete Werte für ID sind:
|
|
||||||
* html, audio, video, lage, pdf (alles klein geschrieben!)
|
|
||||||
*/
|
|
||||||
QHash<QString, QUrl> ThpViewer::getCombinedPlaybackDetails(const QUrl &url) const
|
|
||||||
{
|
|
||||||
QHash<QString, QUrl> hash;
|
|
||||||
QFile file(url.toLocalFile());
|
|
||||||
QDomDocument doc(QStringLiteral("RSS"));
|
|
||||||
if (!file.open(QIODevice::ReadOnly))
|
|
||||||
return hash;
|
|
||||||
const auto parseResult = doc.setContent(&file, QDomDocument::ParseOption::UseNamespaceProcessing);
|
|
||||||
if (!parseResult)
|
|
||||||
{
|
|
||||||
file.close();
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
QDomElement domel = doc.documentElement();
|
|
||||||
domel = domel.firstChildElement(QStringLiteral("BODY"));
|
|
||||||
domel = domel.firstChildElement(QStringLiteral("A"));
|
|
||||||
|
|
||||||
while (!domel.isNull())
|
|
||||||
{
|
|
||||||
if (!domel.attribute(QStringLiteral("id")).isEmpty())
|
|
||||||
{
|
|
||||||
QUrl linkurl(domel.attribute(QStringLiteral("HREF")));
|
|
||||||
if (linkurl.isRelative())
|
|
||||||
linkurl = url.resolved(linkurl);
|
|
||||||
DEBUG_LOG(m_logger) << "attr: " << domel.attribute(QStringLiteral("id")).toLower() << " url: " << linkurl.toString();
|
|
||||||
hash[domel.attribute(QStringLiteral("id")).toLower()] = linkurl;
|
|
||||||
}
|
|
||||||
domel = domel.nextSiblingElement(QStringLiteral("A"));
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onPrint()
|
|
||||||
{
|
|
||||||
if (ui->stackedWidget->isVisible())
|
|
||||||
{
|
|
||||||
if (ui->stackedWidget->currentWidget() == ui->situationWidget)
|
|
||||||
{
|
|
||||||
QImage image = ui->situationWidget->grabFrameBuffer();
|
|
||||||
|
|
||||||
QPrinter printer;
|
|
||||||
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
|
||||||
dialog->setWindowTitle(tr("Print Document"));
|
|
||||||
if (dialog->exec() != QDialog::Accepted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QPainter painter;
|
|
||||||
painter.begin(&printer);
|
|
||||||
|
|
||||||
QRectF rect = painter.viewport();
|
|
||||||
|
|
||||||
double mmH = printer.logicalDpiY() / 25.4; // 25.4 = mm/inch
|
|
||||||
double mmW = printer.logicalDpiX() / 25.4;
|
|
||||||
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 30));
|
|
||||||
QString title = tr("Combat Training Center");
|
|
||||||
QRectF textBox = painter.boundingRect(QRectF(), Qt::AlignLeft & Qt::TextSingleLine, title);
|
|
||||||
textBox.setWidth(painter.viewport().width());
|
|
||||||
painter.drawText(textBox, Qt::AlignCenter & Qt::TextSingleLine, title);
|
|
||||||
QPointF underImage;
|
|
||||||
|
|
||||||
if (printer.orientation() == QPrinter::Portrait)
|
|
||||||
{
|
|
||||||
const QPointF textBlockBegin = QPointF(0 * mmW, 25 * mmH); // Baseline 25mm unter Seitenbeginn
|
|
||||||
|
|
||||||
// Noch mal schauen, welches (auch übersetzt!) der breiteste Bezeichner (also 1. Spalte) ist!
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Bold, false));
|
|
||||||
textBox = painter.boundingRect(QRect(), Qt::AlignLeft & Qt::TextSingleLine, tr("Center point:\nExercise:\nTime:"));
|
|
||||||
|
|
||||||
// Textbox hat 3 Zeilen, also ist der Faktor pro Zeile 0.33 = 1/3
|
|
||||||
// Spalte 1
|
|
||||||
painter.drawText(textBlockBegin, tr("Exercise:"));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.33 * textBox.height()), tr("Time:"));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.66 * textBox.height()), tr("Center point:"));
|
|
||||||
|
|
||||||
// Zwischen Spalte 1 und Spalte 2 noch 3mm Platz lassen
|
|
||||||
// Spalte 2
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Normal, false));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(textBox.width() + 3 * mmW, 0), m_trainingName);
|
|
||||||
painter.drawText(textBlockBegin + QPointF(textBox.width() + 3 * mmW, 0.33 * textBox.height()), ui->situationWidget->currentDTGTime());
|
|
||||||
painter.drawText(textBlockBegin + QPointF(textBox.width() + 3 * mmW, 0.66 * textBox.height()), ui->situationWidget->centerPointString());
|
|
||||||
|
|
||||||
// Das Bild soll formatfüllend angezeigt werden, das Rechteck muss 45mm "flacher" sein, da es erst ab 45mm gedruckt werden soll.
|
|
||||||
QSizeF size = image.size();
|
|
||||||
rect.adjust(0, 0, 0, -45 * mmH);
|
|
||||||
size.scale(rect.size(), Qt::KeepAspectRatio);
|
|
||||||
|
|
||||||
// Und ab 45mm von oben drucken:
|
|
||||||
QRectF imgrect = QRectF(QPointF(0 * mmW, 45 * mmH), size);
|
|
||||||
painter.drawImage(imgrect, image);
|
|
||||||
|
|
||||||
// Untere linke Ecke des Bildes
|
|
||||||
underImage = imgrect.bottomLeft();
|
|
||||||
|
|
||||||
}
|
|
||||||
else // Landscape
|
|
||||||
{
|
|
||||||
// Noch mal schauen, welches (auch übersetzt!) der breiteste Bezeichner oder variable Text ist!
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Bold, false));
|
|
||||||
textBox = painter.boundingRect(QRect(), Qt::AlignLeft, tr("Center point:\n%1\n\nTime:\n%2\n\nExercise:\n%3")
|
|
||||||
.arg(m_trainingName,
|
|
||||||
ui->situationWidget->currentDTGTime(),
|
|
||||||
ui->situationWidget->centerPointString()));
|
|
||||||
|
|
||||||
// TextBlock fängt an: Notwendige Breite von rechts und 15 mm + 1 Zeilenhöhe (=1/8 der Textboxhöhe) von oben.
|
|
||||||
// Die Zeilenhöhe ist notwendig weil drawText(QPoint, QString) den QPoint auf die Baseline setzt!
|
|
||||||
QPointF textBlockBegin = QPointF(painter.viewport().width() - textBox.width(), 15 * mmH + 0.125 * textBox.height());
|
|
||||||
|
|
||||||
// Die Textbox hat 8 Zeilen, also ist der Faktor pro Zeile 1/8 = 0.125
|
|
||||||
// Übung
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Bold, false));
|
|
||||||
painter.drawText(textBlockBegin, tr("Exercise:"));
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Normal, false));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.125 * textBox.height()), m_trainingName);
|
|
||||||
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Bold, false));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.375 * textBox.height()), tr("Time:"));
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Normal, false));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.500 * textBox.height()), ui->situationWidget->currentDTGTime());
|
|
||||||
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Bold, false));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.750 * textBox.height()), tr("Center point:"));
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 14, QFont::Normal, false));
|
|
||||||
painter.drawText(textBlockBegin + QPointF(0, 0.875 * textBox.height()), ui->situationWidget->centerPointString());
|
|
||||||
|
|
||||||
// Das Bild soll formatfüllend angezeigt werden, das Rechteck muss 15mm "flacher" sein, da es erst ab 15mm gedruckt werden soll.
|
|
||||||
// Ausserdem müssen in der Breite die Textboxbreite und 3mm Luft dazwischen abgezogen werden.
|
|
||||||
QSizeF size = image.size();
|
|
||||||
rect.adjust(0, 0, -textBox.width() - 3 * mmW, -15 * mmH);
|
|
||||||
size.scale(rect.size(), Qt::KeepAspectRatio);
|
|
||||||
|
|
||||||
// Und ab 15mm von oben drucken:
|
|
||||||
QRectF imgrect = QRectF(QPointF(0 * mmW, 15 * mmH), size);
|
|
||||||
painter.drawImage(imgrect, image);
|
|
||||||
|
|
||||||
// Untere linke Ecke des Bildes
|
|
||||||
underImage = imgrect.bottomLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.setFont(QFont(QStringLiteral("Arial"), 12));
|
|
||||||
// String für Breite und Höhe erstellen
|
|
||||||
const QRectF extent = ui->situationWidget->extentMgrs();
|
|
||||||
QString areasize = tr("Width: %1m, Height: %2m").arg(extent.width()).arg(extent.height());
|
|
||||||
// Die Größe herausfinden
|
|
||||||
textBox = painter.boundingRect(QRect(), Qt::AlignLeft & Qt::TextSingleLine, areasize);
|
|
||||||
// Einen Dot vergrößern (siehe QRect: Die Rahmenpixel unten und rechts sind nicht Teil der Rechteckgröße)
|
|
||||||
textBox.adjust(0, 0, 1, 1);
|
|
||||||
// An die richtige Stelle bugsieren
|
|
||||||
textBox.moveBottomLeft(underImage);
|
|
||||||
// Und mit weiß und 50% Deckkraft vollmalen.
|
|
||||||
painter.fillRect(textBox, QColor(255, 255, 255, 128));
|
|
||||||
//Dann den Text drüberlegen
|
|
||||||
painter.drawText(underImage, areasize);
|
|
||||||
|
|
||||||
painter.end();
|
|
||||||
}
|
|
||||||
else if (ui->stackedWidget->currentWidget() == ui->pdfWidget)
|
|
||||||
{
|
|
||||||
QPrinter printer;
|
|
||||||
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
|
||||||
dialog->setWindowTitle(tr("Print Document"));
|
|
||||||
if (dialog->exec() != QDialog::Accepted)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QVector<QImage> images = ui->pdfWidget->getPrintableImages(printer.resolution());
|
|
||||||
int lastItem = images.size() - 1;
|
|
||||||
|
|
||||||
QPainter painter;
|
|
||||||
painter.begin(&printer);
|
|
||||||
for (int i = 0; i < images.size(); ++i)
|
|
||||||
{
|
|
||||||
QRect rect = painter.viewport();
|
|
||||||
QSize size = images.at(i).size();
|
|
||||||
size.scale(rect.size(), Qt::KeepAspectRatio);
|
|
||||||
painter.setViewport(rect.x(), rect.y(),
|
|
||||||
size.width(), size.height());
|
|
||||||
painter.setWindow(images.at(i).rect());
|
|
||||||
painter.drawImage(0, 0, images.at(i));
|
|
||||||
if (i != lastItem)
|
|
||||||
printer.newPage();
|
|
||||||
}
|
|
||||||
painter.end();
|
|
||||||
}
|
|
||||||
else if (ui->stackedWidget->currentWidget() == ui->htmlWidget)
|
|
||||||
{
|
|
||||||
QPrinter printer;
|
|
||||||
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
|
||||||
dialog->setWindowTitle(tr("Print Document"));
|
|
||||||
if (dialog->exec() != QDialog::Accepted)
|
|
||||||
return;
|
|
||||||
ui->htmlWidget->print(&printer);
|
|
||||||
}
|
|
||||||
else // Audio/Video-Widget
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // nur HTML sichtbar...
|
|
||||||
{
|
|
||||||
QPrinter printer;
|
|
||||||
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
|
||||||
dialog->setWindowTitle(tr("Print Document"));
|
|
||||||
if (dialog->exec() != QDialog::Accepted)
|
|
||||||
return;
|
|
||||||
ui->htmlWidget->print(&printer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onBack()
|
|
||||||
{
|
|
||||||
ui->audioWidget->stop();
|
|
||||||
ui->videoWidget->stop();
|
|
||||||
ui->situationWidget->stop();
|
|
||||||
|
|
||||||
ui->audioWidget->hide();
|
|
||||||
ui->videoWidget->hide();
|
|
||||||
if (ui->stackedWidget->currentWidget() == ui->htmlWidget &&
|
|
||||||
ui->stackedWidget->isVisible())
|
|
||||||
ui->htmlWidget->back();
|
|
||||||
ui->stackedWidget->show();
|
|
||||||
ui->stackedWidget->setCurrentWidget(ui->htmlWidget);
|
|
||||||
onUrlChanged(ui->htmlWidget->url());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onHome()
|
|
||||||
{
|
|
||||||
ui->htmlWidget->show();
|
|
||||||
onLinkClicked(m_homeLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onFullScreen()
|
|
||||||
{
|
|
||||||
setWindowState(windowState() ^ Qt::WindowFullScreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThpViewer::onUrlChanged(const QUrl &url)
|
|
||||||
{
|
|
||||||
ui->backButton->setEnabled(url != m_homeLink);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace NGL
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Main thp viewer widget
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QMainWindow>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class thpViewer;
|
|
||||||
}
|
|
||||||
namespace NGL
|
|
||||||
{
|
|
||||||
class INGLLogger;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace NGL
|
|
||||||
{
|
|
||||||
class ThpViewer : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit ThpViewer(const QUrl &url, QWidget *parent = nullptr);
|
|
||||||
~ThpViewer();
|
|
||||||
|
|
||||||
bool init();
|
|
||||||
void center();
|
|
||||||
|
|
||||||
void closeEvent(QCloseEvent *event) override;
|
|
||||||
protected:
|
|
||||||
QHash<QString, QUrl> getCombinedPlaybackDetails(const QUrl &url) const;
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onLinkClicked(const QUrl &url);
|
|
||||||
void onZoomChanged();
|
|
||||||
void onBack();
|
|
||||||
void onHome();
|
|
||||||
void onHelp();
|
|
||||||
void onPrint();
|
|
||||||
void onFullScreen();
|
|
||||||
void onTitleChanged(const QString &title);
|
|
||||||
void onUrlChanged(const QUrl &url);
|
|
||||||
public Q_SLOTS:
|
|
||||||
void onNewThp(const QString &index);
|
|
||||||
protected:
|
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
|
||||||
protected:
|
|
||||||
Ui::thpViewer *ui;
|
|
||||||
double m_scaleFactor;
|
|
||||||
QUrl m_homeLink;
|
|
||||||
QString m_homePath;
|
|
||||||
QString m_trainingName;
|
|
||||||
NGL::INGLLogger &m_logger;
|
|
||||||
};
|
|
||||||
} // namespace NGL
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#include <WINVER.H>
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION @THP_VERSION_INFO@
|
|
||||||
PRODUCTVERSION @THP_VERSION_INFO@
|
|
||||||
FILEFLAGSMASK 0x0L
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
FILEOS VOS_NT_WINDOWS32
|
|
||||||
FILETYPE VFT_APP
|
|
||||||
FILESUBTYPE VFT2_UNKNOWN
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040704b0"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "Rheinmetall Electronics GmbH"
|
|
||||||
VALUE "FileDescription", "Take Home Package Viewer"
|
|
||||||
VALUE "FileVersion", "@THP_VERSION_INFO@"
|
|
||||||
VALUE "InternalName", "THP"
|
|
||||||
VALUE "LegalCopyright", "Copyright © 2018 Rheinmetall Electronics GmbH. Alle Rechte vorbehalten"
|
|
||||||
VALUE "OriginalFilename", "thp_viewer.exe"
|
|
||||||
VALUE "ProductName", "Take Home Package Viewer (THP)"
|
|
||||||
VALUE "ProductVersion", "@THP_VERSION_INFO@"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x407, 1200
|
|
||||||
END
|
|
||||||
END
|
|
||||||
@@ -1,216 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>thpViewer</class>
|
|
||||||
<widget class="QWidget" name="thpViewer">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>793</width>
|
|
||||||
<height>675</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>793</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">MainWindow</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="backButton">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/go-previous.png</normaloff>:icons/16x16/go-previous.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="fullScreenButton">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/view-fullscreen.png</normaloff>:icons/16x16/view-fullscreen.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>F11</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="homeButton">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/go-home.png</normaloff>:icons/16x16/go-home.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="mainLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">THP-Viewer</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="printButton">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/document-print.png</normaloff>:icons/16x16/document-print.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="helpButton">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/system-help.png</normaloff>:icons/16x16/system-help.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="closeButton">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/dialog-close.png</normaloff>:icons/16x16/dialog-close.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSplitter" name="splitter_1">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="QSplitter" name="splitter_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<widget class="THP::AudioVideoWidget" name="videoWidget" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
<widget class="QStackedWidget" name="stackedWidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<widget class="THP::HtmlWidget" name="htmlWidget"/>
|
|
||||||
<widget class="THP::BuildingWidget" name="buildingWidget"/>
|
|
||||||
<widget class="THP::PdfWidget" name="pdfWidget"/>
|
|
||||||
<widget class="THP::SituationWidget" name="situationWidget"/>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
<widget class="THP::AudioVideoWidget" name="audioWidget" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>THP::AudioVideoWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>thpwidgets/thp_audio_video_widget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>THP::PdfWidget</class>
|
|
||||||
<extends>QFrame</extends>
|
|
||||||
<header>thpwidgets/thp_pdf_widget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>THP::HtmlWidget</class>
|
|
||||||
<extends>QFrame</extends>
|
|
||||||
<header>thpwidgets/thp_html_widget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>THP::SituationWidget</class>
|
|
||||||
<extends>QFrame</extends>
|
|
||||||
<header>thpwidgets/thp_situation_widget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>THP::BuildingWidget</class>
|
|
||||||
<extends>QFrame</extends>
|
|
||||||
<header>thpwidgets/thp_building_widget.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
-629
@@ -1,629 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle Audio/Video output for thp through libvlc
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#include "thp_audio_video_widget.h"
|
|
||||||
#include "thp_audio_video_widget_p.h"
|
|
||||||
#include "ui_thp_audio_video_widget.h"
|
|
||||||
|
|
||||||
#include <QCoreApplication>
|
|
||||||
#include <QDirIterator>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QMutex>
|
|
||||||
#include <QScreen>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <vlc/libvlc_version.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
static const float s_speedArray[] =
|
|
||||||
{
|
|
||||||
1. / 8.,
|
|
||||||
1. / 4.,
|
|
||||||
1. / 2.,
|
|
||||||
1.,
|
|
||||||
2.,
|
|
||||||
4.,
|
|
||||||
8.
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AudioVideoWidget::Private
|
|
||||||
*/
|
|
||||||
AudioVideoWidget::Private::Private(QFrame *parent)
|
|
||||||
: m_vlcinstance(nullptr)
|
|
||||||
, m_mPlayer(nullptr)
|
|
||||||
, m_mListPlayer(nullptr)
|
|
||||||
, m_mediaList(nullptr)
|
|
||||||
, currentSpeedIdx(3)
|
|
||||||
, m_parent(parent)
|
|
||||||
, m_timer(new QTimer)
|
|
||||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("THP.AudioVideoWidget"))
|
|
||||||
{
|
|
||||||
init();
|
|
||||||
|
|
||||||
connect(ui->btnSlower, &QToolButton::clicked, this, &AudioVideoWidget::Private::onSlower);
|
|
||||||
connect(ui->btnFaster, &QToolButton::clicked, this, &AudioVideoWidget::Private::onFaster);
|
|
||||||
connect(ui->btn100pct, &QToolButton::clicked, this, &AudioVideoWidget::Private::on100pct);
|
|
||||||
connect(ui->btnPlay, &QToolButton::clicked, this, &AudioVideoWidget::Private::onPlay);
|
|
||||||
connect(ui->btnStop, &QToolButton::clicked, this, &AudioVideoWidget::Private::onStop);
|
|
||||||
connect(ui->sldPosition, &QSlider::sliderMoved, this, &AudioVideoWidget::Private::onPositionChanged);
|
|
||||||
connect(ui->sldVolume, &QSlider::sliderMoved, this, &AudioVideoWidget::Private::onVolumeChanged);
|
|
||||||
connect(m_timer, &QTimer::timeout, this, &AudioVideoWidget::Private::onUpdateGUI);
|
|
||||||
|
|
||||||
m_initThread = new AudioVideoInitThread(this);
|
|
||||||
connect(m_initThread, &AudioVideoInitThread::finished, this, &AudioVideoWidget::Private::onVLCInstanceInitializd);
|
|
||||||
m_initThread->start(QThread::LowPriority);
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioVideoWidget::Private::~Private()
|
|
||||||
{
|
|
||||||
uninitVLCPlayer();
|
|
||||||
uninitVLCInstance();
|
|
||||||
delete ui;
|
|
||||||
delete m_timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::init()
|
|
||||||
{
|
|
||||||
if (!m_parent)
|
|
||||||
return false;
|
|
||||||
ui = new Ui::audioVideoWidget();
|
|
||||||
ui->setupUi(m_parent);
|
|
||||||
|
|
||||||
QPixmap pm(10, 10);
|
|
||||||
pm.fill(Qt::black);
|
|
||||||
ui->outputWidget->setPixmap(pm);
|
|
||||||
ui->outputWidget->setScaledContents(true);
|
|
||||||
|
|
||||||
ui->sldPosition->setMaximum(1000);
|
|
||||||
ui->sldVolume->setMaximum(100);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onVLCInstanceInitializd()
|
|
||||||
{
|
|
||||||
m_initThread->deleteLater();
|
|
||||||
m_initThread = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::setAV(bool isAudio)
|
|
||||||
{
|
|
||||||
if (isAudio)
|
|
||||||
{
|
|
||||||
delete ui->btn100pct;
|
|
||||||
delete ui->btnFaster;
|
|
||||||
delete ui->btnSlower;
|
|
||||||
delete ui->outputWidget;
|
|
||||||
ui->outputWidget = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// delete ui->verticalSpacer; ui->verticalSpacer = 0;
|
|
||||||
delete ui->lblAudio;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static QMutex *serializeVLCInit()
|
|
||||||
{
|
|
||||||
static QMutex s_serializeVLCInit;
|
|
||||||
return &s_serializeVLCInit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::initVLCInstance(bool bInInitThread)
|
|
||||||
{
|
|
||||||
QMutexLocker l(serializeVLCInit());
|
|
||||||
|
|
||||||
if (!bInInitThread && m_initThread != nullptr)
|
|
||||||
{
|
|
||||||
QLabel myLabel;
|
|
||||||
myLabel.setWindowTitle(tr("Loading VLC player..."));
|
|
||||||
myLabel.setText(tr("Waiting until VLC player is loaded"));
|
|
||||||
QRect r = QGuiApplication::primaryScreen()->availableGeometry();
|
|
||||||
myLabel.show();
|
|
||||||
myLabel.move(r.width() / 2 - myLabel.width() / 2, r.height() / 2 - myLabel.height() / 2);
|
|
||||||
myLabel.setWindowIcon(QIcon(QLatin1String(":icons/16x16/rde.ico")));
|
|
||||||
|
|
||||||
while (m_initThread)
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
}
|
|
||||||
if (m_vlcinstance != nullptr)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
//preparation of the vlc command
|
|
||||||
const char *vlc_argv[20];
|
|
||||||
int iCount = 0;
|
|
||||||
vlc_argv[iCount++] = "-I";
|
|
||||||
vlc_argv[iCount++] = "dummy"; // Don't use any interface
|
|
||||||
// vlc_argv[iCount++] = "--ignore-config"; // Don't use VLC's config
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
vlc_argv[iCount++] = "--extraintf=logger"; // log anything
|
|
||||||
vlc_argv[iCount++] = "--verbose=2"; // be much more verbose then normal for debugging purpose
|
|
||||||
#else
|
|
||||||
vlc_argv[iCount++] = "--quiet";
|
|
||||||
#endif
|
|
||||||
if (bInInitThread)
|
|
||||||
vlc_argv[iCount++] = "--no-media-library";
|
|
||||||
vlc_argv[iCount++] = "--";
|
|
||||||
vlc_argv[iCount] = nullptr;
|
|
||||||
|
|
||||||
//Initialize an instance of vlc
|
|
||||||
//create a new libvlc instance
|
|
||||||
m_vlcinstance = libvlc_new(iCount, vlc_argv); //tricky calculation of the char space used
|
|
||||||
if (!m_vlcinstance)
|
|
||||||
ERROR_LOG(m_logger) << "Error initializing libVLC - unable to play audio or video";
|
|
||||||
|
|
||||||
return (m_vlcinstance != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::uninitVLCInstance()
|
|
||||||
{
|
|
||||||
QMutexLocker l(serializeVLCInit());
|
|
||||||
|
|
||||||
if (!uninitVLCPlayer())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (m_vlcinstance)
|
|
||||||
{
|
|
||||||
libvlc_release(m_vlcinstance);
|
|
||||||
m_vlcinstance = nullptr;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::initVLCPlayer()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Initializing libVLC";
|
|
||||||
if (m_mPlayer)
|
|
||||||
{
|
|
||||||
if (!ui)
|
|
||||||
return false;
|
|
||||||
ui->sldVolume->setValue(libvlc_audio_get_volume(m_mPlayer));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
initVLCInstance();
|
|
||||||
|
|
||||||
//Initialize an instance of vlc
|
|
||||||
//Create a media player playing environement
|
|
||||||
m_mPlayer = libvlc_media_player_new(m_vlcinstance);
|
|
||||||
m_mListPlayer = libvlc_media_list_player_new(m_vlcinstance);
|
|
||||||
m_mediaList = libvlc_media_list_new(m_vlcinstance);
|
|
||||||
|
|
||||||
libvlc_media_list_player_set_media_player(m_mListPlayer, m_mPlayer);
|
|
||||||
libvlc_media_list_player_set_media_list(m_mListPlayer, m_mediaList);
|
|
||||||
|
|
||||||
ui->sldVolume->setValue(libvlc_audio_get_volume(m_mPlayer));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::uninitVLCPlayer()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Uninitializing libVLC";
|
|
||||||
|
|
||||||
if (m_mListPlayer)
|
|
||||||
{
|
|
||||||
/* Stop playing */
|
|
||||||
libvlc_media_list_player_stop(m_mListPlayer);
|
|
||||||
/* Free the media_player */
|
|
||||||
libvlc_media_list_player_release(m_mListPlayer);
|
|
||||||
m_mListPlayer = nullptr;
|
|
||||||
}
|
|
||||||
if (m_mediaList)
|
|
||||||
{
|
|
||||||
clearMediaList();
|
|
||||||
libvlc_media_list_release(m_mediaList);
|
|
||||||
m_mediaList = nullptr;
|
|
||||||
}
|
|
||||||
if (m_mPlayer)
|
|
||||||
{
|
|
||||||
/* Stop playing */
|
|
||||||
libvlc_media_player_stop(m_mPlayer);
|
|
||||||
/* Free the media_player */
|
|
||||||
libvlc_media_player_release(m_mPlayer);
|
|
||||||
|
|
||||||
m_mPlayer = nullptr;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::clearMediaList()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Clearing current playlist";
|
|
||||||
|
|
||||||
if (!m_mediaList)
|
|
||||||
return;
|
|
||||||
libvlc_media_list_lock(m_mediaList);
|
|
||||||
const int cnt = libvlc_media_list_count(m_mediaList);
|
|
||||||
for (int i = cnt - 1; i >= 0; --i)
|
|
||||||
libvlc_media_list_remove_index(m_mediaList, i);
|
|
||||||
libvlc_media_list_unlock(m_mediaList);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::playVLC(const QUrl &url)
|
|
||||||
{
|
|
||||||
if (!ui)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Try to play " << url.toString();
|
|
||||||
|
|
||||||
const QString path = url.toLocalFile();
|
|
||||||
if (path.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
clearMediaList();
|
|
||||||
|
|
||||||
libvlc_media_list_lock(m_mediaList);
|
|
||||||
QFileInfo fi(path);
|
|
||||||
DEBUG_LOG(m_logger) << "path: " << path << " isFile: " << fi.isFile();
|
|
||||||
if (fi.isFile() && path.endsWith(QLatin1String(".pls")))
|
|
||||||
{
|
|
||||||
// pls parsing scheint nicht mehr richtig zu funktionieren - selbst machen
|
|
||||||
DEBUG_LOG(m_logger) << "Parse Playlist";
|
|
||||||
QFile f(path);
|
|
||||||
if (f.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Parse Playlist2 " << f.canReadLine();
|
|
||||||
QMap<int, QByteArray> fileMap;
|
|
||||||
QByteArray baAll = f.readAll();
|
|
||||||
const QList<QByteArray> lines = baAll.split('\n');
|
|
||||||
for (const QByteArray &line : lines)
|
|
||||||
{
|
|
||||||
QByteArray ba = line.trimmed();
|
|
||||||
DEBUG_LOG(m_logger) << "ba: " << ba;
|
|
||||||
if (!ba.startsWith("File "))
|
|
||||||
continue;
|
|
||||||
ba = ba.mid(qstrlen("File "));
|
|
||||||
int idx = ba.indexOf('=');
|
|
||||||
DEBUG_LOG(m_logger) << "idx: " << idx;
|
|
||||||
if (idx < 0)
|
|
||||||
continue;
|
|
||||||
bool bOk;
|
|
||||||
int id = ba.left(idx).toInt(&bOk);
|
|
||||||
DEBUG_LOG(m_logger) << "id: " << id << " bOk: " << bOk << " str: " << ba.left(idx);
|
|
||||||
if (!bOk)
|
|
||||||
continue;
|
|
||||||
QByteArray filename = ba.mid(idx + 1);
|
|
||||||
DEBUG_LOG(m_logger) << "filename: " << filename;
|
|
||||||
fileMap.insertMulti(id, fi.absolutePath().toLocal8Bit() + '/' + filename);
|
|
||||||
}
|
|
||||||
for (const QByteArray &fn : fileMap)
|
|
||||||
{
|
|
||||||
const QByteArray pNative = QDir::toNativeSeparators(QString::fromLocal8Bit(fn)).toLocal8Bit();
|
|
||||||
DEBUG_LOG(m_logger) << "pNative: " << pNative;
|
|
||||||
libvlc_media_t *media = libvlc_media_new_path(m_vlcinstance, pNative.data());
|
|
||||||
if (!media)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error setting media to " << pNative;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//add option to disable hardware acceleration
|
|
||||||
libvlc_media_add_option(media, ":avcodec-hw=none");
|
|
||||||
libvlc_media_list_add_media(m_mediaList, media);
|
|
||||||
#if LIBVLC_VERSION_MAJOR > 2
|
|
||||||
libvlc_media_parse_with_options(media, libvlc_media_parse_local, 0);
|
|
||||||
#else
|
|
||||||
libvlc_media_parse(media);
|
|
||||||
#endif
|
|
||||||
libvlc_media_release(media); // libvlc_media_new_location(), ref-counting!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fi.isFile())
|
|
||||||
{
|
|
||||||
const QByteArray pNative = QDir::toNativeSeparators(path).toLocal8Bit();
|
|
||||||
libvlc_media_t *media = libvlc_media_new_path(m_vlcinstance, pNative.data());
|
|
||||||
if (!media)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error setting media to '" << pNative << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
libvlc_media_list_add_media(m_mediaList, media);
|
|
||||||
libvlc_media_release(media); // libvlc_media_new_location(), ref-counting!
|
|
||||||
}
|
|
||||||
else if (fi.isDir())
|
|
||||||
{
|
|
||||||
QDirIterator dirIt(fi.absoluteFilePath());
|
|
||||||
while (dirIt.hasNext())
|
|
||||||
{
|
|
||||||
const QString fn = dirIt.next();
|
|
||||||
fi.setFile(fn);
|
|
||||||
if (!fi.isFile())
|
|
||||||
continue;
|
|
||||||
const QByteArray pNative = QDir::toNativeSeparators(fn).toLocal8Bit();
|
|
||||||
libvlc_media_t *media = libvlc_media_new_path(m_vlcinstance, pNative.data());
|
|
||||||
if (!media)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Error setting media to " << pNative;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
libvlc_media_list_add_media(m_mediaList, media);
|
|
||||||
#if LIBVLC_VERSION_MAJOR > 2
|
|
||||||
libvlc_media_parse_with_options(media, libvlc_media_parse_local, 0);
|
|
||||||
#else
|
|
||||||
libvlc_media_parse(media);
|
|
||||||
#endif
|
|
||||||
libvlc_media_release(media); // libvlc_media_new_location(), ref-counting!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "Unknown media given: " << path;
|
|
||||||
libvlc_media_list_unlock(m_mediaList);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
libvlc_media_list_unlock(m_mediaList);
|
|
||||||
|
|
||||||
if (ui->outputWidget)
|
|
||||||
{
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
libvlc_media_player_set_hwnd(m_mPlayer, (HWND)ui->outputWidget->winId());
|
|
||||||
#elif defined(Q_OS_MAC)
|
|
||||||
libvlc_media_player_set_agl(m_mPlayer, ui->outputWidget->winId()) ;
|
|
||||||
#else //Linux
|
|
||||||
libvlc_media_player_set_xwindow(m_mPlayer, ui->outputWidget->winId());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
|
|
||||||
ui->btnPlay->setEnabled(true);
|
|
||||||
ui->sldPosition->setEnabled(false);
|
|
||||||
ui->btnStop->setEnabled(true);
|
|
||||||
|
|
||||||
currentSpeedIdx = 3;
|
|
||||||
|
|
||||||
QTimer::singleShot(0, this, &AudioVideoWidget::Private::onPlay);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::Private::stopVLC()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Stop playing";
|
|
||||||
|
|
||||||
QTimer::singleShot(0, this, &AudioVideoWidget::Private::onStop);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::setRate()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Setting speed to " << s_speedArray[currentSpeedIdx];
|
|
||||||
|
|
||||||
libvlc_state_t state = getState();
|
|
||||||
if (state == libvlc_Playing || state == libvlc_Paused)
|
|
||||||
libvlc_media_player_set_rate(m_mPlayer, s_speedArray[currentSpeedIdx]);
|
|
||||||
}
|
|
||||||
|
|
||||||
libvlc_state_t AudioVideoWidget::Private::getState() const
|
|
||||||
{
|
|
||||||
libvlc_state_t s = libvlc_media_list_player_get_state(m_mListPlayer);
|
|
||||||
static libvlc_state_t lastState = libvlc_NothingSpecial;
|
|
||||||
if (s == lastState)
|
|
||||||
return s;
|
|
||||||
lastState = s;
|
|
||||||
if (s == libvlc_Error)
|
|
||||||
ERROR_LOG(m_logger) << "libVLC error: " << libvlc_errmsg();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onSlower()
|
|
||||||
{
|
|
||||||
if (currentSpeedIdx == 0)
|
|
||||||
return;
|
|
||||||
--currentSpeedIdx;
|
|
||||||
setRate();
|
|
||||||
onUpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onFaster()
|
|
||||||
{
|
|
||||||
if (currentSpeedIdx == 6)
|
|
||||||
return;
|
|
||||||
++currentSpeedIdx;
|
|
||||||
setRate();
|
|
||||||
onUpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::on100pct()
|
|
||||||
{
|
|
||||||
currentSpeedIdx = 3;
|
|
||||||
setRate();
|
|
||||||
onUpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onPlay()
|
|
||||||
{
|
|
||||||
if (libvlc_media_list_player_is_playing(m_mListPlayer))
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Pause playing";
|
|
||||||
libvlc_media_list_player_pause(m_mListPlayer);
|
|
||||||
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
|
|
||||||
m_timer->stop();
|
|
||||||
onUpdateGUIWithState(libvlc_Paused);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Start playing";
|
|
||||||
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-pause.png")));
|
|
||||||
ui->sldPosition->setEnabled(true);
|
|
||||||
|
|
||||||
libvlc_media_list_player_play(m_mListPlayer);
|
|
||||||
setRate();
|
|
||||||
|
|
||||||
m_timer->start(100);
|
|
||||||
onUpdateGUIWithState(libvlc_Playing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onStop()
|
|
||||||
{
|
|
||||||
if (!m_mListPlayer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
libvlc_state_t state = getState();
|
|
||||||
|
|
||||||
if (state == libvlc_Stopped)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Stop playing";
|
|
||||||
|
|
||||||
libvlc_media_list_player_stop(m_mListPlayer);
|
|
||||||
onUpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onPositionChanged(int newPosition)
|
|
||||||
{
|
|
||||||
libvlc_state_t state = getState();
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << "Slider changed - going to new position";
|
|
||||||
|
|
||||||
if (state != libvlc_Playing && state != libvlc_Paused)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Position geht von 0..1, Slider hat 1000 Steps
|
|
||||||
libvlc_media_player_set_position(m_mPlayer, newPosition / 1000.);
|
|
||||||
onUpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onVolumeChanged(int newVol)
|
|
||||||
{
|
|
||||||
libvlc_audio_set_volume(m_mPlayer, newVol);
|
|
||||||
onUpdateGUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onUpdateGUI()
|
|
||||||
{
|
|
||||||
onUpdateGUIWithState(libvlc_NothingSpecial);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::Private::onUpdateGUIWithState(libvlc_state_t overwrite_state)
|
|
||||||
{
|
|
||||||
libvlc_state_t state = overwrite_state;
|
|
||||||
if (state == libvlc_NothingSpecial)
|
|
||||||
state = getState();
|
|
||||||
DEBUG_LOG(m_logger) << "onUpdateGUI for state " << state;
|
|
||||||
|
|
||||||
if (state == libvlc_Playing || state == libvlc_Paused)
|
|
||||||
{
|
|
||||||
double maxTime = libvlc_media_player_get_length(m_mPlayer) / 1000.;
|
|
||||||
if (maxTime > 0.1)
|
|
||||||
{
|
|
||||||
libvlc_media_list_lock(m_mediaList);
|
|
||||||
const int cnt = libvlc_media_list_count(m_mediaList);
|
|
||||||
for (int i = cnt - 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
libvlc_media_t *media = libvlc_media_list_item_at_index(m_mediaList, i);
|
|
||||||
DEBUG_LOG(m_logger) << "Duration: " << libvlc_media_get_duration(media);
|
|
||||||
libvlc_media_release(media);
|
|
||||||
}
|
|
||||||
libvlc_media_list_unlock(m_mediaList);
|
|
||||||
|
|
||||||
}
|
|
||||||
double curTime = libvlc_media_player_get_time(m_mPlayer) / 1000.;
|
|
||||||
auto curPos = libvlc_media_player_get_position(m_mPlayer);
|
|
||||||
// Slider ist in 1000 Schritte eingeteilt
|
|
||||||
ui->sldPosition->setValue(qRound(curPos * 1000));
|
|
||||||
|
|
||||||
const int minutesCur = floor(curTime / 60.);
|
|
||||||
const int secondsCur = curTime - 60 * minutesCur;
|
|
||||||
const int minutesAbs = floor(maxTime / 60.);
|
|
||||||
const int secondsAbs = maxTime - 60 * minutesAbs;
|
|
||||||
char timeStr[64];
|
|
||||||
snprintf(timeStr, sizeof(timeStr), "%02d:%02d / %02d:%02d", minutesCur, secondsCur, minutesAbs, secondsAbs);
|
|
||||||
ui->lblPosition->setText(QString::fromLatin1(timeStr));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (state == libvlc_Stopped || state == libvlc_Ended)
|
|
||||||
{
|
|
||||||
// wir können nicht onStop() aufrufen -> rekursion!
|
|
||||||
bool bStop = true;
|
|
||||||
if (state == libvlc_Ended)
|
|
||||||
{
|
|
||||||
// Timer und VLC *nicht* stoppen da der aktuelle State ggf. genau zwischen den einzelnen
|
|
||||||
// Video-Schnipseln einer Playlist abgefragt wurde
|
|
||||||
// --> prüfen, ob es das letzte Video der Playlist war
|
|
||||||
libvlc_media_t *media = libvlc_media_player_get_media(m_mPlayer);
|
|
||||||
if (media != nullptr)
|
|
||||||
{
|
|
||||||
const int cnt = libvlc_media_list_count(m_mediaList);
|
|
||||||
if (cnt > 0)
|
|
||||||
{
|
|
||||||
libvlc_media_t *media2 = libvlc_media_list_item_at_index(m_mediaList, cnt - 1);
|
|
||||||
bStop = (media2 == media);
|
|
||||||
libvlc_media_release(media2);
|
|
||||||
}
|
|
||||||
libvlc_media_release(media);
|
|
||||||
}
|
|
||||||
if (bStop)
|
|
||||||
libvlc_media_list_player_stop(m_mListPlayer);
|
|
||||||
}
|
|
||||||
if (bStop)
|
|
||||||
{
|
|
||||||
ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
|
|
||||||
ui->sldPosition->setEnabled(false);
|
|
||||||
m_timer->stop();
|
|
||||||
ui->sldPosition->setValue(0);
|
|
||||||
ui->lblPosition->setText(QLatin1String("--:-- / --:--"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString speedStr = QStringLiteral("%1x").arg(s_speedArray[currentSpeedIdx], 4, 'f', 2);
|
|
||||||
ui->lblSpeed->setText(speedStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AudioVideoInitThread
|
|
||||||
*/
|
|
||||||
AudioVideoInitThread::AudioVideoInitThread(AudioVideoWidget::Private *p)
|
|
||||||
: m_private(p)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void AudioVideoInitThread::run()
|
|
||||||
{
|
|
||||||
m_private->initVLCInstance(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AudioVideoWidget
|
|
||||||
*/
|
|
||||||
AudioVideoWidget::AudioVideoWidget(QWidget *parent)
|
|
||||||
: QFrame(parent)
|
|
||||||
, d(new Private(this))
|
|
||||||
{}
|
|
||||||
|
|
||||||
AudioVideoWidget::~AudioVideoWidget()
|
|
||||||
{
|
|
||||||
delete d;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::play(const QUrl &file)
|
|
||||||
{
|
|
||||||
d->initVLCPlayer();
|
|
||||||
return d->playVLC(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AudioVideoWidget::stop()
|
|
||||||
{
|
|
||||||
return d->stopVLC();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioVideoWidget::setAV(bool isAudio)
|
|
||||||
{
|
|
||||||
d->setAV(isAudio);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle Audio/Video output for thp through libvlc
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QFrame>
|
|
||||||
|
|
||||||
class QUrl;
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class AudioVideoWidget : public QFrame
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AudioVideoWidget(QWidget *parent = nullptr);
|
|
||||||
~AudioVideoWidget();
|
|
||||||
|
|
||||||
bool play(const QUrl &file);
|
|
||||||
bool stop();
|
|
||||||
void setAV(bool isAudio = false);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Private;
|
|
||||||
Private *const d;
|
|
||||||
friend class AudioVideoInitThread;
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
-254
@@ -1,254 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>audioVideoWidget</class>
|
|
||||||
<widget class="QFrame" name="audioVideoWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>911</width>
|
|
||||||
<height>563</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">Form</string>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::Panel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Sunken</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="outputWidget">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblAudio">
|
|
||||||
<property name="text">
|
|
||||||
<string>Audio</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="sldPosition">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblPosition">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>70</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">55:55 / 55:55</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnPlay">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../Z/src/nglwidgets/nglresources.qrc">
|
|
||||||
<normaloff>:icons/16x16/media-playback-start.png</normaloff>:icons/16x16/media-playback-start.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnStop">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../Z/src/nglwidgets/nglresources.qrc">
|
|
||||||
<normaloff>:icons/16x16/media-playback-stop.png</normaloff>:icons/16x16/media-playback-stop.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnSlower">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../Z/src/nglwidgets/nglresources.qrc">
|
|
||||||
<normaloff>:icons/16x16/media-play-slower.png</normaloff>:icons/16x16/media-play-slower.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btn100pct">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../Z/src/nglwidgets/nglresources.qrc">
|
|
||||||
<normaloff>:icons/16x16/media-play-normal.png</normaloff>:icons/16x16/media-play-normal.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnFaster">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset resource="../../../Z/src/nglwidgets/nglresources.qrc">
|
|
||||||
<normaloff>:icons/16x16/media-play-faster.png</normaloff>:icons/16x16/media-play-faster.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblSpeed">
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Sunken</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">100 %</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Volume:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="sldVolume">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>16777215</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>60</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources>
|
|
||||||
<include location="../../../Z/src/nglwidgets/nglresources.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle Audio/Video output for thp through libvlc, private data
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
// no ssize_t with msdn...
|
|
||||||
#include <BaseTsd.h>
|
|
||||||
typedef SSIZE_T ssize_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <vlc/vlc.h>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QThread>
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include "thp_audio_video_widget.h"
|
|
||||||
|
|
||||||
class QUrl;
|
|
||||||
class QFrame;
|
|
||||||
class QTimer;
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class audioVideoWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class AudioVideoInitThread;
|
|
||||||
class AudioVideoWidget::Private : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit Private(QFrame *parent);
|
|
||||||
~Private();
|
|
||||||
|
|
||||||
bool initVLCInstance(bool bInInitThread = false);
|
|
||||||
bool uninitVLCInstance();
|
|
||||||
bool initVLCPlayer();
|
|
||||||
bool uninitVLCPlayer();
|
|
||||||
bool playVLC(const QUrl &url);
|
|
||||||
bool stopVLC();
|
|
||||||
void setAV(bool isAudio);
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onSlower();
|
|
||||||
void onFaster();
|
|
||||||
void on100pct();
|
|
||||||
void onPlay();
|
|
||||||
void onStop();
|
|
||||||
void onPositionChanged(int);
|
|
||||||
void onVolumeChanged(int);
|
|
||||||
void onUpdateGUI();
|
|
||||||
void onVLCInstanceInitializd();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void clearMediaList();
|
|
||||||
void playVLCInternal();
|
|
||||||
void onUpdateGUIWithState(libvlc_state_t overwrite_state);
|
|
||||||
bool init();
|
|
||||||
void setRate();
|
|
||||||
libvlc_state_t getState() const;
|
|
||||||
|
|
||||||
libvlc_instance_t *m_vlcinstance;
|
|
||||||
libvlc_media_player_t *m_mPlayer;
|
|
||||||
libvlc_media_list_player_t *m_mListPlayer;
|
|
||||||
libvlc_media_list_t *m_mediaList;
|
|
||||||
|
|
||||||
int currentSpeedIdx;
|
|
||||||
|
|
||||||
QFrame *m_parent;
|
|
||||||
QTimer *m_timer;
|
|
||||||
AudioVideoInitThread *m_initThread;
|
|
||||||
|
|
||||||
Ui::audioVideoWidget *ui;
|
|
||||||
|
|
||||||
NGL::INGLLogger &m_logger;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AudioVideoInitThread final : public QThread
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit AudioVideoInitThread(AudioVideoWidget::Private *p);
|
|
||||||
protected:
|
|
||||||
void run() override;
|
|
||||||
protected:
|
|
||||||
AudioVideoWidget::Private *m_private;
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
-118
@@ -1,118 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* HMI Plugin for MeteoDataManagement - Meteo Data Overview Dialog
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Patric Karwat, SLSE, 2016-10-05
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_building_settings.h"
|
|
||||||
#include "ui_thp_building_settings.h"
|
|
||||||
#include <BuildingViewer/Common/bdv_controller.h>
|
|
||||||
|
|
||||||
#include <LtsUtilsSettings/settings.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
static QVariant getSetting(const QString &key, const QVariant &def)
|
|
||||||
{
|
|
||||||
return LtsUtils::OperatorSettings::getInstance()->value(QStringLiteral("BgViewer"), key, def);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setSetting(const QString &key, const QVariant &val)
|
|
||||||
{
|
|
||||||
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("BgViewer"), key, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
BgViewerSettingsView::BgViewerSettingsView(BuildingViewer::BgViewerController *pBgvController,
|
|
||||||
QWidget *parent)
|
|
||||||
: QDialog(parent)
|
|
||||||
, m_ui(new Ui::BgViewerSettingsUI)
|
|
||||||
, m_pBgvController(pBgvController)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
|
|
||||||
connect(m_ui->m_pCheckBoxGlobalIsoMode, &QCheckBox::clicked, this, &BgViewerSettingsView::onViewModeChanged);
|
|
||||||
connect(m_ui->m_pCheckBoxUseDotsMode, &QCheckBox::clicked, this, &BgViewerSettingsView::onPlayerDisplayModeChanged);
|
|
||||||
connect(m_ui->m_pSliderGlobalTransparency, &QSlider::valueChanged, this, &BgViewerSettingsView::onTransparencyChanged);
|
|
||||||
connect(m_ui->m_pSliderPlayerSymbolSize, &QSlider::valueChanged, this, &BgViewerSettingsView::onSymbolSizeChanged);
|
|
||||||
connect(m_ui->m_slider_SymbolFlashing, &QSlider::valueChanged, this, &BgViewerSettingsView::onSymbolFireEventFlashingChanged);
|
|
||||||
connect(m_ui->m_slider_HitlineDuration, &QSlider::valueChanged, this, &BgViewerSettingsView::onHitLineDisplayLengthChanged);
|
|
||||||
|
|
||||||
resetValues();
|
|
||||||
onSymbolFireEventFlashingChanged(m_ui->m_slider_HitlineDuration->value());
|
|
||||||
onHitLineDisplayLengthChanged(m_ui->m_slider_SymbolFlashing->value());
|
|
||||||
|
|
||||||
connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &BgViewerSettingsView::accept);
|
|
||||||
connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &BgViewerSettingsView::reject);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BgViewerSettingsView::~BgViewerSettingsView()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BgViewerSettingsView::accept()
|
|
||||||
{
|
|
||||||
setSetting(QStringLiteral("GlobalTransparency"), m_ui->m_pSliderGlobalTransparency->value());
|
|
||||||
setSetting(QStringLiteral("UseIsoMode"), m_ui->m_pCheckBoxGlobalIsoMode->isChecked());
|
|
||||||
setSetting(QStringLiteral("UseDotsMode"), m_ui->m_pCheckBoxUseDotsMode->isChecked());
|
|
||||||
setSetting(QStringLiteral("PlayerSymbolSize"), m_ui->m_pSliderPlayerSymbolSize->value());
|
|
||||||
setSetting(QStringLiteral("maxHitlineDurationTime_s"), m_ui->m_slider_HitlineDuration->value());
|
|
||||||
setSetting(QStringLiteral("GearFlashTime_s"), m_ui->m_slider_SymbolFlashing->value());
|
|
||||||
setSetting(QStringLiteral("maxGearFlashTime_s"), m_ui->m_slider_SymbolFlashing->maximum());
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::reject()
|
|
||||||
{
|
|
||||||
resetValues();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::resetValues()
|
|
||||||
{
|
|
||||||
m_ui->m_pSliderGlobalTransparency->setValue(getSetting(QStringLiteral("GlobalTransparency"), 75).toInt());
|
|
||||||
m_ui->m_pCheckBoxGlobalIsoMode->setChecked(getSetting(QStringLiteral("UseIsoMode"), false).toBool());
|
|
||||||
m_ui->m_pCheckBoxUseDotsMode->setChecked(getSetting(QStringLiteral("UseDotsMode"), false).toBool()) ;
|
|
||||||
m_ui->m_pSliderPlayerSymbolSize->setValue(getSetting(QStringLiteral("PlayerSymbolSize"), 20).toInt());
|
|
||||||
m_ui->m_slider_HitlineDuration->setValue(getSetting(QStringLiteral("maxHitlineDurationTime_s"), 10).toInt());
|
|
||||||
m_ui->m_slider_SymbolFlashing->setValue(getSetting(QStringLiteral("GearFlashTime_s"), 10).toInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::onViewModeChanged()
|
|
||||||
{
|
|
||||||
m_pBgvController->excSetGlobalViewMode(m_ui->m_pCheckBoxGlobalIsoMode->isChecked());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::onPlayerDisplayModeChanged()
|
|
||||||
{
|
|
||||||
m_pBgvController->excSetGlobalDotsMode(m_ui->m_pCheckBoxUseDotsMode->isChecked());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::onSymbolSizeChanged()
|
|
||||||
{
|
|
||||||
m_pBgvController->updatePlayerSymbols(m_ui->m_pSliderPlayerSymbolSize->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::onTransparencyChanged()
|
|
||||||
{
|
|
||||||
m_pBgvController->excSetGlobalTransparency(m_ui->m_pSliderGlobalTransparency->value());
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::onSymbolFireEventFlashingChanged(int val)
|
|
||||||
{
|
|
||||||
// only modified per config setting...
|
|
||||||
m_ui->m_label_durationSymbolFlashing->setText(tr("%1 sec").arg(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
void BgViewerSettingsView::onHitLineDisplayLengthChanged(int val)
|
|
||||||
{
|
|
||||||
m_pBgvController->excSetHitlineDuration(val);
|
|
||||||
m_ui->m_label_HitlineDuration->setText(tr("%1 sec").arg(val));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace BuildingViewer
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* HMI Plugin for MeteoDataManagement - Meteo Data Overview Dialog
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
* Created by Patric Karwat, SLSE, 2016-10-05
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <LtsWidgets/lts_dialog.h>
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class BgViewerSettingsUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace BuildingViewer
|
|
||||||
{
|
|
||||||
class BgViewerController;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class BgViewerSettingsView final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit BgViewerSettingsView(BuildingViewer::BgViewerController *pBgvController,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
~BgViewerSettingsView();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onViewModeChanged();
|
|
||||||
void onPlayerDisplayModeChanged();
|
|
||||||
void onTransparencyChanged();
|
|
||||||
void onSymbolSizeChanged();
|
|
||||||
void onSymbolFireEventFlashingChanged(int val);
|
|
||||||
void onHitLineDisplayLengthChanged(int val);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void accept() override;
|
|
||||||
void reject() override;
|
|
||||||
void resetValues();
|
|
||||||
|
|
||||||
Ui::BgViewerSettingsUI *m_ui;
|
|
||||||
BuildingViewer::BgViewerController *m_pBgvController;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace BuildingViewer
|
|
||||||
-181
@@ -1,181 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>BgViewerSettingsUI</class>
|
|
||||||
<widget class="QWidget" name="BgViewerSettingsUI">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>300</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">General Settings</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout_2" columnstretch="2">
|
|
||||||
<item row="1" column="0">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QSlider" name="m_pSliderGlobalTransparency">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>100</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>75</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QCheckBox" name="m_pCheckBoxGlobalIsoMode">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Use orthographic view mode</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Player symbol size:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="2">
|
|
||||||
<widget class="QLabel" name="m_label_durationSymbolFlashing">
|
|
||||||
<property name="text">
|
|
||||||
<string>%1 sec</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QLabel" name="m_label_HitlineDuration">
|
|
||||||
<property name="text">
|
|
||||||
<string>%1 sec</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="label_3">
|
|
||||||
<property name="text">
|
|
||||||
<string>Symbol fire event flashing:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QSlider" name="m_pSliderPlayerSymbolSize">
|
|
||||||
<property name="minimum">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>45</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>20</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Transparency value:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QLabel" name="label_4">
|
|
||||||
<property name="text">
|
|
||||||
<string>Hit line display length:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QSlider" name="m_slider_HitlineDuration">
|
|
||||||
<property name="maximum">
|
|
||||||
<number>120</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QCheckBox" name="m_pCheckBoxUseDotsMode">
|
|
||||||
<property name="text">
|
|
||||||
<string>Use dots mode</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QSlider" name="m_slider_SymbolFlashing">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>120</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle bulding display in thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_building_widget.h"
|
|
||||||
#include "ui_thp_situation_building_base.h"
|
|
||||||
#include "thp_building_settings.h"
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
|
|
||||||
#include <QMenu>
|
|
||||||
|
|
||||||
#include <BuildingViewer/Common/bdv_controller.h>
|
|
||||||
#include <BuildingViewer/Common/bdv_plugin_provider.h>
|
|
||||||
#include <LtsScriptTimeline/track_entry.h>
|
|
||||||
#include <LtsWidgets/lts_dialog_helper.h>
|
|
||||||
|
|
||||||
#include <SituationReplay/handler_situation_replay_sqlite.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
using namespace SituationReplay;
|
|
||||||
|
|
||||||
BuildingWidget::BuildingWidget(QWidget *parent)
|
|
||||||
: SituationBuildingBase("THP.BuildingWidget", parent)
|
|
||||||
{
|
|
||||||
QMenu *m = new QMenu(m_ui->btnFilter);
|
|
||||||
m->addAction(tr("Global Settings"), this, &BuildingWidget::onGlobalSettings);
|
|
||||||
m_ui->btnFilter->setMenu(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildingWidget::~BuildingWidget()
|
|
||||||
{
|
|
||||||
delete m_bgvController;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildingWidget::init(SituationReplay::MainHandlerSqlite *mhs, BuildingPluginProvider *pp, const QString &homePath)
|
|
||||||
{
|
|
||||||
if (!SituationBuildingBase::init(mhs))
|
|
||||||
return false;
|
|
||||||
m_replayHandler = mhs;
|
|
||||||
m_pluginProvider = pp;
|
|
||||||
|
|
||||||
// parse json, create xml, init buildingviewer
|
|
||||||
delete m_bgvController;
|
|
||||||
m_bgvController = new BuildingViewer::BgViewerController(this);
|
|
||||||
if (!m_bgvController->init(m_pluginProvider, true, homePath + QStringLiteral("/BuildingModels/")))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto w = m_bgvController->getBgViewerWidget();
|
|
||||||
w->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
m_ui->vLayout->insertWidget(0, w);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BuildingWidget::showSituationInternal()
|
|
||||||
{
|
|
||||||
m_bgvController->excRestoreViewState(m_attributes[QStringLiteral("arrBuildingStates")]);
|
|
||||||
if (!SituationBuildingBase::showSituationInternal())
|
|
||||||
return false;
|
|
||||||
onInitDone();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildingWidget::emitPartitionTimeChanged(qint64 curTime)
|
|
||||||
{
|
|
||||||
m_pluginProvider->emitPartitionTimeChanged(curTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BuildingWidget::onGlobalSettings()
|
|
||||||
{
|
|
||||||
if (!m_globalSettingsDialog)
|
|
||||||
m_globalSettingsDialog = new BgViewerSettingsView(m_bgvController, this);
|
|
||||||
m_globalSettingsDialog->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle bulding display in thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SituationReplay/main_handler_sqlite.h>
|
|
||||||
#include "thp_situation_building_base.h"
|
|
||||||
|
|
||||||
namespace BuildingViewer
|
|
||||||
{
|
|
||||||
class BgViewerController;
|
|
||||||
}
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class BuildingWidget;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class BuildingPluginProvider;
|
|
||||||
class BgViewerSettingsView;
|
|
||||||
class BuildingWidget : public SituationBuildingBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
BuildingWidget(QWidget *parent = nullptr);
|
|
||||||
~BuildingWidget();
|
|
||||||
|
|
||||||
bool init(SituationReplay::MainHandlerSqlite *mhs,
|
|
||||||
BuildingPluginProvider *pp,
|
|
||||||
const QString &homePath);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool showSituationInternal() override;
|
|
||||||
void emitPartitionTimeChanged(qint64 curTime) override;
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onGlobalSettings();
|
|
||||||
virtual void applyCurentFilter(const SituationReplay::FilterInformation &) override {}
|
|
||||||
virtual void applyNewOverlay(int) override {}
|
|
||||||
virtual void removeOverlay(int) override {}
|
|
||||||
private:
|
|
||||||
BuildingPluginProvider *m_pluginProvider = nullptr;
|
|
||||||
BuildingViewer::BgViewerController *m_bgvController = nullptr;
|
|
||||||
BgViewerSettingsView *m_globalSettingsDialog = nullptr;
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle HTML output for thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#include "thp_html_widget.h"
|
|
||||||
#include "ui_thp_html_widget.h"
|
|
||||||
|
|
||||||
#include <QUrl>
|
|
||||||
#include <QWebEnginePage>
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
class MyQWebEnginePage : public QWebEnginePage
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit MyQWebEnginePage(NGL::INGLLogger &logger, QObject *parent = nullptr)
|
|
||||||
: QWebEnginePage(parent)
|
|
||||||
, m_logger(logger)
|
|
||||||
{}
|
|
||||||
MyQWebEnginePage(NGL::INGLLogger &logger, QWebEngineProfile *profile, QObject *parent = nullptr)
|
|
||||||
: QWebEnginePage(profile, parent)
|
|
||||||
, m_logger(logger)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool needsToBeOpenedExternally(const QUrl &url)
|
|
||||||
{
|
|
||||||
const QString lpath = url.toString();
|
|
||||||
const QStringView ext = QStringView{lpath}.split(QLatin1Char('.')).last();
|
|
||||||
const QStringView ext2Chars = ext.left(2);
|
|
||||||
if (ext == QLatin1String("html") &&
|
|
||||||
QStringView{lpath}.mid(lpath.lastIndexOf(QLatin1Char('/')) + 1).startsWith(QLatin1String("combined_")))
|
|
||||||
return true;
|
|
||||||
// PDF
|
|
||||||
if (ext == QLatin1String("pdf"))
|
|
||||||
return true;
|
|
||||||
// A/V playlist
|
|
||||||
if (ext == QLatin1String("pls"))
|
|
||||||
return true;
|
|
||||||
// Situation
|
|
||||||
if (ext == QLatin1String("json"))
|
|
||||||
return true;
|
|
||||||
// Word/Excel/PowerPoint
|
|
||||||
if (ext2Chars == QLatin1String("do") ||
|
|
||||||
ext2Chars == QLatin1String("xl") ||
|
|
||||||
ext2Chars == QLatin1String("pp"))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool acceptNavigationRequest(const QUrl &url,
|
|
||||||
QWebEnginePage::NavigationType type,
|
|
||||||
bool isMainFrame) override
|
|
||||||
{
|
|
||||||
Q_UNUSED(isMainFrame)
|
|
||||||
if (type == QWebEnginePage::NavigationTypeLinkClicked)
|
|
||||||
{
|
|
||||||
if (needsToBeOpenedExternally(url))
|
|
||||||
{
|
|
||||||
emit linkClicked(url);
|
|
||||||
DEBUG_LOG(m_logger) << "acceptNavigationRequest denied for " << url.toString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DEBUG_LOG(m_logger) << "acceptNavigationRequest allowed for " << url.toString();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void linkClicked(const QUrl &url);
|
|
||||||
private:
|
|
||||||
NGL::INGLLogger &m_logger;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
HtmlWidget::HtmlWidget(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, ui(new Ui::HtmlWidget)
|
|
||||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("THP.HtmlWidget"))
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
auto webEnginePage = new MyQWebEnginePage(m_logger, this);
|
|
||||||
ui->html->setPage(webEnginePage);
|
|
||||||
connect(webEnginePage, &MyQWebEnginePage::linkClicked, this, &HtmlWidget::linkClicked);
|
|
||||||
connect(ui->html, &QWebEngineView::loadFinished, this, &HtmlWidget::loadFinished);
|
|
||||||
connect(ui->html, &QWebEngineView::urlChanged, this, &HtmlWidget::urlChanged);
|
|
||||||
connect(ui->html, &QWebEngineView::titleChanged, this, &HtmlWidget::titleChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
HtmlWidget::~HtmlWidget()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HtmlWidget::back()
|
|
||||||
{
|
|
||||||
ui->html->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString HtmlWidget::title() const
|
|
||||||
{
|
|
||||||
return ui->html->title();
|
|
||||||
}
|
|
||||||
|
|
||||||
QUrl HtmlWidget::url() const
|
|
||||||
{
|
|
||||||
return ui->html->url();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HtmlWidget::showHTML(const QUrl &url)
|
|
||||||
{
|
|
||||||
if (!url.isValid())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Invalid url: " << url.toString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ui->html->load(url);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HtmlWidget::setZoomFactor(double newZoomFactor)
|
|
||||||
{
|
|
||||||
ui->html->setZoomFactor(newZoomFactor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HtmlWidget::print(QPrinter *printer) const
|
|
||||||
{
|
|
||||||
ui->html->page()->print(printer, [](bool) {});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
|
|
||||||
#include "thp_html_widget.moc"
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle HTML output for thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <QWidget>
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
|
|
||||||
class QUrl;
|
|
||||||
class QPrinter;
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class HtmlWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class HtmlWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit HtmlWidget(QWidget *parent = nullptr);
|
|
||||||
~HtmlWidget();
|
|
||||||
|
|
||||||
void back();
|
|
||||||
void print(QPrinter *printer) const;
|
|
||||||
void setZoomFactor(double newZoomFactor);
|
|
||||||
QString title() const;
|
|
||||||
QUrl url() const;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
bool showHTML(const QUrl &url);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void linkClicked(const QUrl &link);
|
|
||||||
void loadFinished(bool);
|
|
||||||
void urlChanged(const QUrl &url);
|
|
||||||
void titleChanged(const QString &title);
|
|
||||||
protected:
|
|
||||||
Ui::HtmlWidget *ui;
|
|
||||||
NGL::INGLLogger &m_logger;
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>HtmlWidget</class>
|
|
||||||
<widget class="QWidget" name="HtmlWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>719</width>
|
|
||||||
<height>540</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QWebEngineView" name="html">
|
|
||||||
<property name="url">
|
|
||||||
<url>
|
|
||||||
<string>about:blank</string>
|
|
||||||
</url>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>QWebEngineView</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">QtWebEngineWidgets/QWebEngineView</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle PDF output for thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#include "thp_pdf_widget.h"
|
|
||||||
#include "ui_thp_pdf_widget.h"
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
PdfWidget::PdfWidget(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, ui(new Ui::PdfWidget)
|
|
||||||
{
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
connect(ui->previousPage, &QToolButton::clicked, this, &PdfWidget::onPreviousPage);
|
|
||||||
connect(ui->nextPage, &QToolButton::clicked, this, &PdfWidget::onNextPage);
|
|
||||||
connect(ui->pdfDocument, &NGL::PDFDocument::currentPageChanged, this, &PdfWidget::pageChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
PdfWidget::~PdfWidget()
|
|
||||||
{
|
|
||||||
delete ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PdfWidget::showPDF(const QUrl &pdf)
|
|
||||||
{
|
|
||||||
return ui->pdfDocument->showPDF(pdf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfWidget::setZoomFactor(double newZoomFactor)
|
|
||||||
{
|
|
||||||
ui->pdfDocument->setZoomFactor(newZoomFactor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfWidget::onPreviousPage()
|
|
||||||
{
|
|
||||||
ui->pdfDocument->previousPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfWidget::onNextPage()
|
|
||||||
{
|
|
||||||
ui->pdfDocument->nextPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<QImage> PdfWidget::getPrintableImages(int resolution)
|
|
||||||
{
|
|
||||||
return ui->pdfDocument->getPrintableImages(resolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfWidget::resizePdfToWidth()
|
|
||||||
{
|
|
||||||
ui->pdfDocument->resizePdfToWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PdfWidget::pageChanged(int cur, int max)
|
|
||||||
{
|
|
||||||
ui->pageLabel->setText(tr("Page %1 of %2").arg(cur).arg(max));
|
|
||||||
ui->nextPage->setEnabled(cur < max);
|
|
||||||
ui->previousPage->setEnabled(cur > 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle PDF output for thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
|
|
||||||
class QUrl;
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class PdfWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class PdfWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit PdfWidget(QWidget *parent = nullptr);
|
|
||||||
~PdfWidget();
|
|
||||||
|
|
||||||
bool showPDF(const QUrl &pdf);
|
|
||||||
void setZoomFactor(double newZoomFactor);
|
|
||||||
QVector<QImage> getPrintableImages(int resolution = 300);
|
|
||||||
void resizePdfToWidth();
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void onPreviousPage();
|
|
||||||
void onNextPage();
|
|
||||||
void pageChanged(int cur, int max);
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Ui::PdfWidget *ui;
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>PdfWidget</class>
|
|
||||||
<widget class="QWidget" name="PdfWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>580</width>
|
|
||||||
<height>396</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item row="0" column="0" colspan="3">
|
|
||||||
<widget class="NGL::PDFDocument" name="pdfDocument" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>202</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="previousPage">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/go-previous.png</normaloff>:icons/16x16/go-previous.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+P</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="pageLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>page %1 of %2</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="nextPage">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/go-next.png</normaloff>:icons/16x16/go-next.png</iconset>
|
|
||||||
</property>
|
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>16</width>
|
|
||||||
<height>16</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+N</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="2">
|
|
||||||
<spacer name="horizontalSpacer_4">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>201</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>NGL::PDFDocument</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">nglwidgets/nglpdfdocument.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
-488
@@ -1,488 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle situation display in thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_building_base.h"
|
|
||||||
#include "ui_thp_situation_building_base.h"
|
|
||||||
|
|
||||||
#include "thp_situation_filter_aes.h"
|
|
||||||
#include "thp_situation_filter_symbol_appearance.h"
|
|
||||||
#include "thp_situation_filter_collapse_expand.h"
|
|
||||||
#include "thp_situation_filter_types.h"
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <LtsScriptTimeline/track_entry.h>
|
|
||||||
#include <LtsUtilsCore/qpoint3d.h>
|
|
||||||
|
|
||||||
#include <SituationReplay/handler_situation_replay_sqlite.h>
|
|
||||||
#include <PlanOverlays/Gui/plan_overlay_model.h>
|
|
||||||
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <ngltools/ngltools_dtg.h>
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
using namespace SituationReplay;
|
|
||||||
|
|
||||||
SituationBuildingBase::SituationBuildingBase(const char *loggerName,
|
|
||||||
QWidget *parent)
|
|
||||||
: QFrame(parent)
|
|
||||||
, m_playTimer(new QTimer(this))
|
|
||||||
, m_ui(new Ui::SituationBuildingBase)
|
|
||||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName))
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
m_ui->zoomSlider->hide();
|
|
||||||
m_ui->sldPosition->setMinimum(0);
|
|
||||||
m_ui->sldPosition->setMaximum(s_sliderMax);
|
|
||||||
|
|
||||||
m_playTimer->setSingleShot(true);
|
|
||||||
connect(m_playTimer, &QTimer::timeout, this, &SituationBuildingBase::onPlay);
|
|
||||||
|
|
||||||
connect(m_ui->btnSlower, &QToolButton::clicked, this, &SituationBuildingBase::onSlower);
|
|
||||||
connect(m_ui->btnFaster, &QToolButton::clicked, this, &SituationBuildingBase::onFaster);
|
|
||||||
connect(m_ui->btn100pct, &QToolButton::clicked, this, &SituationBuildingBase::on100pct);
|
|
||||||
connect(m_ui->btnPlay, &QToolButton::clicked, this, &SituationBuildingBase::onPlay);
|
|
||||||
connect(m_ui->btnStop, &QToolButton::clicked, this, &SituationBuildingBase::onStop);
|
|
||||||
|
|
||||||
connect(m_ui->sldPosition, &QSlider::sliderPressed, this, &SituationBuildingBase::onSliderPressed);
|
|
||||||
connect(m_ui->sldPosition, &QSlider::sliderMoved, this, &SituationBuildingBase::onSliderPositionChanged);
|
|
||||||
connect(m_ui->sldPosition, &QSlider::sliderReleased, this, &SituationBuildingBase::onSliderReleased);
|
|
||||||
|
|
||||||
connect(m_ui->cbPlaybackParts, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
|
||||||
this, &SituationBuildingBase::onCbPlaybackPartsChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
SituationBuildingBase::~SituationBuildingBase()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationBuildingBase::init(SituationReplay::MainHandlerSqlite *replayHandler)
|
|
||||||
{
|
|
||||||
if (m_replayHandler)
|
|
||||||
m_replayHandler->disconnect(this);
|
|
||||||
m_replayHandler = replayHandler;
|
|
||||||
connect(m_replayHandler, &SituationReplay::MainHandlerSqlite::initialReplaySpeed,
|
|
||||||
this, &SituationBuildingBase::setSpeed);
|
|
||||||
connect(m_replayHandler, &SituationReplay::MainHandlerSqlite::applyCurentFilter,
|
|
||||||
this, &SituationBuildingBase::applyCurentFilter);
|
|
||||||
connect(m_replayHandler, &SituationReplay::MainHandlerSqlite::applyNewOverlay,
|
|
||||||
this, &SituationBuildingBase::applyNewOverlay);
|
|
||||||
connect(m_replayHandler, &SituationReplay::MainHandlerSqlite::removeOverlay,
|
|
||||||
this, &SituationBuildingBase::removeOverlay);
|
|
||||||
connect(m_replayHandler, &SituationReplay::MainHandlerSqlite::fileContentAvailable,
|
|
||||||
this, &SituationBuildingBase::onFileContentAvailable);
|
|
||||||
updatePositionLabel(LtsUtils::QPoint3D(), false);
|
|
||||||
updateSpeedLabel();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationBuildingBase::showSituation(const QString &sitReplayDescription,
|
|
||||||
const QString &basePath)
|
|
||||||
{
|
|
||||||
// read ReplayInformation from sitmap.json (key 'replays')
|
|
||||||
|
|
||||||
QFile f(sitReplayDescription); // ...Exercise_123//n/m/sitmap.json
|
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not open file '" << sitReplayDescription << "': " << f.errorString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfo fi(f);
|
|
||||||
m_scriptPath = fi.absolutePath();
|
|
||||||
|
|
||||||
QJsonParseError jError;
|
|
||||||
const QByteArray ba = f.readAll();
|
|
||||||
QJsonDocument doc(QJsonDocument::fromJson(ba, &jError));
|
|
||||||
if (jError.error)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document: " << jError.errorString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const QJsonObject rootObj = doc.object();
|
|
||||||
const QJsonArray arrReplays(rootObj[QStringLiteral("replays")].toArray());
|
|
||||||
QVector<ReplayInformation> replayInformation;
|
|
||||||
replayInformation.reserve(arrReplays.size());
|
|
||||||
for (const auto &val : arrReplays)
|
|
||||||
{
|
|
||||||
const QJsonObject obj = val.toObject();
|
|
||||||
const QJsonObject objPb = obj[QStringLiteral("playbackTime")].toObject();
|
|
||||||
const QJsonObject objSqlite = obj[QStringLiteral("replayInformation")].toObject();
|
|
||||||
const QJsonObject objTip = objSqlite[QStringLiteral("timeInPresentation")].toObject();
|
|
||||||
ReplayInformation info;
|
|
||||||
info.id = obj[QStringLiteral("id")].toInt();
|
|
||||||
info.timeSpan = TimeSpan::fromJson(objPb);
|
|
||||||
info.relativeTimeSpan = TimeSpan::fromJson(objTip);
|
|
||||||
const int sqliteFolderId = objSqlite[QStringLiteral("id")].toInt();
|
|
||||||
info.databaseFilePath = QStringLiteral("%1/%2/sitreplay.sqlite").arg(basePath).arg(sqliteFolderId);
|
|
||||||
info.replayConfigPath = QStringLiteral("%1/%2/sitreplay.json").arg(basePath).arg(sqliteFolderId);
|
|
||||||
if (info.relativeTimeSpan.begin < 0 ||
|
|
||||||
info.relativeTimeSpan.end <= info.relativeTimeSpan.begin ||
|
|
||||||
sqliteFolderId == 0)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document: " << QJsonDocument(obj).toJson();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
replayInformation.push_back(std::move(info));
|
|
||||||
}
|
|
||||||
const QJsonObject attributes(rootObj[QStringLiteral("attributes")].toObject());
|
|
||||||
const QJsonArray arrFilters1(attributes[QStringLiteral("Filters")].toArray());
|
|
||||||
QVector<FilterInformation> filterInformation;
|
|
||||||
QVector<FilterInformation> overlayInformation;
|
|
||||||
|
|
||||||
for (const auto &arrVal : arrFilters1)
|
|
||||||
{
|
|
||||||
// const QJsonArray arrFilters2(arrVal.toArray());
|
|
||||||
// for (const auto &val : arrFilters2)
|
|
||||||
// {
|
|
||||||
FilterInformation filter;
|
|
||||||
const QJsonObject obj = arrVal.toObject();
|
|
||||||
LtsScriptTimeline::TrackEntry te;
|
|
||||||
te.fromJson(obj);
|
|
||||||
if (te.m_topicId <= 0)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not load filter information from '" << QJsonDocument(obj).toJson() << "'";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (te.m_type != LtsScriptTimeline::TrackEntryType::SituationMapFilter &&
|
|
||||||
te.m_type != LtsScriptTimeline::TrackEntryType::TacticalPlan)
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Unknown Filter type " << te.m_type << " - ignoring: " << QJsonDocument(obj).toJson() << "'";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
filter.id = te.m_topicId;
|
|
||||||
filter.relativeTimeSpan.begin = te.m_startTime * 1000LL;
|
|
||||||
filter.relativeTimeSpan.end = te.m_length * 1000LL + filter.relativeTimeSpan.begin;
|
|
||||||
const QJsonObject details = obj[QStringLiteral("detailData")].toObject();
|
|
||||||
if (te.m_type == LtsScriptTimeline::TrackEntryType::SituationMapFilter)
|
|
||||||
{
|
|
||||||
const QJsonObject filters = te.m_detailData[QStringLiteral("filters")].toObject();
|
|
||||||
filter.aesFilters = filters[QStringLiteral("AesFilterJson")].toObject();
|
|
||||||
filter.symbolSettings = filters[QStringLiteral("SymbolAppearanceJson")].toObject();
|
|
||||||
filter.buildingComponentSettings = filters[QStringLiteral("BuildingComponentSettingsJson")].toObject();
|
|
||||||
filter.mapSettings = details[QStringLiteral("settings")].toObject();
|
|
||||||
|
|
||||||
if (filter.relativeTimeSpan.begin < 0 || filter.aesFilters.isEmpty() || filter.symbolSettings.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document - can not read filter data " << QJsonDocument(obj).toJson();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (filter.buildingComponentSettings.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document - can not read filter data 'BuildingComponentSettingsJson', json= " << QJsonDocument(obj).toJson();
|
|
||||||
// return false; // support older thps with this thpViewer
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
filterInformation.push_back(std::move(filter));
|
|
||||||
}
|
|
||||||
else if (te.m_type == LtsScriptTimeline::TrackEntryType::TacticalPlan)
|
|
||||||
{
|
|
||||||
if (filter.relativeTimeSpan.begin < 0)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document - can not read filter data " << QJsonDocument(obj).toJson();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// old version (before 2020/02)
|
|
||||||
filter.overlayId = details[QStringLiteral("FileId")].toInt(-1);
|
|
||||||
if (filter.overlayId >= 0)
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "Add overlay with id " << filter.overlayId;
|
|
||||||
overlayInformation.push_back(std::move(filter));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const QJsonArray arr = details[QStringLiteral("PlanItems")].toArray();
|
|
||||||
if (arr.isEmpty())
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << "No PlanItems given - " << QJsonDocument(details).toJson();
|
|
||||||
}
|
|
||||||
for (const auto &ele : arr)
|
|
||||||
{
|
|
||||||
const auto pi = PlanOverlaysPlugin::PlanOverlayModel::PlanItem::fromJson(ele.toObject());
|
|
||||||
if (!pi.isValid() || pi.m_fileId <= 0)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document - can not read filter data " << QJsonDocument(ele.toObject()).toJson();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
filter.overlayId = pi.m_fileId;
|
|
||||||
DEBUG_LOG(m_logger) << "Add overlay with id " << filter.overlayId;
|
|
||||||
overlayInformation.push_back(filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
m_replayInformation = replayInformation;
|
|
||||||
m_filterInformation = filterInformation;
|
|
||||||
m_overlayInformation = overlayInformation;
|
|
||||||
m_attributes = rootObj[QStringLiteral("attributes")].toObject();
|
|
||||||
return showSituationInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationBuildingBase::showSituationInternal()
|
|
||||||
{
|
|
||||||
m_ui->cbPlaybackParts->setVisible(m_replayInformation.size() > 1);
|
|
||||||
if (m_replayInformation.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "No replay information given...";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString sqliteDb = m_replayInformation.first().databaseFilePath;
|
|
||||||
if (sqliteDb.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "No database given...";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QFileInfo fi(sqliteDb);
|
|
||||||
if (!fi.exists() || !fi.isFile() || !fi.isReadable())
|
|
||||||
{
|
|
||||||
Q_ASSERT(false);
|
|
||||||
WARNING_LOG(m_logger) << "Can not access sqlite database '" << fi.absoluteFilePath() << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ui->cbPlaybackParts->clear();
|
|
||||||
m_ui->cbPlaybackParts->blockSignals(true);
|
|
||||||
for (int i = 0; i < m_replayInformation.size(); ++i)
|
|
||||||
{
|
|
||||||
const ReplayInformation &info = m_replayInformation.at(i);
|
|
||||||
m_ui->cbPlaybackParts->addItem(QStringLiteral("%1: %2 - %3").arg(i+1).arg(DTG::toStringMSec(info.timeSpan.begin, DTG::Long),
|
|
||||||
DTG::toStringMSec(info.timeSpan.end, DTG::Long)), i);
|
|
||||||
}
|
|
||||||
m_ui->cbPlaybackParts->setCurrentIndex(0);
|
|
||||||
m_ui->cbPlaybackParts->blockSignals(false);
|
|
||||||
onCbPlaybackPartsChanged(); // creates replayHandler for correct db etc.
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::setSpeed(double newSpeed)
|
|
||||||
{
|
|
||||||
m_speedVal = qBound(0.0, newSpeed, 16.0);
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onPaceChangeRequest(m_speedVal);
|
|
||||||
|
|
||||||
updateSpeedLabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onSlower()
|
|
||||||
{
|
|
||||||
// cur speed = 9 -> new speed = 7
|
|
||||||
// cur speed = 4 -> new speed = 3
|
|
||||||
int diff = lrint(sqrt(m_speedVal) - 1);
|
|
||||||
if (diff < 1)
|
|
||||||
diff = 1;
|
|
||||||
setSpeed(m_speedVal - diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onFaster()
|
|
||||||
{
|
|
||||||
int diff = lrint(sqrt(m_speedVal) - 1);
|
|
||||||
if (diff < 1)
|
|
||||||
diff = 1;
|
|
||||||
setSpeed(m_speedVal + diff);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::on100pct()
|
|
||||||
{
|
|
||||||
setSpeed(1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onPlay()
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << "OnPlay " << int(m_state);
|
|
||||||
switch (m_state)
|
|
||||||
{
|
|
||||||
case State::PS_STOP:
|
|
||||||
m_state = State::PS_PLAY;
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onStartReplayRequest(m_speedVal);
|
|
||||||
break;
|
|
||||||
case State::PS_PAUSE:
|
|
||||||
m_state = State::PS_PLAY;
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onResumeReplayRequest();
|
|
||||||
break;
|
|
||||||
case State::PS_PLAY:
|
|
||||||
m_state = State::PS_PAUSE;
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onPauseReplayRequest();
|
|
||||||
break;
|
|
||||||
case State::PS_UNDEFINED:
|
|
||||||
// dürfte nicht vorkommen
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onStop()
|
|
||||||
{
|
|
||||||
auto srp = m_replayHandler->handlerSrp();
|
|
||||||
if (srp)
|
|
||||||
{
|
|
||||||
srp->onStopReplayRequest();
|
|
||||||
onUpdateTimeSlider(srp->beginTime());
|
|
||||||
}
|
|
||||||
m_state = State::PS_STOP;
|
|
||||||
updateButtons();
|
|
||||||
m_ui->sldPosition->setValue(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onSliderPressed()
|
|
||||||
{
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onPauseReplayRequest();
|
|
||||||
m_state = State::PS_PAUSE;
|
|
||||||
updateButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onSliderPositionChanged(int newPosition)
|
|
||||||
{
|
|
||||||
if (!m_replayHandler->handlerSrp())
|
|
||||||
return;
|
|
||||||
auto srp = m_replayHandler->handlerSrp();
|
|
||||||
const double len = (srp->endTime() - srp->beginTime());
|
|
||||||
const double ofs = newPosition * len / s_sliderMax;
|
|
||||||
m_sliderMoveTime = qRound64(srp->beginTime() + ofs);
|
|
||||||
|
|
||||||
m_currentTimeDTGString = DTG::toStringMSec(m_sliderMoveTime, DTG::Long);
|
|
||||||
m_ui->lblPosition->setText(m_currentTimeDTGString);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onSliderReleased()
|
|
||||||
{
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onStartReplayRequest(m_sliderMoveTime,
|
|
||||||
m_replayHandler->handlerSrp()->endTime(),
|
|
||||||
m_speedVal);
|
|
||||||
m_state = State::PS_PLAY;
|
|
||||||
updateButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onUpdateTimeSlider(qint64 curTime)
|
|
||||||
{
|
|
||||||
if (!m_replayHandler->handlerSrp() || m_state == State::PS_STOP)
|
|
||||||
return;
|
|
||||||
const auto srp = m_replayHandler->handlerSrp();
|
|
||||||
const double len = (srp->endTime() - srp->beginTime());
|
|
||||||
const double ofs = (curTime - srp->beginTime());
|
|
||||||
double pos = ofs / len * s_sliderMax;
|
|
||||||
if (pos < 0)
|
|
||||||
pos = 0;
|
|
||||||
if (pos >= s_sliderMax)
|
|
||||||
{
|
|
||||||
onStop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
DEBUG_LOG(m_logger) << "onUpdateTimeSlider: " << curTime << ", pos: " << pos;
|
|
||||||
m_ui->sldPosition->setValue(qRound(pos));
|
|
||||||
|
|
||||||
m_currentTimeDTGString = DTG::toStringMSec(curTime, DTG::Long);
|
|
||||||
m_ui->lblPosition->setText(m_currentTimeDTGString);
|
|
||||||
emitPartitionTimeChanged(curTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onCbPlaybackPartsChanged()
|
|
||||||
{
|
|
||||||
onStop();
|
|
||||||
int idx = m_ui->cbPlaybackParts->currentData().toInt();
|
|
||||||
if (idx < 0 || idx >= m_replayInformation.size())
|
|
||||||
return;
|
|
||||||
const ReplayInformation &info = m_replayInformation.at(idx);
|
|
||||||
if (!m_replayHandler->initDb(info, m_filterInformation, m_overlayInformation))
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not initialize replay handler (" << info.databaseFilePath << ")";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// currently after initDb since there handlerSrp is (re)created
|
|
||||||
connect(m_replayHandler->handlerSrp().get(), &SituationReplay::HandlerSituationReplaySqlite::replayTimeChanged,
|
|
||||||
this, &SituationBuildingBase::onUpdateTimeSlider, Qt::UniqueConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::updateSpeedLabel()
|
|
||||||
{
|
|
||||||
QString speedStr = QStringLiteral("%1x").arg(m_speedVal, 4, 'f', 2);
|
|
||||||
m_ui->lblSpeed->setText(speedStr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::updatePositionLabel(const LtsUtils::QPoint3D &geoPos, bool isValid)
|
|
||||||
{
|
|
||||||
if (isValid)
|
|
||||||
{
|
|
||||||
const LtsCoordTrans::UtmCoordinate coord(LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.x(), geoPos.y()));
|
|
||||||
m_ui->lblCursorPos->setText(coord.mgrs());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_ui->lblCursorPos->setText(QString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SituationBuildingBase::currentDTGTime() const
|
|
||||||
{
|
|
||||||
return m_currentTimeDTGString;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::updateButtons()
|
|
||||||
{
|
|
||||||
switch (m_state)
|
|
||||||
{
|
|
||||||
case State::PS_UNDEFINED:
|
|
||||||
m_ui->btnStop->setEnabled(false);
|
|
||||||
m_ui->btnPlay->setEnabled(false);
|
|
||||||
m_ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
|
|
||||||
m_ui->sldPosition->setEnabled(false);
|
|
||||||
break;
|
|
||||||
case State::PS_STOP:
|
|
||||||
m_ui->btnStop->setEnabled(false);
|
|
||||||
m_ui->btnPlay->setEnabled(true);
|
|
||||||
m_ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
|
|
||||||
m_ui->sldPosition->setEnabled(true);
|
|
||||||
break;
|
|
||||||
case State::PS_PLAY:
|
|
||||||
m_ui->btnStop->setEnabled(true);
|
|
||||||
m_ui->btnPlay->setEnabled(true);
|
|
||||||
m_ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-pause.png")));
|
|
||||||
m_ui->sldPosition->setEnabled(true);
|
|
||||||
break;
|
|
||||||
case State::PS_PAUSE:
|
|
||||||
m_ui->btnStop->setEnabled(true);
|
|
||||||
m_ui->btnPlay->setEnabled(true);
|
|
||||||
m_ui->btnPlay->setIcon(QIcon(QStringLiteral(":icons/16x16/media-playback-start.png")));
|
|
||||||
m_ui->sldPosition->setEnabled(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationBuildingBase::stop()
|
|
||||||
{
|
|
||||||
onStop();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationBuildingBase::onInitDone()
|
|
||||||
{
|
|
||||||
m_state = State::PS_STOP;
|
|
||||||
m_playTimer->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
-105
@@ -1,105 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle situation / building display in thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QFrame>
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include <SituationReplay/main_handler_sqlite.h>
|
|
||||||
|
|
||||||
namespace FileManagement
|
|
||||||
{
|
|
||||||
namespace Database
|
|
||||||
{
|
|
||||||
struct FlmFileContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace SituationReplay
|
|
||||||
{
|
|
||||||
class MainHandlerSqlite;
|
|
||||||
}
|
|
||||||
namespace LtsUtils
|
|
||||||
{
|
|
||||||
class QPoint3D;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class SituationBuildingBase;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
enum class State
|
|
||||||
{
|
|
||||||
PS_UNDEFINED = 0,
|
|
||||||
PS_STOP = 1,
|
|
||||||
PS_PLAY = 2,
|
|
||||||
PS_PAUSE = 3
|
|
||||||
};
|
|
||||||
constexpr int s_sliderMax = 1000; // 0 .. 1000
|
|
||||||
|
|
||||||
class SituationBuildingBase : public QFrame
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituationBuildingBase(const char *loggerName,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
~SituationBuildingBase();
|
|
||||||
|
|
||||||
bool init(SituationReplay::MainHandlerSqlite *replayHandler);
|
|
||||||
bool showSituation(const QString &sitReplayDescription, const QString &basePath);
|
|
||||||
|
|
||||||
void updateButtons();
|
|
||||||
bool stop();
|
|
||||||
QString currentDTGTime() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual bool showSituationInternal();
|
|
||||||
|
|
||||||
protected Q_SLOTS:
|
|
||||||
void setSpeed(double newSpeed);
|
|
||||||
virtual void applyCurentFilter(const SituationReplay::FilterInformation &filter) = 0;
|
|
||||||
virtual void applyNewOverlay(int overlayId) = 0;
|
|
||||||
virtual void removeOverlay(int overlayId) = 0;
|
|
||||||
void onSlower();
|
|
||||||
void onFaster();
|
|
||||||
void on100pct();
|
|
||||||
void onPlay();
|
|
||||||
void onStop();
|
|
||||||
|
|
||||||
void onSliderPressed();
|
|
||||||
void onSliderPositionChanged(int newPosition);
|
|
||||||
void onSliderReleased();
|
|
||||||
void updateSpeedLabel();
|
|
||||||
void onUpdateTimeSlider(qint64 curTime);
|
|
||||||
void onCbPlaybackPartsChanged();
|
|
||||||
void updatePositionLabel(const LtsUtils::QPoint3D &geoPos, bool isValid);
|
|
||||||
virtual void updateZoomSlider() {}
|
|
||||||
|
|
||||||
virtual void onInitDone();
|
|
||||||
virtual void emitPartitionTimeChanged(qint64 curTime) = 0;
|
|
||||||
|
|
||||||
virtual void onFileContentAvailable(const FileManagement::Database::FlmFileContent &) {}
|
|
||||||
protected:
|
|
||||||
QVector<SituationReplay::ReplayInformation> m_replayInformation;
|
|
||||||
QVector<SituationReplay::FilterInformation> m_filterInformation;
|
|
||||||
QVector<SituationReplay::FilterInformation> m_overlayInformation;
|
|
||||||
QJsonObject m_attributes;
|
|
||||||
QString m_scriptPath; // sitmap.json
|
|
||||||
double m_speedVal = 1;
|
|
||||||
State m_state = State::PS_STOP;
|
|
||||||
QTimer *m_playTimer = nullptr;
|
|
||||||
SituationReplay::MainHandlerSqlite *m_replayHandler = nullptr;
|
|
||||||
|
|
||||||
QString m_currentTimeDTGString;
|
|
||||||
qint64 m_sliderMoveTime = 0;
|
|
||||||
|
|
||||||
Ui::SituationBuildingBase *m_ui;
|
|
||||||
NGL::INGLLogger &m_logger;
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
-234
@@ -1,234 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>SituationBuildingBase</class>
|
|
||||||
<widget class="QFrame" name="SituationBuildingBase">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>911</width>
|
|
||||||
<height>563</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">Form</string>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::Panel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Sunken</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<layout class="QVBoxLayout" name="vLayout">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="THP::ZoomSlider" name="zoomSlider" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSlider" name="sldPosition">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblPosition">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">--:-- / --:--</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnPlay">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/media-playback-start.png</normaloff>:icons/16x16/media-playback-start.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnStop">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/media-playback-stop.png</normaloff>:icons/16x16/media-playback-stop.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnSlower">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/media-play-slower.png</normaloff>:icons/16x16/media-play-slower.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btn100pct">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/media-play-normal.png</normaloff>:icons/16x16/media-play-normal.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnFaster">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
<property name="icon">
|
|
||||||
<iconset>
|
|
||||||
<normaloff>:icons/16x16/media-play-faster.png</normaloff>:icons/16x16/media-play-faster.png</iconset>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblSpeed">
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Sunken</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">100 %</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer_3">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeType">
|
|
||||||
<enum>QSizePolicy::Fixed</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>5</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="cbPlaybackParts">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>100</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QComboBox::AdjustToContents</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblCursorPos">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">MGRS</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="btnFilter">
|
|
||||||
<property name="text">
|
|
||||||
<string>Filter</string>
|
|
||||||
</property>
|
|
||||||
<property name="popupMode">
|
|
||||||
<enum>QToolButton::InstantPopup</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>THP::ZoomSlider</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>thpwidgets/thp_zoom_slider.h</header>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* AES filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_filter_aes.h"
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
|
||||||
#include <FilterManagement/Gui/Aes/flt_aes_filter_widget.h>
|
|
||||||
#include <ProjectDataManagement/Gui/PdmComboBox/pdm_combobox_foreign_gui_interface_impl.h>
|
|
||||||
#include <ParticipantManagement/Gui/PpmComboBox/ppm_combobox_foreign_gui_interface_impl.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
SituatationFilterAes::SituatationFilterAes(const std::shared_ptr<FilterManagement::AesDisplayFilter> &aesFilter,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent)
|
|
||||||
: QDialog(parent)
|
|
||||||
, m_filterWidget(new FilterManagement::AesFilterWidget(this))
|
|
||||||
{
|
|
||||||
setWindowTitle(tr("Area Effect Simulation filter settings"));
|
|
||||||
QGridLayout *gl = new QGridLayout(this);
|
|
||||||
m_filterWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
gl->addWidget(m_filterWidget, 0, 0);
|
|
||||||
QFrame *line = new QFrame(this);
|
|
||||||
line->setFrameShape(QFrame::HLine);
|
|
||||||
line->setFrameShadow(QFrame::Sunken);
|
|
||||||
gl->addWidget(line, 1, 0);
|
|
||||||
QDialogButtonBox *bb = new QDialogButtonBox(this);
|
|
||||||
gl->addWidget(bb, 2, 0);
|
|
||||||
|
|
||||||
|
|
||||||
bb->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Close | QDialogButtonBox::Cancel);
|
|
||||||
connect(bb->button(QDialogButtonBox::Apply), &QPushButton::clicked,
|
|
||||||
m_filterWidget, &FilterManagement::AesFilterWidget::apply);
|
|
||||||
connect(bb->button(QDialogButtonBox::Close), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterAes::accept);
|
|
||||||
connect(bb->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterAes::reject);
|
|
||||||
|
|
||||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterfaceImpl>
|
|
||||||
ifcPpmCbx(std::make_shared<ParticipantManagement::ForeignGuiComboboxInterfaceImpl>());
|
|
||||||
ifcPpmCbx->init(pluginProvider->ppmDtc());
|
|
||||||
|
|
||||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterfaceImpl>
|
|
||||||
ifcPdmCbx(std::make_shared<ProjectDataManagement::ForeignGuiInterfaceImpl>());
|
|
||||||
ifcPdmCbx->init(pluginProvider->pdmDtc());
|
|
||||||
|
|
||||||
m_filterWidget->init(ifcPpmCbx, ifcPdmCbx, aesFilter);
|
|
||||||
// make sure to update ui when filter changes
|
|
||||||
connect(m_filterWidget, &FilterManagement::AesFilterWidget::unknownChangesRecognized,
|
|
||||||
m_filterWidget, &FilterManagement::AesFilterWidget::updateGuiToFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterAes::accept()
|
|
||||||
{
|
|
||||||
m_filterWidget->apply();
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterAes::reject()
|
|
||||||
{
|
|
||||||
m_filterWidget->dialogCanceled();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* AES filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class AesFilterWidget;
|
|
||||||
class AesDisplayFilter;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class SitMapPluginProvider;
|
|
||||||
class SituatationFilterAes final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituatationFilterAes(const std::shared_ptr<FilterManagement::AesDisplayFilter> &aesFilter,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void accept() override;
|
|
||||||
void reject() override;
|
|
||||||
private:
|
|
||||||
FilterManagement::AesFilterWidget *m_filterWidget;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-62
@@ -1,62 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Type filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_filter_building_components.h"
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
|
||||||
#include <FilterManagement/Gui/BuildingComponents/flt_building_component_settings_widget.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
SituationFilterBuildingComponent::SituationFilterBuildingComponent(const std::shared_ptr<FilterManagement::BuildingComponentSettings> &bcs,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent)
|
|
||||||
: QDialog(parent)
|
|
||||||
, m_filterWidget(new FilterManagement::BuildingComponentSettingsWidget(this))
|
|
||||||
{
|
|
||||||
setWindowTitle(tr("Building / Component filter settings"));
|
|
||||||
QGridLayout *gl = new QGridLayout(this);
|
|
||||||
m_filterWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
gl->addWidget(m_filterWidget, 0, 0);
|
|
||||||
QFrame *line = new QFrame(this);
|
|
||||||
line->setFrameShape(QFrame::HLine);
|
|
||||||
line->setFrameShadow(QFrame::Sunken);
|
|
||||||
gl->addWidget(line, 1, 0);
|
|
||||||
QDialogButtonBox *bb = new QDialogButtonBox(this);
|
|
||||||
gl->addWidget(bb, 2, 0);
|
|
||||||
|
|
||||||
|
|
||||||
bb->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Close | QDialogButtonBox::Cancel);
|
|
||||||
connect(bb->button(QDialogButtonBox::Apply), &QPushButton::clicked,
|
|
||||||
m_filterWidget, &FilterManagement::BuildingComponentSettingsWidget::apply);
|
|
||||||
connect(bb->button(QDialogButtonBox::Close), &QPushButton::clicked,
|
|
||||||
this, &SituationFilterBuildingComponent::accept);
|
|
||||||
connect(bb->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
|
|
||||||
this, &SituationFilterBuildingComponent::reject);
|
|
||||||
|
|
||||||
m_filterWidget->init(bcs, pluginProvider->ismDtc());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationFilterBuildingComponent::accept()
|
|
||||||
{
|
|
||||||
m_filterWidget->apply();
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationFilterBuildingComponent::reject()
|
|
||||||
{
|
|
||||||
m_filterWidget->dialogCanceled();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Type filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class BuildingComponentSettings;
|
|
||||||
class BuildingComponentSettingsWidget;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class SitMapPluginProvider;
|
|
||||||
class SituationFilterBuildingComponent final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituationFilterBuildingComponent(const std::shared_ptr<FilterManagement::BuildingComponentSettings> &bcs,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
protected:
|
|
||||||
void accept() override;
|
|
||||||
void reject() override;
|
|
||||||
private:
|
|
||||||
FilterManagement::BuildingComponentSettingsWidget *m_filterWidget{nullptr};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-77
@@ -1,77 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* AES filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_filter_collapse_expand.h"
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include <AdvancedSymbology/Data/asb_foreign_interface_impl.h>
|
|
||||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
|
||||||
#include <FilterManagement/Gui/Participant/flt_collapse_expand_participants_widget.h>
|
|
||||||
#include <ParticipantManagement/Gui/PpmComboBox/ppm_combobox_foreign_gui_interface_impl.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
SituatationFilterCollapseExpand::SituatationFilterCollapseExpand(const std::shared_ptr<FilterManagement::SymbolAppearanceSettings> &sas,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent)
|
|
||||||
: QDialog(parent)
|
|
||||||
, m_filterWidget(new FilterManagement::CollapseExpandParticipantWidget(this))
|
|
||||||
{
|
|
||||||
setWindowTitle(tr("Collapse/Expand Participant filter settings"));
|
|
||||||
QGridLayout *gl = new QGridLayout(this);
|
|
||||||
m_filterWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
gl->addWidget(m_filterWidget, 0, 0);
|
|
||||||
QFrame *line = new QFrame(this);
|
|
||||||
line->setFrameShape(QFrame::HLine);
|
|
||||||
line->setFrameShadow(QFrame::Sunken);
|
|
||||||
gl->addWidget(line, 1, 0);
|
|
||||||
QDialogButtonBox *bb = new QDialogButtonBox(this);
|
|
||||||
gl->addWidget(bb, 2, 0);
|
|
||||||
|
|
||||||
|
|
||||||
bb->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Close | QDialogButtonBox::Cancel);
|
|
||||||
connect(bb->button(QDialogButtonBox::Apply), &QPushButton::clicked,
|
|
||||||
m_filterWidget, &FilterManagement::CollapseExpandParticipantWidget::apply);
|
|
||||||
connect(bb->button(QDialogButtonBox::Close), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterCollapseExpand::accept);
|
|
||||||
connect(bb->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterCollapseExpand::reject);
|
|
||||||
|
|
||||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterfaceImpl>
|
|
||||||
ifcPpmCbx(std::make_shared<ParticipantManagement::ForeignGuiComboboxInterfaceImpl>());
|
|
||||||
ifcPpmCbx->init(pluginProvider->ppmDtc());
|
|
||||||
|
|
||||||
std::shared_ptr<AdvancedSymbology::ForeignInterfaceImpl>
|
|
||||||
ifcAsb(std::make_shared<AdvancedSymbology::ForeignInterfaceImpl>(pluginProvider->ppmDtc(),
|
|
||||||
pluginProvider->aesDtc(),
|
|
||||||
pluginProvider->gimDtc()));
|
|
||||||
|
|
||||||
m_filterWidget->init(pluginProvider->ppmDtc(),
|
|
||||||
ifcPpmCbx,
|
|
||||||
ifcAsb,
|
|
||||||
// pluginProvider->fltParticipantIfc(),
|
|
||||||
sas);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterCollapseExpand::accept()
|
|
||||||
{
|
|
||||||
m_filterWidget->apply();
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterCollapseExpand::reject()
|
|
||||||
{
|
|
||||||
m_filterWidget->dialogCanceled();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Collapse/Expand filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class CollapseExpandParticipantWidget;
|
|
||||||
class SymbolAppearanceSettings;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class SitMapPluginProvider;
|
|
||||||
class SituatationFilterCollapseExpand final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituatationFilterCollapseExpand(const std::shared_ptr<FilterManagement::SymbolAppearanceSettings> &sas,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
protected:
|
|
||||||
void accept() override;
|
|
||||||
void reject() override;
|
|
||||||
private:
|
|
||||||
FilterManagement::CollapseExpandParticipantWidget *m_filterWidget;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-63
@@ -1,63 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* AES filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_filter_symbol_appearance.h"
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include <ParticipantManagement/ppm_dtc.h>
|
|
||||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
|
||||||
#include <FilterManagement/Gui/Participant/flt_symbol_appearance_widget.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
SituatationFilterSymbolAppearance::SituatationFilterSymbolAppearance(const std::shared_ptr<FilterManagement::SymbolAppearanceSettings> &sas,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent)
|
|
||||||
: QDialog(parent)
|
|
||||||
, m_filterWidget(new FilterManagement::SymbolAppearanceWidget(this))
|
|
||||||
{
|
|
||||||
setWindowTitle(tr("Symbol Appearance filter settings"));
|
|
||||||
QGridLayout *gl = new QGridLayout(this);
|
|
||||||
m_filterWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
gl->addWidget(m_filterWidget, 0, 0);
|
|
||||||
QFrame *line = new QFrame(this);
|
|
||||||
line->setFrameShape(QFrame::HLine);
|
|
||||||
line->setFrameShadow(QFrame::Sunken);
|
|
||||||
gl->addWidget(line, 1, 0);
|
|
||||||
QDialogButtonBox *bb = new QDialogButtonBox(this);
|
|
||||||
gl->addWidget(bb, 2, 0);
|
|
||||||
|
|
||||||
|
|
||||||
bb->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Close | QDialogButtonBox::Cancel);
|
|
||||||
connect(bb->button(QDialogButtonBox::Apply), &QPushButton::clicked,
|
|
||||||
m_filterWidget, &FilterManagement::SymbolAppearanceWidget::apply);
|
|
||||||
connect(bb->button(QDialogButtonBox::Close), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterSymbolAppearance::accept);
|
|
||||||
connect(bb->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterSymbolAppearance::reject);
|
|
||||||
|
|
||||||
m_filterWidget->init(pluginProvider->ppmDtc()->partys(), sas);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterSymbolAppearance::accept()
|
|
||||||
{
|
|
||||||
m_filterWidget->apply();
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterSymbolAppearance::reject()
|
|
||||||
{
|
|
||||||
m_filterWidget->dialogCanceled();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Symbol Appearance filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class SymbolAppearanceSettings;
|
|
||||||
class SymbolAppearanceWidget;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class SitMapPluginProvider;
|
|
||||||
class SituatationFilterSymbolAppearance final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituatationFilterSymbolAppearance(const std::shared_ptr<FilterManagement::SymbolAppearanceSettings> &sas,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
protected:
|
|
||||||
void accept() override;
|
|
||||||
void reject() override;
|
|
||||||
private:
|
|
||||||
FilterManagement::SymbolAppearanceWidget *m_filterWidget;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-69
@@ -1,69 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Type filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_filter_types.h"
|
|
||||||
|
|
||||||
#include <QDialogButtonBox>
|
|
||||||
#include <QFrame>
|
|
||||||
#include <QGridLayout>
|
|
||||||
#include <QPushButton>
|
|
||||||
|
|
||||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
|
||||||
#include <FilterManagement/Gui/Participant/flt_type_filter_widget.h>
|
|
||||||
#include <ParticipantManagement/Gui/PpmComboBox/ppm_combobox_foreign_gui_interface_impl.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
SituatationFilterTypes::SituatationFilterTypes(const std::shared_ptr<FilterManagement::SymbolAppearanceSettings> &sas,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent)
|
|
||||||
: QDialog(parent)
|
|
||||||
, m_filterWidget(new FilterManagement::TypeFilterWidget(this))
|
|
||||||
{
|
|
||||||
setWindowTitle(tr("Type filter settings"));
|
|
||||||
QGridLayout *gl = new QGridLayout(this);
|
|
||||||
m_filterWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
gl->addWidget(m_filterWidget, 0, 0);
|
|
||||||
QFrame *line = new QFrame(this);
|
|
||||||
line->setFrameShape(QFrame::HLine);
|
|
||||||
line->setFrameShadow(QFrame::Sunken);
|
|
||||||
gl->addWidget(line, 1, 0);
|
|
||||||
QDialogButtonBox *bb = new QDialogButtonBox(this);
|
|
||||||
gl->addWidget(bb, 2, 0);
|
|
||||||
|
|
||||||
|
|
||||||
bb->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Close | QDialogButtonBox::Cancel);
|
|
||||||
connect(bb->button(QDialogButtonBox::Apply), &QPushButton::clicked,
|
|
||||||
m_filterWidget, &FilterManagement::TypeFilterWidget::apply);
|
|
||||||
connect(bb->button(QDialogButtonBox::Close), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterTypes::accept);
|
|
||||||
connect(bb->button(QDialogButtonBox::Cancel), &QPushButton::clicked,
|
|
||||||
this, &SituatationFilterTypes::reject);
|
|
||||||
|
|
||||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterfaceImpl>
|
|
||||||
ifcPpmCbx(std::make_shared<ParticipantManagement::ForeignGuiComboboxInterfaceImpl>());
|
|
||||||
ifcPpmCbx->init(pluginProvider->ppmDtc());
|
|
||||||
|
|
||||||
m_filterWidget->init(pluginProvider->ppmDtc(),
|
|
||||||
ifcPpmCbx,
|
|
||||||
sas);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterTypes::accept()
|
|
||||||
{
|
|
||||||
m_filterWidget->apply();
|
|
||||||
QDialog::accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituatationFilterTypes::reject()
|
|
||||||
{
|
|
||||||
m_filterWidget->dialogCanceled();
|
|
||||||
QDialog::reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Type filter dialog for situation map/thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class SymbolAppearanceSettings;
|
|
||||||
class TypeFilterWidget;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class SitMapPluginProvider;
|
|
||||||
class SituatationFilterTypes final : public QDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituatationFilterTypes(const std::shared_ptr<FilterManagement::SymbolAppearanceSettings> &sas,
|
|
||||||
SitMapPluginProvider *pluginProvider,
|
|
||||||
QWidget *parent = nullptr);
|
|
||||||
protected:
|
|
||||||
void accept() override;
|
|
||||||
void reject() override;
|
|
||||||
private:
|
|
||||||
FilterManagement::TypeFilterWidget *m_filterWidget;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-651
@@ -1,651 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle situation display in thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_situation_widget.h"
|
|
||||||
#include <utility>
|
|
||||||
#include "ui_thp_situation_building_base.h"
|
|
||||||
|
|
||||||
#include "thp_situation_filter_aes.h"
|
|
||||||
#include "thp_situation_filter_symbol_appearance.h"
|
|
||||||
#include "thp_situation_filter_collapse_expand.h"
|
|
||||||
#include "thp_situation_filter_types.h"
|
|
||||||
#include "thp_situation_filter_building_components.h"
|
|
||||||
#include "thp_plugin_provider.h"
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFileInfo>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QJsonParseError>
|
|
||||||
#include <QKeyEvent>
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QSvgRenderer>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QThread>
|
|
||||||
#include <FileManagement/flm_db_structs.h>
|
|
||||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
|
||||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
|
||||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
|
||||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
|
||||||
#include <FilterManagement/Gui/Aes/Common/aes_display_filter_impl.h>
|
|
||||||
#include <FilterManagement/Gui/Aes/Common/symbol_appearance_settings_impl.h>
|
|
||||||
|
|
||||||
#include <SituationReplay/handler_situation_replay_sqlite.h>
|
|
||||||
|
|
||||||
#include <SituationMap/situation_map_init.h>
|
|
||||||
#include <SituationMap/Utils/movement_track_manager.h>
|
|
||||||
#include <SituationMap/Map/grid.h>
|
|
||||||
#include <SituationMap/Map/point3D.h>
|
|
||||||
#include <SituationMap/Map/map_initializer.h>
|
|
||||||
#include <SituationMap/Map/map_notifier.h>
|
|
||||||
#include <SituationMap/Map/operator_map_settings.h>
|
|
||||||
#include <SituationMap/Map/overlay_handler.h>
|
|
||||||
#include <SituationMap/Symbology/sidc_codec.h>
|
|
||||||
#include <PlanOverlays/Gui/plan_overlay_model.h>
|
|
||||||
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include <ngltools/ngltools_dtg.h>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
class MySitMapIinit final : public SituationMap::SituationMapInit
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
using SituationMap::SituationMapInit::SituationMapInit;
|
|
||||||
|
|
||||||
bool trainingAreaExists() const override { return true; }
|
|
||||||
SituationMap::MapSettingsJson getMapSettingsFromService() const override { return m_mapSettingsJson; }
|
|
||||||
void setMapSettingsJson(const SituationMap::MapSettingsJson &settings) { m_mapSettingsJson = settings; }
|
|
||||||
const SituationMap::MapSettingsJson & getMapSettingsJson() const { return m_mapSettingsJson; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
SituationMap::MapSettingsJson m_mapSettingsJson;
|
|
||||||
};
|
|
||||||
|
|
||||||
using namespace SituationReplay;
|
|
||||||
|
|
||||||
SituationWidget::SituationWidget(QWidget *parent)
|
|
||||||
: SituationBuildingBase("THP.SituationWidget", parent)
|
|
||||||
, m_pluginProvider(new SitMapPluginProvider)
|
|
||||||
, m_situationMapInit(new MySitMapIinit(nullptr))
|
|
||||||
{
|
|
||||||
QMenu *m = new QMenu(m_ui->btnFilter);
|
|
||||||
m->addAction(tr("AES Filter"), this, &SituationWidget::onFilterAes);
|
|
||||||
// 29.09.2022, Norbert Thoden
|
|
||||||
// SWPÄ 2:22 GUEZE-1477 Kartenfilter für Komponenten:
|
|
||||||
// Es wurde der Komponenten Filter eingeführt.
|
|
||||||
// in der LiveLage werden allerdings nur MountingPoints angezeigt, die auch eine
|
|
||||||
// zugeordnetes Asset haben. Die Zuordnug befindet sich in der Tabelle ism.sim_mounting_point_asset.
|
|
||||||
// ism.sim_mounting_point_asset wird derzeit nicht in die sitreplay.sqlite
|
|
||||||
// überführt. Es koennen also keine Komponenten angezeigt / gefiltert werden...
|
|
||||||
// FilterDialog nicht anzeigen:
|
|
||||||
// m->addAction(tr("Building / Component"), this, &SituationWidget::onFilterBuildingComponent);
|
|
||||||
|
|
||||||
m->addAction(tr("Symbol Appearance"), this, &SituationWidget::onFilterSymbolAppearance);
|
|
||||||
m->addAction(tr("Collpase/Expand"), this, &SituationWidget::onFilterCollapseExpand);
|
|
||||||
m->addAction(tr("Type filter"), this, &SituationWidget::onFilterTypes);
|
|
||||||
m_ui->btnFilter->setMenu(m);
|
|
||||||
}
|
|
||||||
|
|
||||||
SituationWidget::~SituationWidget()
|
|
||||||
{
|
|
||||||
if (m_replayHandler->handlerSrp())
|
|
||||||
m_replayHandler->handlerSrp()->onStopReplayRequest();
|
|
||||||
delete m_situationMapInit;
|
|
||||||
delete m_pluginProvider;
|
|
||||||
delete m_replayHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationWidget::init(const QString &homePath, int exerciseId)
|
|
||||||
{
|
|
||||||
m_pluginProvider->setExerciseId(exerciseId);
|
|
||||||
delete m_replayHandler;
|
|
||||||
m_replayHandler = new SituationReplay::MainHandlerSqlite;
|
|
||||||
|
|
||||||
if (!SituationBuildingBase::init(m_replayHandler))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
loadLayerMappings(homePath);
|
|
||||||
|
|
||||||
SituationReplay::ConnectionParams connParams;
|
|
||||||
connParams.domainId = 1;
|
|
||||||
connParams.partitionId = 1;
|
|
||||||
if (!m_replayHandler->initDds(connParams))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!m_pluginProvider->init(m_replayHandler->ddsReplay()))
|
|
||||||
return false;
|
|
||||||
if (!m_situationMapInit->initPluginProvider(m_pluginProvider))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QPointer<SituationMap::MovementTrackManager> movementTrackMgr =
|
|
||||||
QPointer<SituationMap::MovementTrackManager>(new SituationMap::MovementTrackManager(m_situationMapInit));
|
|
||||||
|
|
||||||
FATAL_LOG(m_logger) << LOGFUNCTION << " XXXX initMap....";
|
|
||||||
|
|
||||||
if (!m_situationMapInit->initMap(false, SituationMap::Mode::Mode_2D))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!m_situationMapInit->initAdapter(movementTrackMgr, false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SituationMap::Map *map = m_situationMapInit->getWidget();
|
|
||||||
if (!map)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
connect(map, &SituationMap::Map::mouseGeoPositionChanged,
|
|
||||||
this, &SituationWidget::updatePositionLabel,
|
|
||||||
Qt::UniqueConnection);
|
|
||||||
connect(map, &SituationMap::Map::extentChanged,
|
|
||||||
this, &SituationWidget::updateZoomSlider);
|
|
||||||
|
|
||||||
map->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
m_ui->vLayout->insertWidget(0, map);
|
|
||||||
|
|
||||||
m_aesDisplayFilter = m_pluginProvider->fltAesIfc()->aesFilterForOperator(0, QString());
|
|
||||||
m_symbolAppaearanceSettings = m_pluginProvider->fltParticipantIfc()->symbolAppearanceForOperator(0, QString());
|
|
||||||
m_buildingComponentSettings = m_pluginProvider->fltBuildingComponentIfc()->buildingComponentSettingsForOperator(0, QString());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationWidget::showSituationInternal()
|
|
||||||
{
|
|
||||||
// cleanup 'old' map:
|
|
||||||
// remove old overlays from former session:
|
|
||||||
{
|
|
||||||
SituationMap::Map *map = m_situationMapInit->getWidget();
|
|
||||||
if (map)
|
|
||||||
map->overlayHandler().removeAllOverlays();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
m_ui->cbPlaybackParts->setVisible(m_replayInformation.size() > 1);
|
|
||||||
|
|
||||||
// MAYBE there are filter to be applied:
|
|
||||||
applyFilterFromReplayConfigFile();
|
|
||||||
|
|
||||||
if (m_replayInformation.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "No replay information given...";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString sqliteDb = m_replayInformation.first().databaseFilePath;
|
|
||||||
if (sqliteDb.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "No database given...";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
QFileInfo fi(sqliteDb);
|
|
||||||
if (!fi.exists() || !fi.isFile() || !fi.isReadable())
|
|
||||||
{
|
|
||||||
Q_ASSERT(false);
|
|
||||||
WARNING_LOG(m_logger) << "Can not access sqlite database '" << fi.absoluteFilePath() << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ui->cbPlaybackParts->clear();
|
|
||||||
m_ui->cbPlaybackParts->blockSignals(true);
|
|
||||||
for (int i = 0; i < m_replayInformation.size(); ++i)
|
|
||||||
{
|
|
||||||
const ReplayInformation &info = m_replayInformation.at(i);
|
|
||||||
m_ui->cbPlaybackParts->addItem(QStringLiteral("%1: %2 - %3").arg(i+1).arg(DTG::toStringMSec(info.timeSpan.begin, DTG::Long),
|
|
||||||
DTG::toStringMSec(info.timeSpan.end, DTG::Long)), i);
|
|
||||||
}
|
|
||||||
m_ui->cbPlaybackParts->setCurrentIndex(0);
|
|
||||||
m_ui->cbPlaybackParts->blockSignals(false);
|
|
||||||
onCbPlaybackPartsChanged(); // creates replayHandler for correct db etc.
|
|
||||||
|
|
||||||
SituationMap::Map *map = m_situationMapInit->getWidget();
|
|
||||||
if (map->isReady())
|
|
||||||
QTimer::singleShot(0, this, &SituationWidget::onInitDone);
|
|
||||||
else
|
|
||||||
connect(map, &SituationMap::Map::mapReady,
|
|
||||||
this, &SituationWidget::onInitDone, Qt::QueuedConnection);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationWidget::applyFilterFromReplayConfigFile()
|
|
||||||
{
|
|
||||||
// Maybe the Situation topic has own Filter (AesFilter, SymbolAppearance; OperatorMapSettings)
|
|
||||||
// Read and apply them:
|
|
||||||
if (m_replayInformation.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "No replay information given...";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString replayConfigFile = m_replayInformation.first().replayConfigPath; // sitreplay.json
|
|
||||||
if (replayConfigFile.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "No replayConfigFile given...";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFileInfo fi(replayConfigFile);
|
|
||||||
if (!fi.exists() || !fi.isFile() || !fi.isReadable())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not access replayConfigFile '" << fi.absoluteFilePath() << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile f(replayConfigFile);
|
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not open replayConfigFile '" << fi.absoluteFilePath() << "': " << f.errorString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonParseError jError;
|
|
||||||
const QByteArray ba = f.readAll();
|
|
||||||
QJsonDocument doc(QJsonDocument::fromJson(ba, &jError));
|
|
||||||
if (jError.error)
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not parse json document: "
|
|
||||||
<< ", replayConfigFile '" << fi.absoluteFilePath() << "'"
|
|
||||||
<< ", errorString= " << jError.errorString();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QJsonObject &rootObj = doc.object();
|
|
||||||
const QJsonObject &filters = rootObj[QStringLiteral("filters")].toObject(); // optional!!!
|
|
||||||
|
|
||||||
if (filters.isEmpty())
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "no 'filters' provided at "
|
|
||||||
<< " replayConfigFile '" << fi.absoluteFilePath() << "'";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " XXXX replayConfigFile='" << fi.absoluteFilePath() << "'"
|
|
||||||
<< " doc.toJson = " << doc.toJson();
|
|
||||||
|
|
||||||
// fine, put together
|
|
||||||
FilterInformation filterInfo;
|
|
||||||
filterInfo.aesFilters = filters[QStringLiteral("AesFilterJson")].toObject();
|
|
||||||
filterInfo.symbolSettings = filters[QStringLiteral("SymbolAppearanceJson")].toObject();
|
|
||||||
filterInfo.buildingComponentSettings = filters[QStringLiteral("BuildingComponentSettingsJson")].toObject();
|
|
||||||
|
|
||||||
filterInfo.mapSettings = rootObj[QStringLiteral("settings")].toObject();
|
|
||||||
|
|
||||||
applyCurentFilter(filterInfo);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::applyCurentFilter(const SituationReplay::FilterInformation &filter)
|
|
||||||
{
|
|
||||||
m_aesDisplayFilter->setFilterFromData(filter.aesFilters);
|
|
||||||
m_symbolAppaearanceSettings->setSettings(filter.symbolSettings, FilterManagement::SymbolAppearanceSettings::Part::All);
|
|
||||||
m_buildingComponentSettings->setBldCmpSettings(filter.buildingComponentSettings);
|
|
||||||
|
|
||||||
SituationMap::OperatorMapSettings oms;
|
|
||||||
oms.fromJsonObject(filter.mapSettings);
|
|
||||||
if (oms.isEmpty() || oms.mode == SituationMap::Mode::Undefined)
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
if (oms.mode != m_situationMapInit->getWidget()->mode())
|
|
||||||
{
|
|
||||||
INFO_LOG(m_logger) << " Switching to new mode : " << oms.mode;
|
|
||||||
|
|
||||||
SituationMap::MapSettingsJson savedMapSettingsJson;
|
|
||||||
if (m_situationMapInit)
|
|
||||||
{
|
|
||||||
savedMapSettingsJson = m_situationMapInit->getMapSettingsJson(); // containing path from layerMappping.json
|
|
||||||
m_situationMapInit->stopDisplay();
|
|
||||||
m_situationMapInit->clearObjects();
|
|
||||||
}
|
|
||||||
delete m_situationMapInit;
|
|
||||||
m_situationMapInit = new MySitMapIinit(nullptr);
|
|
||||||
m_situationMapInit->setMapSettingsJson(savedMapSettingsJson);
|
|
||||||
m_situationMapInit->initPluginProvider(m_pluginProvider);
|
|
||||||
|
|
||||||
m_situationMapInit->initMap(false, oms.mode);
|
|
||||||
|
|
||||||
QPointer<SituationMap::MovementTrackManager> movementTrackMgr =
|
|
||||||
QPointer<SituationMap::MovementTrackManager>(new SituationMap::MovementTrackManager(m_situationMapInit));
|
|
||||||
if (!m_situationMapInit->initAdapter(movementTrackMgr, false))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SituationMap::Map *map = m_situationMapInit->getWidget();
|
|
||||||
if (map)
|
|
||||||
{
|
|
||||||
connect(map, &SituationMap::Map::mouseGeoPositionChanged,
|
|
||||||
this, &SituationWidget::updatePositionLabel,
|
|
||||||
Qt::UniqueConnection);
|
|
||||||
connect(map, &SituationMap::Map::extentChanged,
|
|
||||||
this, &SituationWidget::updateZoomSlider);
|
|
||||||
|
|
||||||
map->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
||||||
m_ui->vLayout->insertWidget(0, map);
|
|
||||||
|
|
||||||
|
|
||||||
static bool s_waitFlag = true;
|
|
||||||
|
|
||||||
QPointer<SituationMap::MapNotifier> mapNotifier = map->createMapNotifier();
|
|
||||||
if (mapNotifier)
|
|
||||||
{
|
|
||||||
connect(mapNotifier.data(), &SituationMap::MapNotifier::mapReadyAndSymbolDictionaryLoaded, this, [this, oms]()
|
|
||||||
{
|
|
||||||
s_waitFlag = false;
|
|
||||||
if (!restoreOperatorMapSettingsOverlays(oms))
|
|
||||||
WARNING_LOG(m_logger) << "restoreOperatorMapSettingsOverlays failed";
|
|
||||||
|
|
||||||
});
|
|
||||||
mapNotifier->run();
|
|
||||||
|
|
||||||
// snyc wait :-(
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << " WAIT_SYNC BEGIN";
|
|
||||||
int i=0;
|
|
||||||
while(i<100 && s_waitFlag) // 100 * 50ms = 5000ms
|
|
||||||
{
|
|
||||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents|QEventLoop::ExcludeSocketNotifiers, 50);
|
|
||||||
QThread::msleep(50);
|
|
||||||
++i;
|
|
||||||
DEBUG_LOG(m_logger) << " WAIT_SYNC ..., i=" << i;
|
|
||||||
}
|
|
||||||
DEBUG_LOG(m_logger) << " WAIT_SYNC ...DONE, i=" << i;
|
|
||||||
DEBUG_LOG(m_logger) << " WAIT_SYNC, m_situationMapInit->getWidget()->mode()" << m_situationMapInit->getWidget()->mode();
|
|
||||||
m_situationMapInit->startDisplay();
|
|
||||||
}
|
|
||||||
} // if (mapNotifier)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!restoreOperatorMapSettingsOverlays(oms))
|
|
||||||
WARNING_LOG(m_logger) << "restoreOperatorMapSettingsOverlays failed";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SituationWidget::restoreOperatorMapSettingsOverlays(const SituationMap::OperatorMapSettings &oms)
|
|
||||||
{
|
|
||||||
if (!m_situationMapInit || !m_situationMapInit->getWidget() || oms.isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!m_situationMapInit->getWidget()->restoreOperatorMapSettings(oms))
|
|
||||||
WARNING_LOG(m_logger) << LOGFUNCTION << " restoreOperatorMapSettings failed";
|
|
||||||
|
|
||||||
// continue!!! maybe just LayerOrder failed.... ToDo
|
|
||||||
|
|
||||||
// 2. handle Overlays :
|
|
||||||
// SituationMap can`t restore the overlays on it´s own:
|
|
||||||
// So we have to do it here:
|
|
||||||
const QList<int> &orderedOverlayIds = oms.orderedOverlays;
|
|
||||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " restore OverlayIds...";
|
|
||||||
for (auto overlayId : std::as_const(orderedOverlayIds))
|
|
||||||
{
|
|
||||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " applyNewOverlay , overlayId=" << overlayId;
|
|
||||||
applyNewOverlay(overlayId);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::applyNewOverlay(int overlayId)
|
|
||||||
{
|
|
||||||
const QString filename = QStringLiteral("%1/%2.TacticalPlan").arg(m_scriptPath).arg(overlayId);
|
|
||||||
QFile f(filename);
|
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Can not open tactical plan '" << filename << "': " << f.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
SituationMap::OverlayHandler &overlayHandler = m_situationMapInit->getWidget()->overlayHandler();
|
|
||||||
if (!overlayHandler.setOverlay(overlayId, tr("Plan '%1'").arg(overlayId), f.readAll(), false))
|
|
||||||
WARNING_LOG(m_logger) << "can not display overlay " << filename;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::removeOverlay(int overlayId)
|
|
||||||
{
|
|
||||||
SituationMap::OverlayHandler &overlayHandler = m_situationMapInit->getWidget()->overlayHandler();
|
|
||||||
overlayHandler.removeOverlay(overlayId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onFilterAes()
|
|
||||||
{
|
|
||||||
if (!m_filterAesDialog)
|
|
||||||
m_filterAesDialog = new SituatationFilterAes(m_aesDisplayFilter,
|
|
||||||
m_pluginProvider, this);
|
|
||||||
m_filterAesDialog->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onFilterSymbolAppearance()
|
|
||||||
{
|
|
||||||
if (!m_filterSymbolAppearanceDialog)
|
|
||||||
m_filterSymbolAppearanceDialog = new SituatationFilterSymbolAppearance(m_symbolAppaearanceSettings,
|
|
||||||
m_pluginProvider, this);
|
|
||||||
m_filterSymbolAppearanceDialog->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onFilterCollapseExpand()
|
|
||||||
{
|
|
||||||
if (!m_filterCollapseExpandDialog)
|
|
||||||
m_filterCollapseExpandDialog = new SituatationFilterCollapseExpand(m_symbolAppaearanceSettings,
|
|
||||||
m_pluginProvider, this);
|
|
||||||
m_filterCollapseExpandDialog->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onFilterTypes()
|
|
||||||
{
|
|
||||||
if (!m_filterTypesDialog)
|
|
||||||
m_filterTypesDialog = new SituatationFilterTypes(m_symbolAppaearanceSettings,
|
|
||||||
m_pluginProvider, this);
|
|
||||||
m_filterTypesDialog->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onFilterBuildingComponent()
|
|
||||||
{
|
|
||||||
if (!m_filterBuildingComponentDialog)
|
|
||||||
m_filterBuildingComponentDialog = new SituationFilterBuildingComponent(m_buildingComponentSettings,
|
|
||||||
m_pluginProvider, this);
|
|
||||||
m_filterBuildingComponentDialog->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::emitPartitionTimeChanged(qint64 curTime)
|
|
||||||
{
|
|
||||||
m_pluginProvider->emitPartitionTimeChanged(curTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::updateZoomSlider()
|
|
||||||
{
|
|
||||||
// this is not really what we want to display... but currently we hide the slider anyway
|
|
||||||
m_ui->zoomSlider->setZoomValue(m_situationMapInit->getWidget()->scale() / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString SituationWidget::centerPointString() const
|
|
||||||
{
|
|
||||||
const QPointF center = m_situationMapInit->getWidget()->centerPoint();
|
|
||||||
LtsCoordTrans::UtmCoordinate coord(LtsCoordTrans::UtmCoordinate::fromGeographic(center.x(), center.y()));
|
|
||||||
return coord.mgrs();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF SituationWidget::extentMgrs() const
|
|
||||||
{
|
|
||||||
const QRectF r = m_situationMapInit->getWidget()->extent();
|
|
||||||
LtsCoordTrans::UtmCoordinate topLeft(LtsCoordTrans::UtmCoordinate::fromGeographic(r.left(), r.top()));
|
|
||||||
LtsCoordTrans::UtmCoordinate bottomRight(LtsCoordTrans::UtmCoordinate::fromGeographic(r.right(), r.bottom(), topLeft.zone));
|
|
||||||
return QRectF(QPointF(topLeft.x, topLeft.y), QPointF(bottomRight.x, bottomRight.y));
|
|
||||||
}
|
|
||||||
|
|
||||||
QImage SituationWidget::grabFrameBuffer() const
|
|
||||||
{
|
|
||||||
return m_situationMapInit->getWidget()->grab().toImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onInitDone()
|
|
||||||
{
|
|
||||||
SituationBuildingBase::onInitDone();
|
|
||||||
m_situationMapInit->startDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::keyPressEvent(QKeyEvent *event)
|
|
||||||
{
|
|
||||||
switch (event->key())
|
|
||||||
{
|
|
||||||
case Qt::Key_F10:
|
|
||||||
onMgrsGrid();
|
|
||||||
break;
|
|
||||||
case Qt::Key_PageUp:
|
|
||||||
onRotate(10);
|
|
||||||
break;
|
|
||||||
case Qt::Key_PageDown:
|
|
||||||
onRotate(-10);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
QFrame::keyPressEvent(event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onMgrsGrid()
|
|
||||||
{
|
|
||||||
SituationMap::Map *m = m_situationMapInit->getWidget();
|
|
||||||
m->grid().setVisible(!m->grid().isVisible());
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onRotate(int degrees)
|
|
||||||
{
|
|
||||||
SituationMap::Map *m = m_situationMapInit->getWidget();
|
|
||||||
m->setRotation(m->rotation() + degrees);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::onFileContentAvailable(const FileManagement::Database::FlmFileContent &data)
|
|
||||||
{
|
|
||||||
if (data.fileTypeId != FileManagement::FileType::OperatorDefinedSymbol ||
|
|
||||||
data.fileStatusId != FileManagement::FileStatus::Valid ||
|
|
||||||
data.content.size() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QColor colorToBeReplaced;
|
|
||||||
bool bIsXml = false;
|
|
||||||
|
|
||||||
if (!data.properties.isEmpty())
|
|
||||||
{
|
|
||||||
QJsonParseError parseError;
|
|
||||||
const QJsonDocument jDoc(QJsonDocument::fromJson(data.properties.toUtf8(), &parseError));
|
|
||||||
const QJsonObject obj(jDoc.object());
|
|
||||||
const QLatin1String imageFormatKey("imageFormat");
|
|
||||||
bIsXml = obj.value(imageFormatKey).toString() == QLatin1String("xml");
|
|
||||||
if (!bIsXml)
|
|
||||||
{
|
|
||||||
// partyColor
|
|
||||||
const QLatin1String partyColorStr("partyColor");
|
|
||||||
if (obj.contains(partyColorStr))
|
|
||||||
{
|
|
||||||
const QJsonObject partyColor = obj[partyColorStr].toObject();
|
|
||||||
if (partyColor.size() == 3) // r, g, b
|
|
||||||
{
|
|
||||||
// update map:
|
|
||||||
colorToBeReplaced.setRgb(
|
|
||||||
partyColor[QLatin1String("r")].toInt(),
|
|
||||||
partyColor[QLatin1String("g")].toInt(),
|
|
||||||
partyColor[QLatin1String("b")].toInt());
|
|
||||||
} // if (partyColor.size() == 3)
|
|
||||||
} // if (obj.contains(partyColorStr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AdvancedSymbology::SymbologyType symType = AdvancedSymbology::SymbolDictionary::defaultSymbologyType();
|
|
||||||
AdvancedSymbology::SymbolDictionary &dict =
|
|
||||||
AdvancedSymbology::SymbolDictionary::dictionary(symType);
|
|
||||||
if (bIsXml)
|
|
||||||
{
|
|
||||||
dict.setXmlSymbol(data.id, data.name, QStringLiteral("OperatorName"), 0, QString::fromUtf8(data.content), AdvancedSymbology::SymbolProperties());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QImage image;
|
|
||||||
QSvgRenderer svgRenderer;
|
|
||||||
if (!svgRenderer.load(data.content))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// prepare Image:
|
|
||||||
constexpr int size = 200; // pixel
|
|
||||||
QImage imageOut(size, size, QImage::Format_ARGB32);
|
|
||||||
imageOut.fill(Qt::transparent);
|
|
||||||
|
|
||||||
// render
|
|
||||||
QPainter painter(&imageOut);
|
|
||||||
svgRenderer.render(&painter);
|
|
||||||
painter.end();
|
|
||||||
|
|
||||||
AdvancedSymbology::SymbolProperties symProps;
|
|
||||||
symProps.setKey(data.name);
|
|
||||||
symProps.setSidc(AdvancedSymbology::SidcCodec::encodeCivilEts(data.name));
|
|
||||||
symProps.setName(data.name);
|
|
||||||
symProps.setSymbolClass(QLatin1String("3")); // 18.10.2016, N.Thoden: 3 == PointSymbol (mil2525d.stylx - QuartzRelease)
|
|
||||||
symProps.setGeometryType(AdvancedSymbology::GeometryType::Point); // ETS-Symbols are always Points
|
|
||||||
symProps.setTags({data.name});
|
|
||||||
symProps.setColorToBeReplaced(colorToBeReplaced);
|
|
||||||
|
|
||||||
dict.setEtsSymbol(data.id, data.name, symProps, image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SituationWidget::loadLayerMappings(const QString &homePath)
|
|
||||||
{
|
|
||||||
const QString mappingsFile = homePath + QStringLiteral("/layerMapping.json");
|
|
||||||
|
|
||||||
QFile f(mappingsFile);
|
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Could not load layer mappings from '%s' - %s\n", mappingsFile.toStdString().c_str(), f.errorString().toStdString().c_str());
|
|
||||||
WARNING_LOG(m_logger) << "Could not load layer mappings from " << mappingsFile << ": " << f.errorString();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_layerMapping.clear();
|
|
||||||
const QJsonObject obj = QJsonDocument::fromJson(f.readAll()).object();
|
|
||||||
|
|
||||||
SituationMap::MapSettingsJson settings;
|
|
||||||
if (!settings.fromJsonObject(obj))
|
|
||||||
{
|
|
||||||
WARNING_LOG(m_logger) << "Could not parse layer mappings from " << mappingsFile;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.setMapUrls(fixupUrls(settings.getMapUrls(), homePath));
|
|
||||||
settings.setSceneUrls(fixupUrls(settings.getSceneUrls(), homePath));
|
|
||||||
settings.setSceneObjectUrls(fixupUrls(settings.getSceneObjectUrls(), homePath));
|
|
||||||
settings.setElevationUrls(fixupUrls(settings.getElevationUrls(), homePath));
|
|
||||||
|
|
||||||
m_situationMapInit->setMapSettingsJson(settings);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<SituationMap::BaseUrl> SituationWidget::fixupUrls(const QVector<SituationMap::BaseUrl> &in,
|
|
||||||
const QString &homePath)
|
|
||||||
{
|
|
||||||
QVector<SituationMap::BaseUrl> out;
|
|
||||||
for (auto url : in)
|
|
||||||
{
|
|
||||||
const QString fn = QStringLiteral("%1/Maps/%2").arg(homePath, url.url());
|
|
||||||
if (!QFile::exists(fn))
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Can not find map data file '%s'\n", fn.toStdString().c_str());
|
|
||||||
QMessageBox::warning(this, tr("Can not find map data"),
|
|
||||||
tr("Can not find map data file '%1' - can't start application").arg(fn));
|
|
||||||
QCoreApplication::quit();
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
url.setUrl(QUrl::fromLocalFile(fn).toString());
|
|
||||||
out.push_back(std::move(url));
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
|
|
||||||
#include "thp_situation_widget.moc"
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* Handle situation display in thp
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SituationReplay/main_handler_sqlite.h>
|
|
||||||
#include "thp_situation_building_base.h"
|
|
||||||
|
|
||||||
namespace SituationReplay
|
|
||||||
{
|
|
||||||
class HandlerSituationReplaySqlite;
|
|
||||||
}
|
|
||||||
namespace SituationMap
|
|
||||||
{
|
|
||||||
class BaseUrl;
|
|
||||||
struct OperatorMapSettings;
|
|
||||||
}
|
|
||||||
namespace FilterManagement
|
|
||||||
{
|
|
||||||
class AesDisplayFilter;
|
|
||||||
class SymbolAppearanceSettings;
|
|
||||||
class BuildingComponentSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class SituationWidget;
|
|
||||||
}
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
class SitMapPluginProvider;
|
|
||||||
class SituatationFilterAes;
|
|
||||||
class SituatationFilterSymbolAppearance;
|
|
||||||
class SituatationFilterCollapseExpand;
|
|
||||||
class SituatationFilterTypes;
|
|
||||||
class SituationFilterBuildingComponent;
|
|
||||||
class MySitMapIinit;
|
|
||||||
|
|
||||||
class SituationWidget : public SituationBuildingBase
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit SituationWidget(QWidget *parent = nullptr);
|
|
||||||
~SituationWidget();
|
|
||||||
|
|
||||||
bool init(const QString &homePath, int exerciseId);
|
|
||||||
|
|
||||||
SituationReplay::MainHandlerSqlite *replayHandler() { return m_replayHandler; }
|
|
||||||
SitMapPluginProvider *pluginProvider() { return m_pluginProvider; }
|
|
||||||
|
|
||||||
|
|
||||||
QImage grabFrameBuffer() const;
|
|
||||||
QString centerPointString() const;
|
|
||||||
QRectF extentMgrs() const; // mgrs
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool showSituationInternal() override;
|
|
||||||
bool applyFilterFromReplayConfigFile();
|
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent *event) override;
|
|
||||||
void loadLayerMappings(const QString &homePath);
|
|
||||||
QVector<SituationMap::BaseUrl> fixupUrls(const QVector<SituationMap::BaseUrl> &in,
|
|
||||||
const QString &homePath);
|
|
||||||
|
|
||||||
bool restoreOperatorMapSettingsOverlays(const SituationMap::OperatorMapSettings &oms);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void applyCurentFilter(const SituationReplay::FilterInformation &filter) override;
|
|
||||||
void applyNewOverlay(int overlayId) override;
|
|
||||||
void removeOverlay(int overlayId) override;
|
|
||||||
|
|
||||||
void onFilterAes();
|
|
||||||
void onFilterSymbolAppearance();
|
|
||||||
void onFilterCollapseExpand();
|
|
||||||
void onFilterTypes();
|
|
||||||
void onFilterBuildingComponent();
|
|
||||||
|
|
||||||
void updateZoomSlider() override;
|
|
||||||
|
|
||||||
void onInitDone() override;
|
|
||||||
void emitPartitionTimeChanged(qint64 curTime) override;
|
|
||||||
void onMgrsGrid();
|
|
||||||
void onRotate(int degrees);
|
|
||||||
|
|
||||||
void onFileContentAvailable(const FileManagement::Database::FlmFileContent &data) override;
|
|
||||||
private:
|
|
||||||
QVector<QPair<QString, QString>> m_layerMapping;
|
|
||||||
|
|
||||||
SitMapPluginProvider *m_pluginProvider{nullptr};
|
|
||||||
MySitMapIinit *m_situationMapInit{nullptr};
|
|
||||||
SituatationFilterAes *m_filterAesDialog{nullptr};
|
|
||||||
SituatationFilterSymbolAppearance *m_filterSymbolAppearanceDialog{nullptr};
|
|
||||||
SituatationFilterCollapseExpand *m_filterCollapseExpandDialog{nullptr};
|
|
||||||
SituatationFilterTypes *m_filterTypesDialog{nullptr};
|
|
||||||
SituationFilterBuildingComponent *m_filterBuildingComponentDialog{nullptr};
|
|
||||||
|
|
||||||
std::shared_ptr<FilterManagement::AesDisplayFilter> m_aesDisplayFilter;
|
|
||||||
std::shared_ptr<FilterManagement::SymbolAppearanceSettings> m_symbolAppaearanceSettings;
|
|
||||||
std::shared_ptr<FilterManagement::BuildingComponentSettings> m_buildingComponentSettings;
|
|
||||||
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* A special slider for zooming
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "thp_zoom_slider.h"
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QSlider>
|
|
||||||
#include <QHBoxLayout>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
|
|
||||||
ZoomSlider::ZoomSlider(QWidget *parent)
|
|
||||||
: QWidget(parent)
|
|
||||||
, m_InternalMin(0.1)
|
|
||||||
, m_InternalMax(100)
|
|
||||||
, m_LowerThreshold(1)
|
|
||||||
, m_UpperThreshold(10)
|
|
||||||
, m_MinRange(0)
|
|
||||||
, m_MaxRange(280)
|
|
||||||
, m_Slider(nullptr)
|
|
||||||
, m_lbl(nullptr)
|
|
||||||
, m_text(nullptr)
|
|
||||||
, m_ZoomValue(-1)
|
|
||||||
, m_curSliderVal(-1)
|
|
||||||
{
|
|
||||||
setShowDescriptionLabel(true);
|
|
||||||
setShowValueLabel(true);
|
|
||||||
m_Slider = new QSlider(this);
|
|
||||||
|
|
||||||
connect(m_Slider, &QSlider::valueChanged, this, &ZoomSlider::calcZoomFromSlider);
|
|
||||||
connect(this, &ZoomSlider::valueChanged, this, &ZoomSlider::updateLabel);
|
|
||||||
|
|
||||||
m_Slider->setRange(m_MinRange, m_MaxRange);
|
|
||||||
m_Slider->setSingleStep(1);
|
|
||||||
m_Slider->setPageStep(1);
|
|
||||||
|
|
||||||
setOrientation(Qt::Horizontal);
|
|
||||||
//Initial calculation
|
|
||||||
calcZoomFromSlider(m_Slider->value());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoomSlider::setZoomValue(double zoomValue)
|
|
||||||
{
|
|
||||||
if (qFuzzyCompare(m_ZoomValue, zoomValue))
|
|
||||||
return;
|
|
||||||
//ignore values outside Min/Max boundaries.
|
|
||||||
if (zoomValue < m_InternalMin || zoomValue > m_InternalMax)
|
|
||||||
return;
|
|
||||||
m_ZoomValue = zoomValue;
|
|
||||||
|
|
||||||
if (zoomValue < m_LowerThreshold)
|
|
||||||
{
|
|
||||||
//Range is 0..50%
|
|
||||||
double l_Range = (m_MaxRange - m_MinRange) / 2;
|
|
||||||
|
|
||||||
double l_ValToSet = l_Range / static_cast<double>(m_LowerThreshold - m_InternalMin) * (zoomValue - m_InternalMin);
|
|
||||||
//qDebug() << "Value1 = " << l_ValToSet;
|
|
||||||
m_curSliderVal = static_cast<int>(l_ValToSet);
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (zoomValue < m_UpperThreshold)
|
|
||||||
{
|
|
||||||
//Range is 50%..75%
|
|
||||||
double l_Range = (m_MaxRange - m_MinRange) / 4;
|
|
||||||
double l_ValToSet = l_Range / static_cast<double>(m_UpperThreshold - m_LowerThreshold) * (zoomValue - m_LowerThreshold);
|
|
||||||
l_ValToSet += l_Range * 2;
|
|
||||||
//qDebug() << "Value2 = " << l_ValToSet;
|
|
||||||
m_curSliderVal = static_cast<int>(l_ValToSet);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Range is 75%..100%
|
|
||||||
double l_Range = (m_MaxRange - m_MinRange) / 4;
|
|
||||||
double l_ValToSet = l_Range / static_cast<double>(m_InternalMax - m_UpperThreshold) * (zoomValue - m_UpperThreshold);
|
|
||||||
l_ValToSet += l_Range * 3;
|
|
||||||
//qDebug() << "Value3 = " << l_ValToSet;
|
|
||||||
m_curSliderVal = static_cast<int>(l_ValToSet);
|
|
||||||
|
|
||||||
}
|
|
||||||
m_Slider->setValue(m_curSliderVal);
|
|
||||||
updateLabel(m_ZoomValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
double ZoomSlider::getZoomValue() const
|
|
||||||
{
|
|
||||||
return m_ZoomValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoomSlider::setOrientation(Qt::Orientation a_orientation)
|
|
||||||
{
|
|
||||||
if (!m_Slider)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_Slider->setOrientation(a_orientation);
|
|
||||||
QBoxLayout *l_Layout;
|
|
||||||
if (a_orientation == Qt::Horizontal)
|
|
||||||
{
|
|
||||||
m_Slider->setMinimumWidth(40);
|
|
||||||
m_Slider->setMinimumHeight(0);
|
|
||||||
l_Layout = new QHBoxLayout;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_Slider->setMinimumWidth(0);
|
|
||||||
m_Slider->setMinimumHeight(40);
|
|
||||||
l_Layout = new QVBoxLayout;
|
|
||||||
}
|
|
||||||
l_Layout->setContentsMargins(0, 0, 0, 0);
|
|
||||||
if (m_text)
|
|
||||||
l_Layout->addWidget(m_text);
|
|
||||||
if (m_Slider)
|
|
||||||
l_Layout->addWidget(m_Slider);
|
|
||||||
if (m_lbl)
|
|
||||||
l_Layout->addWidget(m_lbl);
|
|
||||||
delete layout();
|
|
||||||
setLayout(l_Layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::Orientation ZoomSlider::getOrientation() const
|
|
||||||
{
|
|
||||||
if (m_Slider)
|
|
||||||
return m_Slider->orientation();
|
|
||||||
return Qt::Horizontal;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZoomSlider::getShowDescriptionLabel() const
|
|
||||||
{
|
|
||||||
return (m_text != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoomSlider::setShowDescriptionLabel(bool bVisible)
|
|
||||||
{
|
|
||||||
if (getShowDescriptionLabel() == bVisible)
|
|
||||||
return;
|
|
||||||
if (bVisible)
|
|
||||||
{
|
|
||||||
m_text = new QLabel(this);
|
|
||||||
m_text->setText(tr("Zoom:"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete m_text;
|
|
||||||
m_text = nullptr;
|
|
||||||
}
|
|
||||||
setOrientation(getOrientation());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ZoomSlider::getShowValueLabel() const
|
|
||||||
{
|
|
||||||
return (m_lbl != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoomSlider::setShowValueLabel(bool bVisible)
|
|
||||||
{
|
|
||||||
if (getShowValueLabel() == bVisible)
|
|
||||||
return;
|
|
||||||
if (bVisible)
|
|
||||||
m_lbl = new QLabel(this);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete m_lbl;
|
|
||||||
m_lbl = nullptr;
|
|
||||||
}
|
|
||||||
setOrientation(getOrientation());
|
|
||||||
updateLabel(m_ZoomValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ZoomSlider::calcZoomFromSlider(int a_value)
|
|
||||||
{
|
|
||||||
if (m_curSliderVal == a_value)
|
|
||||||
return;
|
|
||||||
m_curSliderVal = a_value;
|
|
||||||
|
|
||||||
if (a_value < (m_MaxRange - m_MinRange) / 2)
|
|
||||||
{
|
|
||||||
//Range 0% - 50%
|
|
||||||
double l_R1 = (m_MaxRange - m_MinRange) / 2;
|
|
||||||
double l_R2 = (m_LowerThreshold - m_InternalMin);
|
|
||||||
double l_ValToSet = l_R2 / l_R1 * a_value;
|
|
||||||
l_ValToSet += m_InternalMin;
|
|
||||||
//qDebug() << "Value4 = " << l_ValToSet;
|
|
||||||
m_ZoomValue = l_ValToSet;
|
|
||||||
}
|
|
||||||
else if (a_value < 3 * (m_MaxRange - m_MinRange) / 4)
|
|
||||||
{
|
|
||||||
//Range 50% - 75%
|
|
||||||
double l_R1 = (m_MaxRange - m_MinRange) / 4;
|
|
||||||
double l_R2 = (m_UpperThreshold - m_LowerThreshold);
|
|
||||||
double l_SliderVal = a_value - (m_MaxRange - m_MinRange) / 2;
|
|
||||||
double l_ValToSet = l_R2 / l_R1 * l_SliderVal;
|
|
||||||
l_ValToSet += static_cast<double>(m_LowerThreshold);
|
|
||||||
//qDebug() << "Value5 = " << l_ValToSet;
|
|
||||||
m_ZoomValue = l_ValToSet;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Range 75% - 100%
|
|
||||||
double l_R1 = (m_MaxRange - m_MinRange) / 4;
|
|
||||||
double l_R2 = (m_InternalMax - m_UpperThreshold);
|
|
||||||
double l_SliderVal = a_value - (m_MaxRange - m_MinRange) / 4 * 3;
|
|
||||||
double l_ValToSet = l_R2 / l_R1 * l_SliderVal;
|
|
||||||
|
|
||||||
l_ValToSet += static_cast<double>(m_UpperThreshold);
|
|
||||||
//qDebug() << "Value6 = " << l_ValToSet;
|
|
||||||
m_ZoomValue = l_ValToSet;
|
|
||||||
}
|
|
||||||
emit valueChanged(m_ZoomValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ZoomSlider::updateLabel(double newValue)
|
|
||||||
{
|
|
||||||
if (!m_lbl)
|
|
||||||
return;
|
|
||||||
m_lbl->setText(formatValue(newValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ZoomSlider::formatValue(double value) const
|
|
||||||
{
|
|
||||||
if (value < m_LowerThreshold)
|
|
||||||
return QStringLiteral("%1x").arg(value, 4, 'f', 2);
|
|
||||||
if (value < m_UpperThreshold)
|
|
||||||
return QStringLiteral("%1x").arg(value, 4, 'f', 1);
|
|
||||||
|
|
||||||
return QStringLiteral("%1x").arg(value, 4, 'f', 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace THP
|
|
||||||
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
/**
|
|
||||||
* @RDE_HEADER@
|
|
||||||
* A special slider for zooming
|
|
||||||
* $Id$
|
|
||||||
* $HeadURL$
|
|
||||||
* $Author$
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
class QLabel;
|
|
||||||
class QSlider;
|
|
||||||
|
|
||||||
namespace THP
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* An specialized QSlider
|
|
||||||
* This slider has a special, fixed range from 0.1 - 100 which is mapped to
|
|
||||||
* suitable map scales used in the GUEZ.
|
|
||||||
* The scale is not linear - instead it has a model behind. in smaller scales -
|
|
||||||
* slider's going to 0.1 - it's resolution is finer than on larger scales -
|
|
||||||
* slider's going to 100.
|
|
||||||
* The slider accpets only values within the range 0.1....100. Other values are ignored.
|
|
||||||
*/
|
|
||||||
class ZoomSlider : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(Qt::Orientation Orientation READ getOrientation WRITE setOrientation)
|
|
||||||
Q_PROPERTY(bool showDescriptionLabel READ getShowDescriptionLabel WRITE setShowDescriptionLabel)
|
|
||||||
Q_PROPERTY(bool showValueLabel READ getShowValueLabel WRITE setShowValueLabel)
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
explicit ZoomSlider(QWidget *parent = nullptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get the actual Zoom value.
|
|
||||||
* @return float with the zoom value
|
|
||||||
*/
|
|
||||||
double getZoomValue() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the Orientation.
|
|
||||||
* @param a_orientation The slider's orientation.
|
|
||||||
*/
|
|
||||||
void setOrientation(Qt::Orientation a_orientation);
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
Qt::Orientation getOrientation() const;
|
|
||||||
|
|
||||||
bool getShowDescriptionLabel() const;
|
|
||||||
void setShowDescriptionLabel(bool bVisible);
|
|
||||||
|
|
||||||
bool getShowValueLabel() const;
|
|
||||||
void setShowValueLabel(bool bVisible);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* format the given value as it would be shown in the zoom label
|
|
||||||
*/
|
|
||||||
QString formatValue(double value) const;
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
|
||||||
/**
|
|
||||||
* set the slider's actual zoom value. This is a QT-Slot.
|
|
||||||
* The slider accpet only values within it's range 0.1...100.
|
|
||||||
* Other values are ignored.
|
|
||||||
* @param a_zoomValue the new zoom value.
|
|
||||||
*/
|
|
||||||
void setZoomValue(double zoomValue);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
/**
|
|
||||||
* A QT-Signal which is emitted whenever the slider's value has changed.
|
|
||||||
* The newly set zoom value is delivered as argument.
|
|
||||||
*/
|
|
||||||
void valueChanged(double a_value);
|
|
||||||
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
/**
|
|
||||||
* Update the label text
|
|
||||||
*/
|
|
||||||
void updateLabel(double newValue);
|
|
||||||
private:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains the slider's minimum zoom value
|
|
||||||
*/
|
|
||||||
const double m_InternalMin;
|
|
||||||
/**
|
|
||||||
* Contains the slider's maximum zoom value
|
|
||||||
*/
|
|
||||||
const double m_InternalMax;
|
|
||||||
/**
|
|
||||||
* Contains the slider's lower threshold value.
|
|
||||||
* The lower threshold is at 50% of the sliders range.
|
|
||||||
*/
|
|
||||||
const int m_LowerThreshold;
|
|
||||||
/**
|
|
||||||
* Contains the slider's upper threshold value.
|
|
||||||
* The upper threshold is at 75% of the sliders range.
|
|
||||||
*/
|
|
||||||
const int m_UpperThreshold;
|
|
||||||
/**
|
|
||||||
* Contains the slider's range minimum value
|
|
||||||
*/
|
|
||||||
const int m_MinRange;
|
|
||||||
/**
|
|
||||||
* Contains the slider's range maximum value
|
|
||||||
*/
|
|
||||||
const int m_MaxRange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The QSlider
|
|
||||||
*/
|
|
||||||
QSlider *m_Slider;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The label for showing the exact slider value.
|
|
||||||
*/
|
|
||||||
QLabel *m_lbl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The label for showing the 'zoom' text
|
|
||||||
*/
|
|
||||||
QLabel *m_text;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* contains the zoom value
|
|
||||||
*/
|
|
||||||
double m_ZoomValue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current value of the slider to avoid loops
|
|
||||||
*/
|
|
||||||
int m_curSliderVal;
|
|
||||||
|
|
||||||
private slots :
|
|
||||||
/**
|
|
||||||
* Calculates the zoom value from the slider's position
|
|
||||||
*/
|
|
||||||
void calcZoomFromSlider(int a_value);
|
|
||||||
|
|
||||||
};
|
|
||||||
} // namespace THP
|
|
||||||
@@ -4,11 +4,8 @@
|
|||||||
# $Author$
|
# $Author$
|
||||||
#
|
#
|
||||||
|
|
||||||
# Release 2 Common modules (S set: 16 modules)
|
# Release 2 Common modules (S set: 15 modules)
|
||||||
# Mock library for unit tests (CoordTrans mocks)
|
|
||||||
ADD_SUBDIRECTORY(CommonUnitTestsPlaceholder)
|
|
||||||
ADD_SUBDIRECTORY(CodeGen)
|
ADD_SUBDIRECTORY(CodeGen)
|
||||||
ADD_SUBDIRECTORY(httq)
|
|
||||||
ADD_SUBDIRECTORY(LtsAppDescriptor)
|
ADD_SUBDIRECTORY(LtsAppDescriptor)
|
||||||
ADD_SUBDIRECTORY(LtsCommandLineParser)
|
ADD_SUBDIRECTORY(LtsCommandLineParser)
|
||||||
ADD_SUBDIRECTORY(LtsCoordTrans)
|
ADD_SUBDIRECTORY(LtsCoordTrans)
|
||||||
@@ -19,13 +16,10 @@ ADD_SUBDIRECTORY(LtsLicence)
|
|||||||
ADD_SUBDIRECTORY(LtsNotification)
|
ADD_SUBDIRECTORY(LtsNotification)
|
||||||
ADD_SUBDIRECTORY(LtsPluginManager)
|
ADD_SUBDIRECTORY(LtsPluginManager)
|
||||||
ADD_SUBDIRECTORY(LtsSession)
|
ADD_SUBDIRECTORY(LtsSession)
|
||||||
ADD_SUBDIRECTORY(LtsRestClient)
|
|
||||||
ADD_SUBDIRECTORY(LtsSerialPortQuerry)
|
ADD_SUBDIRECTORY(LtsSerialPortQuerry)
|
||||||
ADD_SUBDIRECTORY(LtsUtils)
|
ADD_SUBDIRECTORY(LtsUtils)
|
||||||
ADD_SUBDIRECTORY(LtsWebSocket)
|
|
||||||
ADD_SUBDIRECTORY(LtsWidgets)
|
ADD_SUBDIRECTORY(LtsWidgets)
|
||||||
ADD_SUBDIRECTORY(ProjectConfig)
|
ADD_SUBDIRECTORY(ProjectConfig)
|
||||||
ADD_SUBDIRECTORY(TopicEditorBase)
|
|
||||||
# LtsMultiMonitor and PluginInterfaces required by LtsSession for Release 2a
|
# LtsMultiMonitor and PluginInterfaces required by LtsSession for Release 2a
|
||||||
ADD_SUBDIRECTORY(LtsMultiMonitor)
|
ADD_SUBDIRECTORY(LtsMultiMonitor)
|
||||||
ADD_SUBDIRECTORY(PluginInterfaces)
|
ADD_SUBDIRECTORY(PluginInterfaces)
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
|
||||||
project(CommonUnitTestsPlaceholder)
|
|
||||||
|
|
||||||
include(FetchContent)
|
|
||||||
|
|
||||||
option(BUILD_SMOKE_TESTS "Build QtTest smoke tests" OFF)
|
|
||||||
option(BUILD_GTEST_SMOKE "Build GTest smoke tests" OFF)
|
|
||||||
|
|
||||||
add_subdirectory(mocks)
|
|
||||||
|
|
||||||
if(BUILD_SMOKE_TESTS)
|
|
||||||
if(NOT TARGET Qt6::Test)
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Test)
|
|
||||||
endif()
|
|
||||||
add_executable(coordTransTests_smoke coordTransTests_smoke.cpp)
|
|
||||||
target_link_libraries(coordTransTests_smoke PRIVATE Qt6::Test MockCoordTrans::MockCoordTrans)
|
|
||||||
add_test(NAME coordTransTests_smoke COMMAND coordTransTests_smoke)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_GTEST_SMOKE)
|
|
||||||
find_package(GTest QUIET)
|
|
||||||
if(NOT GTest_FOUND)
|
|
||||||
FetchContent_Declare(
|
|
||||||
googletest
|
|
||||||
GIT_REPOSITORY https://github.com/google/googletest.git
|
|
||||||
GIT_TAG release-1.12.1
|
|
||||||
)
|
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
||||||
FetchContent_MakeAvailable(googletest)
|
|
||||||
endif()
|
|
||||||
add_executable(coordTransTests_gtest coordTransTests_gtest.cpp)
|
|
||||||
target_link_libraries(coordTransTests_gtest PRIVATE GTest::gtest_main MockCoordTrans::MockCoordTrans)
|
|
||||||
add_test(NAME coordTransTests_gtest COMMAND coordTransTests_gtest)
|
|
||||||
endif()
|
|
||||||
-11
@@ -1,11 +0,0 @@
|
|||||||
// Stub GTest smoke test for coordTrans
|
|
||||||
#include <gtest/gtest.h>
|
|
||||||
|
|
||||||
TEST(CoordTransSmokeTest, StubTest) {
|
|
||||||
EXPECT_TRUE(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
::testing::InitGoogleTest(&argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
// Stub QtTest smoke test for coordTrans
|
|
||||||
#include <QTest>
|
|
||||||
|
|
||||||
class CoordTransSmokeTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void stubTest() {
|
|
||||||
QVERIFY(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
QTEST_APPLESS_MAIN(CoordTransSmokeTest)
|
|
||||||
-5
@@ -1,5 +0,0 @@
|
|||||||
add_library(MockCoordTrans STATIC MockCoordTrans.h)
|
|
||||||
target_include_directories(MockCoordTrans PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
|
|
||||||
# Export header-only semantics by providing an interface target
|
|
||||||
add_library(MockCoordTrans::MockCoordTrans ALIAS MockCoordTrans)
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
// MockCoordTrans.h - Stub mock for CoordTrans functionality
|
|
||||||
// This is a placeholder to allow builds without full CoordTrans implementation
|
|
||||||
|
|
||||||
#ifndef MOCK_COORD_TRANS_H
|
|
||||||
#define MOCK_COORD_TRANS_H
|
|
||||||
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QPointF>
|
|
||||||
|
|
||||||
// Minimal stub to satisfy linker requirements
|
|
||||||
namespace LtsCoordTrans {
|
|
||||||
// Placeholder types
|
|
||||||
struct UtmCoordinate {
|
|
||||||
static UtmCoordinate fromMgrs(const QString&) { return UtmCoordinate(); }
|
|
||||||
QPointF geographic() const { return QPointF(); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MOCK_COORD_TRANS_H
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "app.h"
|
|
||||||
|
|
||||||
#include "AppChooser/app_chooser_model.h"
|
|
||||||
#include "ui_app.h"
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
CustomViewApp::CustomViewApp(QWidget* parent) : AbstractDisplayWidget(parent), m_ui(new Ui::CustomViewApp)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
m_ui->image->setMenuEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomViewApp::~CustomViewApp()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CustomViewApp::init(const QModelIndex& idx)
|
|
||||||
{
|
|
||||||
if (!idx.isValid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_ui->lbAppName->setText(rowData(idx, AppChooserModel::Name).toString());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class CustomViewApp;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
class CustomViewApp final : public LtsDataView::AbstractDisplayWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CustomViewApp(QWidget* parent = nullptr);
|
|
||||||
~CustomViewApp();
|
|
||||||
bool init(const QModelIndex& idx) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::CustomViewApp* m_ui;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
-108
@@ -1,108 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>CustomViewApp</class>
|
|
||||||
<widget class="QWidget" name="CustomViewApp">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>300</width>
|
|
||||||
<height>150</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="LtsWidgets::LtsImageEditor" name="image">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>128</width>
|
|
||||||
<height>128</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
|
||||||
<width>128</width>
|
|
||||||
<height>128</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lbAppName">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"><App Name></string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lbDescription">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"><html><head/><body><p>&lt;Description with wordwrap&gt;</p></body></html></string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>LtsWidgets::LtsImageEditor</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>LtsWidgets/lts_image_editor.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "AppChooser/app_chooser.h"
|
|
||||||
|
|
||||||
#include "AppChooser/CustomViews/app.h"
|
|
||||||
#include "AppChooser/app_chooser_model.h"
|
|
||||||
#include "lts_app_manager.h"
|
|
||||||
#include "ui_app_chooser.h"
|
|
||||||
|
|
||||||
#include <QtGui/QCloseEvent>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
AppChooser::AppChooser() : QWidget(nullptr), m_ui(new Ui::AppChooser), m_model(), m_madeSelection(false)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
connect(m_ui->widget, &LtsDataView::LtsDataView::LtsDataView::signalDoubleClicked, this,
|
|
||||||
&AppChooser::slotAppSelected);
|
|
||||||
connect(m_ui->widget, &LtsDataView::LtsDataView::LtsDataView::signalEnterPressed, this,
|
|
||||||
&AppChooser::slotAppSelected);
|
|
||||||
connect(m_ui->widget, &LtsDataView::LtsDataView::LtsDataView::signalSelectionChanged, this, &AppChooser::enaDisa);
|
|
||||||
connect(m_ui->pbQuit, &QPushButton::clicked, this, &QWidget::close);
|
|
||||||
connect(m_ui->pbSelect, &QPushButton::clicked, this, &AppChooser::slotAppSelected);
|
|
||||||
|
|
||||||
m_model = new AppChooserModel(this);
|
|
||||||
m_model->initModel(LtsAppManager::getInstance()->getAvailableApps());
|
|
||||||
|
|
||||||
m_ui->widget->seamless();
|
|
||||||
|
|
||||||
m_ui->widget->setModel(m_model);
|
|
||||||
m_ui->widget->hideColumn(AppChooserModel::Columns::Visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
AppChooser::~AppChooser()
|
|
||||||
{
|
|
||||||
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooser::slotQuit()
|
|
||||||
{
|
|
||||||
if (m_alreadyCloseEmitted)
|
|
||||||
return;
|
|
||||||
m_alreadyCloseEmitted = true;
|
|
||||||
emit signalLogout();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooser::closeEvent(QCloseEvent*)
|
|
||||||
{
|
|
||||||
if (!m_madeSelection)
|
|
||||||
slotQuit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooser::slotAppSelected()
|
|
||||||
{
|
|
||||||
const QModelIndex idx = m_ui->widget->currentIndex();
|
|
||||||
const LtsAppDescriptor::AppDescription app = m_model->getRowData(idx.row());
|
|
||||||
|
|
||||||
if (!app.active)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hide();
|
|
||||||
m_madeSelection = true;
|
|
||||||
emit signalAppSelected(app.id);
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppChooser::enaDisa()
|
|
||||||
{
|
|
||||||
const QModelIndexList selectedRows = m_ui->widget->selectedRows();
|
|
||||||
const int cntSelectedRows = selectedRows.size();
|
|
||||||
|
|
||||||
m_ui->pbSelect->setEnabled(cntSelectedRows == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtWidgets/QWidget>
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class AppChooser;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
class AppChooserModel;
|
|
||||||
|
|
||||||
class AppChooser : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
AppChooser();
|
|
||||||
~AppChooser();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui::AppChooser* m_ui;
|
|
||||||
AppChooserModel* m_model;
|
|
||||||
bool m_madeSelection;
|
|
||||||
bool m_alreadyCloseEmitted{false};
|
|
||||||
|
|
||||||
void enaDisa();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void closeEvent(QCloseEvent*);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void signalAppSelected(LtsAppDescriptor::App appId);
|
|
||||||
void signalLogout();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotAppSelected();
|
|
||||||
void slotQuit();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>AppChooser</class>
|
|
||||||
<widget class="QWidget" name="AppChooser">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>800</width>
|
|
||||||
<height>400</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>0</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>App Chooser</string>
|
|
||||||
</property>
|
|
||||||
<property name="windowIcon">
|
|
||||||
<iconset resource="../../LtsWidgets/resources/lts_resources.qrc">
|
|
||||||
<normaloff>:/rde_icon_256.png</normaloff>:/rde_icon_256.png</iconset>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Select App:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="LtsDataView::LtsDataView" name="widget" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pbQuit">
|
|
||||||
<property name="text">
|
|
||||||
<string>Quit</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="pbSelect">
|
|
||||||
<property name="enabled">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Select</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>LtsDataView::LtsDataView</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">Viewer/LtsDataView/lts_data_view.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources>
|
|
||||||
<include location="../../LtsWidgets/resources/lts_resources.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
-48
@@ -1,48 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "app_chooser_model.h"
|
|
||||||
|
|
||||||
#include <LtsSession/lts_session.h>
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
AppChooserModel::AppChooserModel(QObject* parent)
|
|
||||||
: LtsWidgets::LtsAbstractTableModel<LtsAppDescriptor::AppDescription>({tr("Name")}, parent)
|
|
||||||
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AppChooserModel::initModel(const LtsAppDescriptor::AppDescriptionVector& availableApps)
|
|
||||||
{
|
|
||||||
for (auto i = availableApps.constBegin(); i != availableApps.constEnd(); ++i)
|
|
||||||
{
|
|
||||||
const LtsAppDescriptor::AppDescription& appDesc = *i;
|
|
||||||
|
|
||||||
if (!appDesc.visible)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
insertRow(appDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant AppChooserModel::data(const QModelIndex& index, int role) const
|
|
||||||
{
|
|
||||||
if (role != Qt::DisplayRole || !indexIsValid(index))
|
|
||||||
return QVariant();
|
|
||||||
|
|
||||||
const LtsAppDescriptor::AppDescription& ad = m_vecData.at(index.row());
|
|
||||||
|
|
||||||
switch (index.column())
|
|
||||||
{
|
|
||||||
case Name:
|
|
||||||
return LtsSession::LtsSession::appToString(ad.id);
|
|
||||||
case Visible:
|
|
||||||
return ad.visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
||||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
class AppChooserModel final : public LtsWidgets::LtsAbstractTableModel<LtsAppDescriptor::AppDescription>
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Columns {
|
|
||||||
Name = 0,
|
|
||||||
Visible,
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit AppChooserModel(QObject* parent = nullptr);
|
|
||||||
|
|
||||||
bool initModel(const LtsAppDescriptor::AppDescriptionVector& availableApps);
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override final;
|
|
||||||
};
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
# Make ${Qt6_Gui} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Gui)
|
|
||||||
set(Qt6_Gui ${Qt6_Gui})
|
|
||||||
else()
|
|
||||||
set(Qt6_Gui "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Make ${Qt6_Widgets} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
|
||||||
set(Qt6_Widgets ${Qt6_Widgets})
|
|
||||||
else()
|
|
||||||
set(Qt6_Widgets "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Mike Wille, SLSE, 2016-10-27
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
# LtsAppManager
|
|
||||||
|
|
||||||
set(LtsAppManager_SRCS
|
|
||||||
lts_app_manager.cpp
|
|
||||||
AppChooser/app_chooser.cpp
|
|
||||||
AppChooser/app_chooser_model.cpp
|
|
||||||
AppChooser/CustomViews/app.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_WRAP_UI(LtsAppManager_SRCS
|
|
||||||
AppChooser/app_chooser.ui
|
|
||||||
AppChooser/CustomViews/app.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(BUILD_RTI)
|
|
||||||
NGL_ADD_LIBRARY2(WS LtsAppManager SHARED ${LtsAppManager_SRCS})
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsAppManager
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/AppChooser/
|
|
||||||
)
|
|
||||||
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsAppManager
|
|
||||||
PRIVATE
|
|
||||||
NGLLogger
|
|
||||||
LtsDataView
|
|
||||||
LtsWidgets
|
|
||||||
LtsLogin
|
|
||||||
LtsPluginManager
|
|
||||||
LtsSession
|
|
||||||
LtsSessionData
|
|
||||||
LtsUtilsSettings
|
|
||||||
LtsMultiMonitor
|
|
||||||
ProjectConfig
|
|
||||||
${Qt6_Gui}
|
|
||||||
${Qt6_Widgets}
|
|
||||||
Qt6::Network # debug server
|
|
||||||
OpmSettingsGuiPluginInterface
|
|
||||||
LtsPluginLoader
|
|
||||||
PUBLIC
|
|
||||||
Qt6::Core
|
|
||||||
LtsAppDescriptor
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
NGL_INSTALL_TARGET(LtsAppManager)
|
|
||||||
ENDIF(BUILD_RTI)
|
|
||||||
@@ -1,963 +0,0 @@
|
|||||||
#include "lts_app_manager.h"
|
|
||||||
|
|
||||||
#include "AppChooser/app_chooser.h"
|
|
||||||
|
|
||||||
#include <LtsLogin/lts_login.h>
|
|
||||||
#include <LtsMultiMonitor/lts_multi_monitor.h>
|
|
||||||
#include <LtsPluginManager/lts_plugin_manager.h>
|
|
||||||
#include <LtsSession/lts_session.h>
|
|
||||||
#include <LtsSession/lts_session_data.h>
|
|
||||||
#include <LtsSession/lts_session_manager.h>
|
|
||||||
#include <LtsUtilsSettings/settings.h>
|
|
||||||
#include <LtsWidgets/lts_events.h>
|
|
||||||
#include <LtsWidgets/lts_global_wait_dialog.h>
|
|
||||||
#include <OperatorManagement/opm_settings_gui_plugin_interface.h>
|
|
||||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QJsonArray>
|
|
||||||
#include <QtCore/QJsonDocument>
|
|
||||||
#include <QtCore/QJsonObject>
|
|
||||||
#include <QtCore/QJsonValue>
|
|
||||||
#include <QtWidgets/QMessageBox>
|
|
||||||
#include <QtNetwork/QTcpServer>
|
|
||||||
#include <QtNetwork/QTcpSocket>
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
#include <QtCore/QUuid>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#ifndef LTS_VERSION_MAJOR
|
|
||||||
#define LTS_VERSION_MAJOR "undefined"
|
|
||||||
#endif
|
|
||||||
#ifndef LTS_VERSION_MINOR
|
|
||||||
#define LTS_VERSION_MINOR "undefined"
|
|
||||||
#endif
|
|
||||||
#ifndef LTS_VERSION_PATCH
|
|
||||||
#define LTS_VERSION_PATCH "undefined"
|
|
||||||
#endif
|
|
||||||
#ifndef JENKINS_BUILD_NUMBER
|
|
||||||
#define JENKINS_BUILD_NUMBER "unknown"
|
|
||||||
#endif
|
|
||||||
static const char ver_major[] = LTS_VERSION_MAJOR;
|
|
||||||
static const char ver_minor[] = LTS_VERSION_MINOR;
|
|
||||||
static const char ver_patch[] = LTS_VERSION_PATCH;
|
|
||||||
static const char ver_jenkins[] = JENKINS_BUILD_NUMBER;
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
struct LtsAppManagerHandler
|
|
||||||
{
|
|
||||||
LtsAppManager ltsAppManager;
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_GLOBAL_STATIC(LtsAppManagerHandler, s_ltsAppManager)
|
|
||||||
|
|
||||||
LtsAppManager* LtsAppManager::getInstance()
|
|
||||||
{
|
|
||||||
return &s_ltsAppManager->ltsAppManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppManager::LtsAppManager() : m_login(nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
qRegisterMetaType<LtsAppDescriptor::App>("LtsAppDescriptor::App");
|
|
||||||
slotStartDebugServer();
|
|
||||||
connect(qApp, &QCoreApplication::aboutToQuit, this, [this] {
|
|
||||||
delete m_login;
|
|
||||||
m_login = nullptr;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppManager::~LtsAppManager()
|
|
||||||
{
|
|
||||||
|
|
||||||
delete m_login;
|
|
||||||
m_login = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::setAvailableApps(const LtsAppDescriptor::AppDescriptionVector& availableApps)
|
|
||||||
{
|
|
||||||
m_availableApps = availableApps;
|
|
||||||
|
|
||||||
#ifndef LTS_DEBUG
|
|
||||||
if (LtsSessionData::LtsSessionData::getInstance()->debugFlagValue(
|
|
||||||
QStringLiteral("PluginManager.CheckAppRequirements")) == QVariant(true))
|
|
||||||
{
|
|
||||||
QMessageBox::information(nullptr, QStringLiteral("LtsAppManager"),
|
|
||||||
QStringLiteral("Checking App Requirements now"));
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
QStringList errors;
|
|
||||||
LtsPluginManager::LtsPluginLoader::getInstance()->checkPlugins(availableApps, errors);
|
|
||||||
|
|
||||||
if (!errors.isEmpty())
|
|
||||||
QMessageBox::critical(
|
|
||||||
nullptr, QStringLiteral("LtsAppManager"),
|
|
||||||
QStringLiteral("App Requirements check failed!<br> - %1").arg(errors.join(QStringLiteral("<br> - "))));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_availableApps.isEmpty())
|
|
||||||
{
|
|
||||||
QMessageBox::critical(nullptr, tr("App Manager"),
|
|
||||||
tr("There are no apps available for this project.\nPlease contact Support."));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::slotStartDebugServer()
|
|
||||||
{
|
|
||||||
QTcpServer* debugServer = new QTcpServer(this);
|
|
||||||
|
|
||||||
if (!debugServer->listen(QHostAddress::Any, 20000))
|
|
||||||
{
|
|
||||||
debugServer->deleteLater();
|
|
||||||
const int waitTryAgain = 5;
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
|
|
||||||
#endif
|
|
||||||
QTimer::singleShot(waitTryAgain * 1000, this, &LtsAppManager::slotStartDebugServer);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(debugServer, &QTcpServer::newConnection, this, [this]() {
|
|
||||||
QTcpServer* server = qobject_cast<QTcpServer*>(sender());
|
|
||||||
|
|
||||||
if (server == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QTcpSocket* client = server->nextPendingConnection();
|
|
||||||
|
|
||||||
if (client == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
connect(client, &QTcpSocket::readyRead, this, [this]() {
|
|
||||||
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
|
|
||||||
|
|
||||||
if (client == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString commandStr(
|
|
||||||
QString::fromUtf8(client->readLine(100)).remove(QStringLiteral("\r")).remove(QStringLiteral("\n")));
|
|
||||||
|
|
||||||
QStringList argList = commandStr.split(QLatin1Char(' '), Qt::SkipEmptyParts);
|
|
||||||
|
|
||||||
if (argList.count() < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const QString& command = argList.at(0);
|
|
||||||
|
|
||||||
LtsSessionData::LtsSessionData* sessionData = LtsSessionData::LtsSessionData::getInstance();
|
|
||||||
static QStringList commands;
|
|
||||||
commands << QStringLiteral("showSessions") << QStringLiteral("operator") << QStringLiteral("help")
|
|
||||||
<< QStringLiteral("logout") << QStringLiteral("flag") << QStringLiteral("setFlag")
|
|
||||||
<< QStringLiteral("start") << QStringLiteral("voiceCommand") << QStringLiteral("ftcmock");
|
|
||||||
|
|
||||||
switch (commands.indexOf(command))
|
|
||||||
{
|
|
||||||
case 0: {
|
|
||||||
sessionData->setDebugFlagValue(QStringLiteral("DeveloperTools.ShowSessionsOnce"), true);
|
|
||||||
client->write("K");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1: {
|
|
||||||
QString operatorName(sessionData->getOperatorName());
|
|
||||||
|
|
||||||
if (operatorName.isEmpty())
|
|
||||||
operatorName = QStringLiteral("(none)");
|
|
||||||
|
|
||||||
QString result(QStringLiteral("%1").arg(operatorName));
|
|
||||||
client->write(result.toUtf8());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2: {
|
|
||||||
QString result(QStringLiteral("Available Commands: %1").arg(commands.join(QStringLiteral(", "))));
|
|
||||||
client->write(result.toUtf8());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3: {
|
|
||||||
client->write("...");
|
|
||||||
slotLogout();
|
|
||||||
client->write("\r\nK");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 4: {
|
|
||||||
if (argList.count() != 2)
|
|
||||||
{
|
|
||||||
client->write("Usage: flag <flag name>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString& debugFlagName = argList.at(1);
|
|
||||||
if (!sessionData->hasDebugFlag(debugFlagName))
|
|
||||||
{
|
|
||||||
client->write("(unknown)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->write(sessionData->debugFlagValue(argList.at(1)).toString().toUtf8());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 5: {
|
|
||||||
if (argList.count() < 3)
|
|
||||||
{
|
|
||||||
client->write("Usage: setFlag <flag name> <flag type> <value>\r\nFlag types: int, string (no "
|
|
||||||
"spaces allowed yet), boolean, double");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QStringList flagTypes;
|
|
||||||
flagTypes << QStringLiteral("int") << QStringLiteral("string") << QStringLiteral("boolean")
|
|
||||||
<< QStringLiteral("double");
|
|
||||||
|
|
||||||
const QString& flagType = argList.at(2);
|
|
||||||
bool k = false;
|
|
||||||
|
|
||||||
const QString& flagName = argList.at(1);
|
|
||||||
|
|
||||||
switch (flagTypes.indexOf(flagType))
|
|
||||||
{
|
|
||||||
case 0: {
|
|
||||||
int value = argList.at(3).toInt(&k);
|
|
||||||
if (k)
|
|
||||||
sessionData->setDebugFlagValue(flagName, value);
|
|
||||||
else
|
|
||||||
client->write("cannot convert value to integer");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1: {
|
|
||||||
sessionData->setDebugFlagValue(flagName, argList.at(3));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2: {
|
|
||||||
QString value(argList.at(3).toLower().simplified());
|
|
||||||
if (value == QStringLiteral("true"))
|
|
||||||
sessionData->setDebugFlagValue(flagName, true);
|
|
||||||
else if (value == QStringLiteral("false"))
|
|
||||||
sessionData->setDebugFlagValue(flagName, false);
|
|
||||||
else
|
|
||||||
client->write("cannot convert value to boolean");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 3: {
|
|
||||||
double value = argList.at(3).toDouble(&k);
|
|
||||||
if (k)
|
|
||||||
sessionData->setDebugFlagValue(flagName, value);
|
|
||||||
else
|
|
||||||
client->write("cannot convert value to double");
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
client->write("unknown flag type");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 6: {
|
|
||||||
if (argList.count() < 3)
|
|
||||||
{
|
|
||||||
client->write("Usage: start <app id> <domain id> ");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->write("not implemented yet");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 7: {
|
|
||||||
if (argList.count() < 2)
|
|
||||||
{
|
|
||||||
client->write("Usage: voiceCommand <keyword> <optional description>");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QStringList keywords;
|
|
||||||
keywords << QStringLiteral("AddMarker") << QStringLiteral("SetMarker")
|
|
||||||
<< QStringLiteral("AddSnapshot") << QStringLiteral("SaveSnapshot");
|
|
||||||
|
|
||||||
const QString& keyword = argList.at(1);
|
|
||||||
|
|
||||||
switch (keywords.indexOf(keyword))
|
|
||||||
{
|
|
||||||
case 0: {
|
|
||||||
auto ev = new LtsWidgets::AddMarkerEvent;
|
|
||||||
ev->setAccepted(false);
|
|
||||||
sessionData->setDebugFlagValue(command, keyword);
|
|
||||||
QCoreApplication::postEvent(qApp, ev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1: {
|
|
||||||
auto ev = new LtsWidgets::SetMarkerEvent(QString());
|
|
||||||
if (argList.size() > 2)
|
|
||||||
ev->setDescription(argList.at(2));
|
|
||||||
ev->setAccepted(false);
|
|
||||||
sessionData->setDebugFlagValue(command, keyword);
|
|
||||||
QCoreApplication::postEvent(qApp, ev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 2: {
|
|
||||||
auto ev = new LtsWidgets::AddSnapshotEvent;
|
|
||||||
ev->setAccepted(false);
|
|
||||||
sessionData->setDebugFlagValue(command, keyword);
|
|
||||||
QCoreApplication::postEvent(qApp, ev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 3: {
|
|
||||||
auto ev = new LtsWidgets::SaveSnapshotEvent(QString());
|
|
||||||
if (argList.size() > 2)
|
|
||||||
ev->setDescription(argList.at(2));
|
|
||||||
ev->setAccepted(false);
|
|
||||||
sessionData->setDebugFlagValue(command, keyword);
|
|
||||||
QCoreApplication::postEvent(qApp, ev);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionData->hasDebugFlag(command))
|
|
||||||
{
|
|
||||||
client->write("(unknown)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
client->write(sessionData->debugFlagValue(argList.at(1)).toString().toUtf8());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 8: {
|
|
||||||
auto usage = [client]() {
|
|
||||||
client->write("Usage: ftcmock start <sessionId> <min ms> <max ms> <timer count> - See 'Session "
|
|
||||||
"id' in DevDialog "
|
|
||||||
"\nftcmock stop <sessionId>");
|
|
||||||
};
|
|
||||||
|
|
||||||
if (argList.count() < 3)
|
|
||||||
{
|
|
||||||
usage();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool k = false;
|
|
||||||
switch (QStringList({QStringLiteral("start"), QStringLiteral("stop")}).indexOf(argList.at(1)))
|
|
||||||
{
|
|
||||||
case 0: {
|
|
||||||
if (argList.count() < 6)
|
|
||||||
{
|
|
||||||
usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int min = argList.at(3).toInt(&k);
|
|
||||||
if (!k || min < 0)
|
|
||||||
{
|
|
||||||
client->write("min must be a positive integer!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int max = argList.at(4).toInt(&k);
|
|
||||||
if (!k || max < 0)
|
|
||||||
{
|
|
||||||
client->write("max must be a positive integer!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int timers = argList.at(5).toInt(&k);
|
|
||||||
if (!k || timers < 1)
|
|
||||||
{
|
|
||||||
client->write("'timer count' must be a positive integer and greater than 0!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const int sessionId = argList.at(2).toInt(&k);
|
|
||||||
if (!k || sessionId < 0)
|
|
||||||
{
|
|
||||||
client->write("sessionId must be a positive integer!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit signalCommand(client, argList);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
QString result(QStringLiteral("Unknown command '%1'").arg(command));
|
|
||||||
client->write(result.toUtf8());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
client->write("\r\n> ");
|
|
||||||
});
|
|
||||||
|
|
||||||
QString versionString = QStringLiteral("%1.%2-%3 (rev: %4)")
|
|
||||||
.arg(QString::fromLatin1(ver_major), QString::fromLatin1(ver_minor),
|
|
||||||
QString::fromLatin1(ver_jenkins), QString::fromLatin1(ver_patch));
|
|
||||||
|
|
||||||
QString motd(QStringLiteral("\r\nOperatorApplication - Version %1").arg(versionString));
|
|
||||||
client->write(motd.toUtf8());
|
|
||||||
client->write("\r\n> ");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::showLogin()
|
|
||||||
{
|
|
||||||
|
|
||||||
QTimer::singleShot(0, this, &LtsAppManager::slotShowLogin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::slotShowLogin()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (m_login == nullptr)
|
|
||||||
{
|
|
||||||
m_login = new LtsLogin::LtsLogin;
|
|
||||||
connect(m_login, &LtsLogin::LtsLogin::signalLoginDone, this, [&] {
|
|
||||||
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
|
|
||||||
#endif
|
|
||||||
if (m_appList.isEmpty())
|
|
||||||
if (!startAppOrLetUserChoose(m_app, {}))
|
|
||||||
QTimer::singleShot(100, this, &LtsAppManager::slotLogout);
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(m_login, &LtsLogin::LtsLogin::signalLogoffDone, this, &LtsAppManager::signalLogoffDone);
|
|
||||||
|
|
||||||
connect(m_login, &LtsLogin::LtsLogin::signalLogoffDone, this, &LtsAppManager::slotShowLogin,
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
|
|
||||||
connect(m_login, &LtsLogin::LtsLogin::signalLogout, this, &LtsAppManager::slotLogout);
|
|
||||||
|
|
||||||
m_login->setLoginPlugin(m_loginPluginIid);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_login->login();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsAppManager::hasRightForApp(const LtsAppDescriptor::AppDescription& appDescription) const
|
|
||||||
{
|
|
||||||
const QSet<int>& acls = LtsSessionData::LtsSessionData::getInstance()->getOperatorRights();
|
|
||||||
for (int reqRight : appDescription.requiredAcls)
|
|
||||||
{
|
|
||||||
if (!acls.contains(reqRight))
|
|
||||||
{
|
|
||||||
QMessageBox::critical(
|
|
||||||
nullptr, tr("App Manager"),
|
|
||||||
tr("The minimal required operator rights are not met. Therefore, the app cannot be started."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::taskSwitch(QObject* _caller)
|
|
||||||
{
|
|
||||||
LtsSession::LtsSession* caller = qobject_cast<LtsSession::LtsSession*>(_caller);
|
|
||||||
|
|
||||||
if (caller == nullptr)
|
|
||||||
{
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVector<LtsSession::LtsSession*> sessions;
|
|
||||||
|
|
||||||
for (const LtsPluginManager::LtsPluginManager* app : m_appList)
|
|
||||||
sessions += app->sessions();
|
|
||||||
|
|
||||||
if (sessions.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
int sessionCount = sessions.count();
|
|
||||||
|
|
||||||
if (sessionCount < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto sessionIt = std::find_if(sessions.begin(), sessions.end(),
|
|
||||||
[caller](const LtsSession::LtsSession* session) { return (session == caller); });
|
|
||||||
|
|
||||||
if (sessionIt == sessions.end())
|
|
||||||
{
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto it = ++sessionIt;
|
|
||||||
|
|
||||||
int x = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
|
|
||||||
if (x > 100)
|
|
||||||
{
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
x++;
|
|
||||||
|
|
||||||
if (it == sessions.end())
|
|
||||||
{
|
|
||||||
|
|
||||||
if (sessions.begin() == sessionIt)
|
|
||||||
{
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
it = sessions.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsSession::LtsSession* session = *it;
|
|
||||||
|
|
||||||
QWidget* blw = session->baseLayoutWidget();
|
|
||||||
|
|
||||||
if (blw == nullptr || session->isForeverInvisible() || session == caller)
|
|
||||||
{
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
caller->baseLayoutWidget()->hide();
|
|
||||||
blw->showFullScreen();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (++it != sessionIt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::hideAllOtherBLWs(QObject* _caller)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!LtsSessionData::LtsSessionData::getInstance()->isTablet())
|
|
||||||
return;
|
|
||||||
|
|
||||||
LtsSession::LtsSession* caller = qobject_cast<LtsSession::LtsSession*>(_caller);
|
|
||||||
|
|
||||||
QVector<LtsSession::LtsSession*> sessions;
|
|
||||||
for (const LtsPluginManager::LtsPluginManager* app : m_appList)
|
|
||||||
sessions += app->sessions();
|
|
||||||
|
|
||||||
for (LtsSession::LtsSession* session : sessions)
|
|
||||||
{
|
|
||||||
|
|
||||||
QWidget* blw = session->baseLayoutWidget();
|
|
||||||
|
|
||||||
if (blw != nullptr && !session->isForeverInvisible() && session != caller)
|
|
||||||
{
|
|
||||||
|
|
||||||
blw->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (caller != nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (LtsSession::LtsSession* session : sessions)
|
|
||||||
{
|
|
||||||
|
|
||||||
QWidget* blw = session->baseLayoutWidget();
|
|
||||||
|
|
||||||
if (blw == nullptr || session->isForeverInvisible())
|
|
||||||
{
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
blw->showFullScreen();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsAppManager::startAppOrLetUserChoose(LtsAppDescriptor::App appId,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams, bool force)
|
|
||||||
{
|
|
||||||
return startAppOrLetUserChoose(getApp(appId), connParams, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsAppManager::startAppOrLetUserChoose(const LtsAppDescriptor::AppDescription& appDescription,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams, bool force)
|
|
||||||
{
|
|
||||||
if (!appDescription.active && !force)
|
|
||||||
{
|
|
||||||
|
|
||||||
AppChooser* appChooser = new AppChooser();
|
|
||||||
appChooser->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
|
|
||||||
connect(appChooser, &AppChooser::signalLogout, this, &LtsAppManager::slotLogout);
|
|
||||||
|
|
||||||
connect(
|
|
||||||
appChooser, &AppChooser::signalAppSelected, this,
|
|
||||||
[this, connParams](LtsAppDescriptor::App appId) {
|
|
||||||
if (createApp(appId, connParams) == nullptr)
|
|
||||||
QTimer::singleShot(100, this, &LtsAppManager::slotLogout);
|
|
||||||
},
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
|
|
||||||
appChooser->show();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (createApp(appDescription, connParams, {}, false, force) == nullptr)
|
|
||||||
{
|
|
||||||
QMessageBox::critical(nullptr, tr("App Manager"), tr("Could not create app.\nPlease contact support."));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsPluginManager::LtsPluginManager* LtsAppManager::createApp(LtsAppDescriptor::App appId,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams,
|
|
||||||
const QString& workspaceId, bool hidden, bool force)
|
|
||||||
{
|
|
||||||
return createApp(getApp(appId), connParams, workspaceId, hidden, force);
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsPluginManager::LtsPluginManager* LtsAppManager::createApp(const LtsAppDescriptor::AppDescription& appDescription,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams,
|
|
||||||
const QString& workspaceId, bool hidden, bool force)
|
|
||||||
{
|
|
||||||
if (!appDescription.isValid())
|
|
||||||
{
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasRightForApp(appDescription) && !force)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
const bool bDesiredAppHasSituationMapInstance =
|
|
||||||
LtsPluginManager::LtsPluginManager::hasSituationMapInstance(appDescription, true);
|
|
||||||
if (bDesiredAppHasSituationMapInstance)
|
|
||||||
{
|
|
||||||
const int curInstances = getNumberOfSituationMapInstances();
|
|
||||||
|
|
||||||
if (curInstances >= 3 && !force)
|
|
||||||
{
|
|
||||||
if (QMessageBox::Yes !=
|
|
||||||
QMessageBox::question(nullptr, tr("App Manager"),
|
|
||||||
tr("Are you sure you want to launch another resource-intensive app? <br />"
|
|
||||||
"Please note that you are currently running three apps containing the "
|
|
||||||
"resource-intensive map componment. <br />"
|
|
||||||
"It may lead to potential performance issues.")))
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* pluginManager = new LtsPluginManager::LtsPluginManager();
|
|
||||||
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalQuit, this, &LtsAppManager::slotQuit);
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalSoftQuit, this, &LtsAppManager::slotSoftQuit);
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalLogout, this, &LtsAppManager::slotLogout);
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalInitializationFinished, this,
|
|
||||||
&LtsAppManager::signalInitializationFinished);
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::destroyed, this, &LtsAppManager::slotAppDestroyed);
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::hideAllOtherBLWs, this,
|
|
||||||
&LtsAppManager::hideAllOtherBLWs);
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::taskSwitch, this, &LtsAppManager::taskSwitch);
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalStillAlive, this, [this]() {
|
|
||||||
auto* app = qobject_cast<LtsPluginManager::LtsPluginManager*>(sender());
|
|
||||||
if (!app)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (auto i = m_appList.constBegin(); i != m_appList.constEnd(); ++i)
|
|
||||||
{
|
|
||||||
if (*i == app)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!pluginManager->startApp(appDescription, false, connParams, workspaceId, hidden))
|
|
||||||
{
|
|
||||||
QMessageBox::critical(
|
|
||||||
nullptr, tr("App Manager"),
|
|
||||||
tr("The Plugin Manager failed to start the app due to plugin errors.\nPlease contact support."));
|
|
||||||
pluginManager->deleteLater();
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_appList.append(pluginManager);
|
|
||||||
|
|
||||||
return pluginManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsAppManager::hasApp(LtsAppDescriptor::App appId) const
|
|
||||||
{
|
|
||||||
return (std::find_if(m_availableApps.constBegin(), m_availableApps.constEnd(),
|
|
||||||
[appId](const LtsAppDescriptor::AppDescription& app) {
|
|
||||||
bool ret = (app.id == appId);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}) != m_availableApps.constEnd());
|
|
||||||
}
|
|
||||||
|
|
||||||
int LtsAppManager::getNumberOfSituationMapInstances() const
|
|
||||||
{
|
|
||||||
int numberOfSituationMapInstances = 0;
|
|
||||||
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(m_appList))
|
|
||||||
{
|
|
||||||
if (!app)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (app->hasSituationMapInstance())
|
|
||||||
++numberOfSituationMapInstances;
|
|
||||||
}
|
|
||||||
|
|
||||||
return numberOfSituationMapInstances;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescription LtsAppManager::getApp(LtsAppDescriptor::App appId) const
|
|
||||||
{
|
|
||||||
for (const LtsAppDescriptor::AppDescription& app : m_availableApps)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (app.id == appId)
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LtsAppDescriptor::AppDescription();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::setMainApp(LtsAppDescriptor::App appId)
|
|
||||||
{
|
|
||||||
m_app = getApp(appId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::saveState()
|
|
||||||
{
|
|
||||||
|
|
||||||
if (LtsSessionData::LtsSessionData::getInstance()->getOperatorId() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QStringList unsavedWorkspaces =
|
|
||||||
LtsUtils::OperatorSettings::getInstance()->identifiers(QStringLiteral("UnsavedWorkspace"));
|
|
||||||
for (auto i = unsavedWorkspaces.constBegin(); i != unsavedWorkspaces.constEnd(); ++i)
|
|
||||||
LtsUtils::OperatorSettings::getInstance()->removeValue(QStringLiteral("UnsavedWorkspace"), *i);
|
|
||||||
|
|
||||||
QStringList unsavedFilterPreset =
|
|
||||||
LtsUtils::OperatorSettings::getInstance()->identifiers(QStringLiteral("UnsavedFilterPreset"));
|
|
||||||
for (auto i = unsavedFilterPreset.constBegin(); i != unsavedFilterPreset.constEnd(); ++i)
|
|
||||||
LtsUtils::OperatorSettings::getInstance()->removeValue(QStringLiteral("UnsavedFilterPreset"), *i);
|
|
||||||
|
|
||||||
QJsonArray root;
|
|
||||||
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(m_appList))
|
|
||||||
{
|
|
||||||
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
|
|
||||||
|
|
||||||
const auto appId = app->appDescription().id;
|
|
||||||
|
|
||||||
if (appId == LtsAppDescriptor::App::Login || sessions.count() < 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QJsonObject appState;
|
|
||||||
appState[QStringLiteral("id")] = static_cast<int>(appId);
|
|
||||||
|
|
||||||
QJsonArray sessionStates;
|
|
||||||
|
|
||||||
for (LtsSession::LtsSession* session : sessions)
|
|
||||||
{
|
|
||||||
if (session->baseLayout() != nullptr && session->baseLayout()->isSecondaryWidget())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
QJsonObject sessionState;
|
|
||||||
|
|
||||||
int screenId = session->screenId();
|
|
||||||
|
|
||||||
int screenContainerId = session->screenContainerId();
|
|
||||||
|
|
||||||
sessionState[QStringLiteral("screenId")] = screenId;
|
|
||||||
sessionState[QStringLiteral("screenContainerId")] = screenContainerId;
|
|
||||||
sessionState[QStringLiteral("exerciseId")] = session->exerciseId();
|
|
||||||
sessionState[QStringLiteral("partitionId")] = session->partitionId();
|
|
||||||
sessionState[QStringLiteral("partitionType")] = int(session->partitionType());
|
|
||||||
sessionState[QStringLiteral("savegame")] = session->getSavegame();
|
|
||||||
|
|
||||||
const QString newId(QUuid::createUuid().toString());
|
|
||||||
sessionState[QStringLiteral("workspaceId")] = newId;
|
|
||||||
|
|
||||||
std::shared_ptr<OperatorManagement::ForeignSettingsGuiInterface> ifcOpm;
|
|
||||||
if (session->getForeignGuiInterface<OperatorManagement::ForeignSettingsGuiInterface>(ifcOpm))
|
|
||||||
{
|
|
||||||
|
|
||||||
ifcOpm->callWorkspaceSaveUnsaved(newId);
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionStates.append(sessionState);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sessionStates.isEmpty())
|
|
||||||
{
|
|
||||||
appState[QStringLiteral("sessions")] = sessionStates;
|
|
||||||
root.append(appState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonDocument doc(root);
|
|
||||||
|
|
||||||
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("app"), QStringLiteral("LastAppStates"),
|
|
||||||
doc.toJson(QJsonDocument::Compact));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::slotLogout()
|
|
||||||
{
|
|
||||||
for (LtsPluginManager::LtsPluginManager* app : std::as_const(m_appList))
|
|
||||||
{
|
|
||||||
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
|
|
||||||
for (LtsSession::LtsSession* session : sessions)
|
|
||||||
{
|
|
||||||
if (session->notifyUnsavedChanges() == false)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
saveState();
|
|
||||||
|
|
||||||
const QVector<LtsPluginManager::LtsPluginManager*> apps = m_appList;
|
|
||||||
|
|
||||||
if (apps.isEmpty() && m_login != nullptr)
|
|
||||||
m_login->logoff();
|
|
||||||
|
|
||||||
for (LtsPluginManager::LtsPluginManager* app : apps)
|
|
||||||
app->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::slotAppDestroyed()
|
|
||||||
{
|
|
||||||
LtsPluginManager::LtsPluginManager* app = static_cast<LtsPluginManager::LtsPluginManager*>(sender());
|
|
||||||
|
|
||||||
m_appList.removeOne(app);
|
|
||||||
|
|
||||||
if (m_appList.isEmpty() && m_login != nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
m_login->logoff();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::slotQuit()
|
|
||||||
{
|
|
||||||
|
|
||||||
QObject* object = sender();
|
|
||||||
|
|
||||||
if (!object)
|
|
||||||
qCritical()
|
|
||||||
<< "ERROR: LtsAppManager: slot called without object - so it cannot be deleted from the app assignments!";
|
|
||||||
|
|
||||||
LtsPluginManager::LtsPluginManager* app = qobject_cast<LtsPluginManager::LtsPluginManager*>(object);
|
|
||||||
|
|
||||||
if (app == nullptr)
|
|
||||||
{
|
|
||||||
qCritical() << "ERROR: LtsAppManager: quit requested for invalid app";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_appList.count() == 1)
|
|
||||||
{
|
|
||||||
m_appList.removeAll(app);
|
|
||||||
saveState();
|
|
||||||
}
|
|
||||||
|
|
||||||
app->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsAppManager::slotSoftQuit()
|
|
||||||
{
|
|
||||||
|
|
||||||
QObject* object = sender();
|
|
||||||
|
|
||||||
LtsPluginManager::LtsPluginManager* app = qobject_cast<LtsPluginManager::LtsPluginManager*>(object);
|
|
||||||
|
|
||||||
if (app == nullptr)
|
|
||||||
{
|
|
||||||
qCritical() << "ERROR: LtsAppManager: quit requested for invalid app";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
app->_softQuit();
|
|
||||||
|
|
||||||
if (m_appList.count() == 1)
|
|
||||||
{
|
|
||||||
m_appList.removeAll(app);
|
|
||||||
saveState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsAppManager::otherSessionsResponsibility(LtsSession::LtsSession* thisSession,
|
|
||||||
const QVector<LtsAppDescriptor::App>& requiredAppTypes,
|
|
||||||
const QVector<IDL::PartitionType>& requiredPartitionTypes,
|
|
||||||
const QString& menuGroup, const QString& identifier,
|
|
||||||
LtsWidgets::LayoutArea area)
|
|
||||||
{
|
|
||||||
const QVector<LtsPluginManager::LtsPluginManager*> apps = LtsAppManager::LtsAppManager::getInstance()->getAppList();
|
|
||||||
QVector<LtsPluginManager::LtsPluginManager*> worthyApps;
|
|
||||||
|
|
||||||
for (LtsPluginManager::LtsPluginManager* app : apps)
|
|
||||||
{
|
|
||||||
if (!requiredAppTypes.contains(static_cast<LtsAppDescriptor::App>(app->appDescription().id)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
worthyApps.append(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(worthyApps))
|
|
||||||
{
|
|
||||||
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
|
|
||||||
for (const LtsSession::LtsSession* session : sessions)
|
|
||||||
{
|
|
||||||
if (session->widgetExists(menuGroup, identifier, area))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsMultiMonitor::LtsMultiMonitor* mm = LtsMultiMonitor::LtsMultiMonitor::getInstance();
|
|
||||||
LtsMultiMonitor::LtsScreenBase* mainScreen = mm->mainScreen();
|
|
||||||
|
|
||||||
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(worthyApps))
|
|
||||||
{
|
|
||||||
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
|
|
||||||
for (LtsSession::LtsSession* session : sessions)
|
|
||||||
{
|
|
||||||
if (session != thisSession && mm->widgetsScreen(session->baseLayoutWidget()) == mainScreen &&
|
|
||||||
requiredPartitionTypes.contains(session->partitionType()))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
|
||||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
||||||
#include <LtsSession/lts_session.h>
|
|
||||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
|
||||||
#include <LtsWidgets/lts_dialog.h>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QVector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#ifndef LTSAPPMANAGER_EXPORT
|
|
||||||
#ifdef BUILD_STATIC_LIBRARIES
|
|
||||||
#define LTSAPPMANAGER_EXPORT
|
|
||||||
#else
|
|
||||||
#if defined(MAKE_LTSAPPMANAGER_LIB)
|
|
||||||
#define LTSAPPMANAGER_EXPORT Q_DECL_EXPORT
|
|
||||||
#else
|
|
||||||
#define LTSAPPMANAGER_EXPORT Q_DECL_IMPORT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace LtsPluginManager
|
|
||||||
{
|
|
||||||
class LtsPluginManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsLogin
|
|
||||||
{
|
|
||||||
class LtsLogin;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsSession
|
|
||||||
{
|
|
||||||
class LtsSession;
|
|
||||||
struct DdsConnectionParams;
|
|
||||||
} // namespace LtsSession
|
|
||||||
|
|
||||||
namespace DeveloperTools
|
|
||||||
{
|
|
||||||
class DevDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
class QTcpSocket;
|
|
||||||
|
|
||||||
namespace LtsAppManager
|
|
||||||
{
|
|
||||||
|
|
||||||
class LTSAPPMANAGER_EXPORT LtsAppManager : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
static LtsAppManager* getInstance();
|
|
||||||
|
|
||||||
void showLogin();
|
|
||||||
|
|
||||||
LtsPluginManager::LtsPluginManager* createApp(LtsAppDescriptor::App appId,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams,
|
|
||||||
const QString& workspaceId = QString(), bool hidden = false,
|
|
||||||
bool force = false);
|
|
||||||
bool startAppOrLetUserChoose(LtsAppDescriptor::App appId, const LtsSession::DdsConnectionParams& connParams,
|
|
||||||
bool force = false);
|
|
||||||
|
|
||||||
void setLoginPluginIid(const QString& loginPluginIid)
|
|
||||||
{
|
|
||||||
m_loginPluginIid = loginPluginIid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setMainApp(LtsAppDescriptor::App appId = LtsAppDescriptor::App::Login);
|
|
||||||
|
|
||||||
QVector<LtsPluginManager::LtsPluginManager*> getAppList() const
|
|
||||||
{
|
|
||||||
return m_appList;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescriptionVector getAvailableApps() const
|
|
||||||
{
|
|
||||||
return m_availableApps;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAvailableApps(const LtsAppDescriptor::AppDescriptionVector& availableApps);
|
|
||||||
bool hasRightForApp(const LtsAppDescriptor::AppDescription& appDescription) const;
|
|
||||||
LtsAppDescriptor::AppDescription getApp(LtsAppDescriptor::App appId) const;
|
|
||||||
bool hasApp(LtsAppDescriptor::App appId) const;
|
|
||||||
int getNumberOfSituationMapInstances() const;
|
|
||||||
void debugSendMessage(const QString& msg);
|
|
||||||
|
|
||||||
bool otherSessionsResponsibility(LtsSession::LtsSession* thisSession,
|
|
||||||
const QVector<LtsAppDescriptor::App>& requiredAppTypes,
|
|
||||||
const QVector<IDL::PartitionType>& requiredPartitionTypes,
|
|
||||||
const QString& menuGroup, const QString& identifier, LtsWidgets::LayoutArea area);
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend struct LtsAppManagerHandler;
|
|
||||||
friend class DeveloperTools::DevDialog;
|
|
||||||
|
|
||||||
LtsAppManager();
|
|
||||||
~LtsAppManager();
|
|
||||||
|
|
||||||
bool startAppOrLetUserChoose(const LtsAppDescriptor::AppDescription& appDescription,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams, bool force = false);
|
|
||||||
LtsPluginManager::LtsPluginManager* createApp(const LtsAppDescriptor::AppDescription& appDescription,
|
|
||||||
const LtsSession::DdsConnectionParams& connParams,
|
|
||||||
const QString& workspaceId = QString(), bool hidden = false,
|
|
||||||
bool force = false);
|
|
||||||
void saveState();
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescriptionVector m_availableApps;
|
|
||||||
QVector<LtsPluginManager::LtsPluginManager*> m_appList;
|
|
||||||
LtsLogin::LtsLogin* m_login;
|
|
||||||
LtsAppDescriptor::AppDescription m_app;
|
|
||||||
QString m_loginPluginIid;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void slotLogout();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void slotQuit();
|
|
||||||
void slotSoftQuit();
|
|
||||||
void slotShowLogin();
|
|
||||||
void slotAppDestroyed();
|
|
||||||
void slotStartDebugServer();
|
|
||||||
void hideAllOtherBLWs(QObject* _caller);
|
|
||||||
void taskSwitch(QObject* _caller);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void signalLoginDone();
|
|
||||||
void signalLogoffDone();
|
|
||||||
void signalShowLogin();
|
|
||||||
void signalInitializationFinished();
|
|
||||||
void signalCommand(QTcpSocket* client, const QStringList argList);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsAppManager
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
find_package(Botan2)
|
|
||||||
|
|
||||||
if (BOTAN_FOUND AND CMAKE_VERSION VERSION_GREATER 3.15.9) # botan doesn't use cmake, make it a cmake target | imported targets don't work correctly with 3.10
|
|
||||||
add_library(LtsBotan STATIC IMPORTED GLOBAL)
|
|
||||||
set_target_properties(LtsBotan PROPERTIES IMPORTED_LOCATION ${BOTAN_LIBRARIES})
|
|
||||||
set_target_properties(LtsBotan PROPERTIES INCLUDE_DIRECTORIES ${BOTAN_INCLUDE_DIRS})
|
|
||||||
target_compile_definitions(LtsBotan INTERFACE BOTAN_FOUND)
|
|
||||||
target_include_directories(LtsBotan SYSTEM INTERFACE ${BOTAN_INCLUDE_DIRS})
|
|
||||||
set(LTS_BOTAN LtsBotan)
|
|
||||||
|
|
||||||
message(STATUS "BOTAN_INCLUDE_DIRS = ${BOTAN_INCLUDE_DIRS}, BOTAN_LIBRARIES = ${BOTAN_LIBRARIES}, LTS_BOTAN = ${LTS_BOTAN}")
|
|
||||||
endif()
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
# Make ${Qt6_Gui} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Gui)
|
|
||||||
set(Qt6_Gui ${Qt6_Gui})
|
|
||||||
else()
|
|
||||||
set(Qt6_Gui "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
NGL_ADD_LIBRARY2(WS SV HLA LtsElevation SHARED
|
|
||||||
lts_elevation_manager.cpp
|
|
||||||
lts_elevation_manager.h
|
|
||||||
logger.cpp
|
|
||||||
logger.h
|
|
||||||
)
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsElevation
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
${CMAKE_SOURCE_DIR}/Lts/Common
|
|
||||||
${CMAKE_SOURCE_DIR}/Lts/Common/LtsUtils
|
|
||||||
${CMAKE_SOURCE_DIR}/Lts/Viewer/SituationMap
|
|
||||||
${CMAKE_SOURCE_DIR}/Lts/Viewer/SituationMap/Common
|
|
||||||
)
|
|
||||||
if(QT6_GUI_AVAILABLE)
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsElevation
|
|
||||||
PRIVATE
|
|
||||||
NGLLogger
|
|
||||||
## LtsSessionDataDds
|
|
||||||
PUBLIC
|
|
||||||
LtsUtilsCoreHeaderOnly
|
|
||||||
Qt6::Core
|
|
||||||
${Qt6_Gui}
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(BUILD_RTI)
|
|
||||||
# All ElevationMapManager / resource_path / exm-dtc usages live inside
|
|
||||||
# #ifdef BUILD_RTI in lts_elevation_manager.cpp (Qt5 dependencies restored).
|
|
||||||
target_link_libraries(LtsElevation PRIVATE
|
|
||||||
AsmDataPluginInterface
|
|
||||||
ExmDataPluginInterface
|
|
||||||
situationMapCommon
|
|
||||||
situationMapElevationMap
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
ADD_SUBDIRECTORY(UnitTest_Elevation)
|
|
||||||
-33
@@ -1,33 +0,0 @@
|
|||||||
# Make ${Qt6_Gui} optional
|
|
||||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Gui)
|
|
||||||
set(Qt6_Gui ${Qt6_Gui})
|
|
||||||
else()
|
|
||||||
set(Qt6_Gui "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# @RDE_HEADER@
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
#
|
|
||||||
|
|
||||||
# External dependency - missing: situationMapCommon, situationMapElevationMap
|
|
||||||
# Test disabled until external dependencies are available
|
|
||||||
# IF(BUILD_TESTING AND TARGET LtsElevation)
|
|
||||||
# ADD_EXECUTABLE(commenUnitTestElevation ${LinkedSources} ${UnitTestSources} )
|
|
||||||
#
|
|
||||||
# TARGET_LINK_LIBRARIES(commenUnitTestElevation
|
|
||||||
# NGLLogger
|
|
||||||
# nglcoreapplication
|
|
||||||
# LtsElevation
|
|
||||||
# LtsCoordTrans
|
|
||||||
# situationMapCommon
|
|
||||||
# situationMapElevationMap
|
|
||||||
# Qt6::Core
|
|
||||||
# ${Qt6_Gui}
|
|
||||||
# Qt6::Test)
|
|
||||||
#
|
|
||||||
# ADD_TEST(NAME commenUnitTestElevation COMMAND $<TARGET_FILE:commenUnitTestElevation>)
|
|
||||||
# ENDIF()
|
|
||||||
-198
@@ -1,198 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "elevation_unit_test.h"
|
|
||||||
|
|
||||||
#include <ElevationMap/elevation_map_manager.h>
|
|
||||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
#include <QtTest/QTest>
|
|
||||||
#include <nglapplication/nglcoreapplication.h>
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(LtsUtils::QPoint3D);
|
|
||||||
Q_DECLARE_METATYPE(LtsElevation::LineOfSight);
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
static const int s_id{4711};
|
|
||||||
static LtsElevation::LtsElevationManager* s_eleMgr{nullptr};
|
|
||||||
|
|
||||||
class MyLtsElevationManagerBootstrap : public LtsElevation::LtsElevationManager
|
|
||||||
{
|
|
||||||
using BaseClass = LtsElevation::LtsElevationManager;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static LtsElevationManager* createInstanceUnitTest(int id, const QStringList& filePaths_rough_to_fine)
|
|
||||||
{
|
|
||||||
return BaseClass::createInstanceUnitTest(id, filePaths_rough_to_fine);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UnitTestElevation::UnitTestElevation()
|
|
||||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("UnitTestElevation"))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::initTestCase()
|
|
||||||
{
|
|
||||||
|
|
||||||
QString filePath(QStringLiteral("/usr/share/arcgis/resources/elevation/Altmark_dt1.tif"));
|
|
||||||
|
|
||||||
s_eleMgr = MyLtsElevationManagerBootstrap::createInstanceUnitTest(s_id, {filePath});
|
|
||||||
|
|
||||||
const bool bIsValid = s_eleMgr->isValid();
|
|
||||||
std::cerr << "myBootstrapMgr->isValid() 1 = " << bIsValid << std::endl;
|
|
||||||
|
|
||||||
{
|
|
||||||
s_eleMgr->waitForInitialization();
|
|
||||||
const bool bIsValid = s_eleMgr->isValid();
|
|
||||||
std::cerr << "myBootstrapMgr->isValid() 2 = " << bIsValid << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::init()
|
|
||||||
{
|
|
||||||
QVERIFY2(s_eleMgr, "static LtsElevationManager does not exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::test_elevation_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QPointF>("lonLat");
|
|
||||||
QTest::addColumn<double>("elevationRef");
|
|
||||||
|
|
||||||
QTest::newRow("elevation 1 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 70000 10000")).geographic() << 75.0;
|
|
||||||
QTest::newRow("elevation 2 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 72000 13000")).geographic() << 80.0;
|
|
||||||
|
|
||||||
QTest::newRow("elevation 3 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 76925 18625")).geographic() << 92.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::test_elevation()
|
|
||||||
{
|
|
||||||
QFETCH(QPointF, lonLat);
|
|
||||||
QFETCH(double, elevationRef);
|
|
||||||
|
|
||||||
double elevation = s_eleMgr->elevation(lonLat.x(), lonLat.y());
|
|
||||||
|
|
||||||
QVERIFY2(qFuzzyCompare(elevationRef, elevation), " got wrong elevation result");
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::test_elevation_isCovered()
|
|
||||||
{
|
|
||||||
const QPointF& lonLat1 = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 70000 10000")).geographic();
|
|
||||||
const QPointF& lonLat2 = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U MD 60000 10000")).geographic();
|
|
||||||
|
|
||||||
const double defaultElevationValue = -123;
|
|
||||||
{
|
|
||||||
bool bIsCovered = false;
|
|
||||||
s_eleMgr->elevation(lonLat1.x(), lonLat1.y(), defaultElevationValue, &bIsCovered);
|
|
||||||
QVERIFY2(bIsCovered, " error on bIsCovered");
|
|
||||||
}
|
|
||||||
{
|
|
||||||
bool bIsCovered = true;
|
|
||||||
s_eleMgr->elevation(lonLat2.x(), lonLat2.y(), defaultElevationValue, &bIsCovered);
|
|
||||||
QVERIFY2(!bIsCovered, " error on bIsCovered");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::test_elevation_defaultValue()
|
|
||||||
{
|
|
||||||
const QPointF& lonLat = LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 60000 10000")).geographic();
|
|
||||||
|
|
||||||
double elevation = s_eleMgr->elevation(lonLat.x(), lonLat.y());
|
|
||||||
QVERIFY2(qFuzzyCompare(elevation, std::numeric_limits<double>::min()), " error on defaultValue");
|
|
||||||
|
|
||||||
{
|
|
||||||
const double defaultValue = 100;
|
|
||||||
elevation = s_eleMgr->elevation(lonLat.x(), lonLat.y(), defaultValue);
|
|
||||||
QVERIFY2(qFuzzyCompare(elevation, defaultValue), " error on defaultValue");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const double defaultValue = std::numeric_limits<double>::max();
|
|
||||||
elevation = s_eleMgr->elevation(lonLat.x(), lonLat.y(), defaultValue);
|
|
||||||
QVERIFY2(qFuzzyCompare(elevation, defaultValue), " error on defaultValue");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::test_lineOfSightCalculation_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QPointF>("startGeo2D");
|
|
||||||
QTest::addColumn<double>("startObjH");
|
|
||||||
QTest::addColumn<QPointF>("endGeo2D");
|
|
||||||
QTest::addColumn<double>("endObjH");
|
|
||||||
QTest::addColumn<LtsElevation::LineOfSight>("expectedResult");
|
|
||||||
|
|
||||||
QTest::newRow("losDataset 1 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 60000 10000")).geographic() << 1.0
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 60000 60000")).geographic() << 1.0
|
|
||||||
<< LtsElevation::LineOfSight::LOS_ERROR;
|
|
||||||
|
|
||||||
QTest::newRow("losDataset 2 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77200 17600")).geographic() << 1.0
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77600 17600")).geographic() << 1.0
|
|
||||||
<< LtsElevation::LineOfSight::LOS_INVISIBLE;
|
|
||||||
|
|
||||||
QTest::newRow("losDataset 3 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77200 17600")).geographic() << 20.0
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77600 17600")).geographic() << 20.0
|
|
||||||
<< LtsElevation::LineOfSight::LOS_VISIBLE;
|
|
||||||
|
|
||||||
QTest::newRow("losDataset 4 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77200 17600")).geographic() << -1.0
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77600 17600")).geographic() << 1.0
|
|
||||||
<< LtsElevation::LineOfSight::LOS_ERROR;
|
|
||||||
QTest::newRow("losDataset 5 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77200 17600")).geographic() << 1.0
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77600 17600")).geographic() << -1.0
|
|
||||||
<< LtsElevation::LineOfSight::LOS_ERROR;
|
|
||||||
QTest::newRow("losDataset 6 ")
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77200 17600")).geographic() << 0.0
|
|
||||||
<< LtsCoordTrans::UtmCoordinate::fromMgrs(QStringLiteral("32U PD 77600 17600")).geographic() << 0.0
|
|
||||||
<< LtsElevation::LineOfSight::LOS_INVISIBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UnitTestElevation::test_lineOfSightCalculation()
|
|
||||||
{
|
|
||||||
QFETCH(QPointF, startGeo2D);
|
|
||||||
QFETCH(double, startObjH);
|
|
||||||
QFETCH(QPointF, endGeo2D);
|
|
||||||
QFETCH(double, endObjH);
|
|
||||||
QFETCH(LtsElevation::LineOfSight, expectedResult);
|
|
||||||
|
|
||||||
LtsUtils::QPoint3D start3D = LtsUtils::QPoint3D::fromQPointF(startGeo2D);
|
|
||||||
start3D.rz() = startObjH;
|
|
||||||
start3D.rz() += s_eleMgr->elevation(start3D.x(), start3D.y());
|
|
||||||
|
|
||||||
LtsUtils::QPoint3D end3D = LtsUtils::QPoint3D::fromQPointF(endGeo2D);
|
|
||||||
end3D.rz() = endObjH;
|
|
||||||
end3D.rz() += s_eleMgr->elevation(end3D.x(), end3D.y());
|
|
||||||
|
|
||||||
LtsElevation::LineOfSight los = s_eleMgr->lineOfSightCalculation(start3D, end3D);
|
|
||||||
NOTICE_LOG(m_logger) << "los = " << los;
|
|
||||||
|
|
||||||
{
|
|
||||||
LtsElevation::LineOfSight los2 = s_eleMgr->lineOfSightCalculation(startGeo2D, startObjH, endGeo2D, endObjH);
|
|
||||||
QVERIFY2(los == los2, " got different lineOfSightCalculation result");
|
|
||||||
}
|
|
||||||
|
|
||||||
QVERIFY2(los == expectedResult, " got lineOfSightCalculation result");
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
NGLCoreApplication app(argc, argv);
|
|
||||||
app.createLogger("UnitTestElevation", "log4cxxElevationUnitTest.props");
|
|
||||||
|
|
||||||
UnitTestElevation tc;
|
|
||||||
|
|
||||||
int ret = QTest::qExec(&tc, argc, argv);
|
|
||||||
|
|
||||||
if (s_eleMgr)
|
|
||||||
{
|
|
||||||
s_eleMgr->cleanupAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
-38
@@ -1,38 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ElevationMap/elevation_map_manager.h>
|
|
||||||
#include <LtsElevation/lts_elevation_manager.h>
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtTest/QTest>
|
|
||||||
|
|
||||||
using LOGGER_T = NGL::INGLLogger&;
|
|
||||||
|
|
||||||
class UnitTestElevation : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
UnitTestElevation();
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
|
|
||||||
void initTestCase();
|
|
||||||
|
|
||||||
void init();
|
|
||||||
|
|
||||||
void test_elevation_data();
|
|
||||||
void test_elevation();
|
|
||||||
|
|
||||||
void test_elevation_isCovered();
|
|
||||||
void test_elevation_defaultValue();
|
|
||||||
|
|
||||||
void test_lineOfSightCalculation_data();
|
|
||||||
void test_lineOfSightCalculation();
|
|
||||||
|
|
||||||
private:
|
|
||||||
NGL::INGLLogger& m_logger;
|
|
||||||
};
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
|
|
||||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
||||||
|
|
||||||
namespace LtsElevation
|
|
||||||
{
|
|
||||||
|
|
||||||
LOGGER_T getLogger(const char* name)
|
|
||||||
{
|
|
||||||
static const char ns[] = "Lts.Elevation.";
|
|
||||||
std::string loggerName;
|
|
||||||
const size_t len = strlen(name);
|
|
||||||
loggerName.reserve(sizeof(ns) + len);
|
|
||||||
loggerName.append(ns, sizeof(ns) - 1);
|
|
||||||
loggerName.append(name, len);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger(loggerName);
|
|
||||||
}
|
|
||||||
catch (const std::exception& ex)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsElevation
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <NGLLogger/INGLLogger.h>
|
|
||||||
|
|
||||||
namespace LtsElevation
|
|
||||||
{
|
|
||||||
typedef NGL::INGLLogger& LOGGER_T;
|
|
||||||
|
|
||||||
LOGGER_T getLogger(const char* name);
|
|
||||||
|
|
||||||
inline LOGGER_T getLogger(const QString& loggerName)
|
|
||||||
{
|
|
||||||
return getLogger(loggerName.toUtf8().constData());
|
|
||||||
}
|
|
||||||
} // namespace LtsElevation
|
|
||||||
@@ -1,587 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_elevation_manager.h"
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
#include <AssetManagement/asm_data_plugin_interface.h>
|
|
||||||
#include <ExerciseManagement/exm_data_plugin_interface.h>
|
|
||||||
#include <Viewer/SituationMap/ElevationMap/elevation_map_manager.h>
|
|
||||||
#include <Viewer/SituationMap/Common/resource_path.h>
|
|
||||||
|
|
||||||
#include <QDir>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QUrl>
|
|
||||||
|
|
||||||
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_UNDEFINED ==
|
|
||||||
(int)LtsElevation::LineOfSight::LOS_UNDEFINED,
|
|
||||||
"LineOfSight mismatch");
|
|
||||||
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_ERROR ==
|
|
||||||
(int)LtsElevation::LineOfSight::LOS_ERROR,
|
|
||||||
"LineOfSight mismatch");
|
|
||||||
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_VISIBLE ==
|
|
||||||
(int)LtsElevation::LineOfSight::LOS_VISIBLE,
|
|
||||||
"LineOfSight mismatch");
|
|
||||||
static_assert((int)SituationMap::ElevationMapManager::LineOfSight::LOS_INVISIBLE ==
|
|
||||||
(int)LtsElevation::LineOfSight::LOS_INVISIBLE,
|
|
||||||
"LineOfSight mismatch");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace LtsElevation
|
|
||||||
{
|
|
||||||
class LtsElevationManager;
|
|
||||||
|
|
||||||
using LtsElevatioMgrMapTrainingAreaId = QMap<int, LTS_ELEVATION_MANAGER_TYPE>;
|
|
||||||
|
|
||||||
static LtsElevatioMgrMapTrainingAreaId& ltsElevatioMgrMapTrainingAreaId()
|
|
||||||
{
|
|
||||||
static LtsElevatioMgrMapTrainingAreaId s_ltsElevatioMgrMapTrainingAreaId;
|
|
||||||
return s_ltsElevatioMgrMapTrainingAreaId;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cleanupLtsElevatioMgrMapTrainingAreaId()
|
|
||||||
{
|
|
||||||
qDeleteAll(ltsElevatioMgrMapTrainingAreaId());
|
|
||||||
ltsElevatioMgrMapTrainingAreaId().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsElevatioMgrMapTrainingAreaId& getLtsElevationMgrMapTrainingAreaId()
|
|
||||||
{
|
|
||||||
if (ltsElevatioMgrMapTrainingAreaId().isEmpty())
|
|
||||||
qAddPostRoutine(cleanupLtsElevatioMgrMapTrainingAreaId);
|
|
||||||
|
|
||||||
return ltsElevatioMgrMapTrainingAreaId();
|
|
||||||
}
|
|
||||||
|
|
||||||
static long s_counter{0};
|
|
||||||
|
|
||||||
class LtsElevationManager::Private
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Private() = default;
|
|
||||||
|
|
||||||
~Private()
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
delete m_elevationManager;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
std::shared_ptr<AssetManagement::Interface::Dtc> m_asmDtc;
|
|
||||||
SituationMap::ElevationMapManager* m_elevationManager{nullptr};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QStringList m_filePaths_rough_to_fine;
|
|
||||||
};
|
|
||||||
|
|
||||||
LtsElevationManager::LtsElevationManager()
|
|
||||||
: QObject(nullptr)
|
|
||||||
, d(new Private)
|
|
||||||
, m_logger(getLogger("LtsElevationManager"))
|
|
||||||
{
|
|
||||||
++s_counter;
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START, s_counter=" << s_counter << " this=" << this;
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END, s_counter=" << s_counter << " this=" << this;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsElevationManager::~LtsElevationManager()
|
|
||||||
{
|
|
||||||
--s_counter;
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START, s_counter=" << s_counter << " this=" << this;
|
|
||||||
delete d;
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END, s_counter=" << s_counter << " this=" << this;
|
|
||||||
}
|
|
||||||
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE
|
|
||||||
LtsElevationManager::createInstance(int exerciseId, const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc
|
|
||||||
#else
|
|
||||||
const std::shared_ptr<void>& asmDtc
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
LOGGER_T logger = getLogger("LtsElevationManager");
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " START, exerciseId=" << exerciseId;
|
|
||||||
|
|
||||||
if (exerciseId < 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " exerciseId invalid, exerciseId=" << exerciseId;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Qt5 logic restored (the qt6 port had dropped the exerciseId->trainingAreaId
|
|
||||||
// caching and always returned nullptr here).
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
int trainingAreaId = -1;
|
|
||||||
|
|
||||||
// remember for future calls
|
|
||||||
// (so createInstance should work WITHOUT dtcs)
|
|
||||||
// Idea: MainHandler: createInstance with exerciseId and valid dtcs
|
|
||||||
// Plugin or simular: createInstance with exerciseId and no dtcs
|
|
||||||
static QHash<int, int> s_exIdToTaIdStore;
|
|
||||||
|
|
||||||
const auto exTaIt = s_exIdToTaIdStore.find(exerciseId);
|
|
||||||
if (exTaIt != s_exIdToTaIdStore.end())
|
|
||||||
{
|
|
||||||
// CASE 1:
|
|
||||||
// already created:
|
|
||||||
trainingAreaId = *exTaIt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// CASE 2:
|
|
||||||
// ... or create on demand:
|
|
||||||
if (!exmDtc || !asmDtc)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " no dtcs for exerciseId=" << exerciseId
|
|
||||||
<< ", asmDtc=" << asmDtc
|
|
||||||
<< ", exmDtc=" << exmDtc;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// exId to taId
|
|
||||||
trainingAreaId = exerciseIdToTrainingAreaId(exerciseId, exmDtc);
|
|
||||||
if (trainingAreaId <= 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " Error getting trainingAreaId"
|
|
||||||
<< ", exerciseId=" << exerciseId
|
|
||||||
<< ", trainingAreaId=" << trainingAreaId;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store and remember:
|
|
||||||
s_exIdToTaIdStore[exerciseId] = trainingAreaId;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CASE 1: Following should work even with invalid asmDtc:
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE temp = createInstanceForTrainingAreaId(trainingAreaId, asmDtc);
|
|
||||||
if (!temp)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " Error on createInstanceForTrainingAreaId"
|
|
||||||
<< ", exerciseId=" << exerciseId
|
|
||||||
<< ", trainingAreaId=" << trainingAreaId;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add exmDtc
|
|
||||||
temp->initDDS(exmDtc, asmDtc);
|
|
||||||
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " END, exerciseId=" << exerciseId;
|
|
||||||
return temp;
|
|
||||||
#else
|
|
||||||
Q_UNUSED(exmDtc);
|
|
||||||
Q_UNUSED(asmDtc);
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, cannot create instance";
|
|
||||||
return nullptr;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::getInstance(int exerciseId)
|
|
||||||
{
|
|
||||||
return LtsElevationManager::createInstance(exerciseId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE
|
|
||||||
LtsElevationManager::createInstanceForTrainingAreaId(int trainingAreaId,
|
|
||||||
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc)
|
|
||||||
{
|
|
||||||
LOGGER_T logger = getLogger("LtsElevationManager");
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " START, trainingAreaId=" << trainingAreaId;
|
|
||||||
|
|
||||||
if (trainingAreaId < 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " trainingAreaId invalid, trainingAreaId=" << trainingAreaId;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsElevatioMgrMapTrainingAreaId& map = getLtsElevationMgrMapTrainingAreaId();
|
|
||||||
QMap<int, LTS_ELEVATION_MANAGER_TYPE>::iterator it = map.find(trainingAreaId);
|
|
||||||
|
|
||||||
if (it != map.end())
|
|
||||||
{
|
|
||||||
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances: " << map.size();
|
|
||||||
return it.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!asmDtc)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " no dtcs for trainingAreaId=" << trainingAreaId << ", asmDtc=" << asmDtc;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE temp = new LtsElevationManager();
|
|
||||||
|
|
||||||
temp->initDDS(nullptr, asmDtc);
|
|
||||||
|
|
||||||
const QStringList& filenames = temp->getFilenamesForTrainingArea(trainingAreaId);
|
|
||||||
if (filenames.isEmpty())
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " no filenames for trainingAreaId=" << trainingAreaId;
|
|
||||||
delete temp;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bInitFilenames = temp->init(filenames);
|
|
||||||
if (!bInitFilenames)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " bInitFilenames failed for trainingAreaId=" << trainingAreaId;
|
|
||||||
delete temp;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
map.insert(trainingAreaId, temp);
|
|
||||||
|
|
||||||
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances now: " << map.size();
|
|
||||||
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " END, trainingAreaId=" << trainingAreaId;
|
|
||||||
return map[trainingAreaId];
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE LtsElevationManager::createInstanceUnitTest(int id,
|
|
||||||
const QStringList& filePaths_rough_to_fine)
|
|
||||||
{
|
|
||||||
LOGGER_T logger = getLogger("LtsElevationManager");
|
|
||||||
|
|
||||||
LtsElevatioMgrMapTrainingAreaId& map = getLtsElevationMgrMapTrainingAreaId();
|
|
||||||
QMap<int, LTS_ELEVATION_MANAGER_TYPE>::iterator it = map.find(id);
|
|
||||||
|
|
||||||
if (it != map.end())
|
|
||||||
{
|
|
||||||
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances: " << map.size();
|
|
||||||
return it.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
LTS_ELEVATION_MANAGER_TYPE temp = new LtsElevationManager();
|
|
||||||
|
|
||||||
bool bInitFilenames = temp->init(filePaths_rough_to_fine);
|
|
||||||
if (!bInitFilenames)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " bInitFilenames failed for id=" << id;
|
|
||||||
delete temp;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
map.insert(id, temp);
|
|
||||||
|
|
||||||
DEBUG_LOG(logger) << " LtsElevationMgrMap contains instances now: " << map.size();
|
|
||||||
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " END, trainingAreaId=" << id;
|
|
||||||
return map[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsElevationManager::cleanupAll()
|
|
||||||
{
|
|
||||||
LOGGER_T logger = getLogger("LtsElevationManager");
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " START";
|
|
||||||
cleanupLtsElevatioMgrMapTrainingAreaId();
|
|
||||||
TRACE_LOG(logger) << Q_FUNC_INFO << " END";
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
void LtsElevationManager::initDDS(const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
|
|
||||||
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc)
|
|
||||||
{
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
|
|
||||||
|
|
||||||
d->m_exmDtc = exmDtc;
|
|
||||||
if (d->m_exmDtc)
|
|
||||||
d->m_exmDtc->waitForHistoricalDataExercise(1000);
|
|
||||||
|
|
||||||
d->m_asmDtc = asmDtc;
|
|
||||||
if (d->m_asmDtc)
|
|
||||||
d->m_asmDtc->waitForHistoricalDataTrainingArea(1000);
|
|
||||||
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void LtsElevationManager::initDDS(const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
|
|
||||||
const std::shared_ptr<void>& asmDtc)
|
|
||||||
{
|
|
||||||
Q_UNUSED(exmDtc);
|
|
||||||
Q_UNUSED(asmDtc);
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START (BUILD_RTI=OFF, no DDS init)";
|
|
||||||
|
|
||||||
// BUILD_RTI=OFF: No DDS initialization
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END";
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
QStringList LtsElevationManager::getFilenamesForExercise(int exerciseId)
|
|
||||||
{
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
|
|
||||||
|
|
||||||
if (!d->m_exmDtc || !d->m_asmDtc)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " no dtcs"
|
|
||||||
<< ", exerciseId=" << exerciseId;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
int trainingAreaId = exerciseIdToTrainingAreaId(exerciseId, d->m_exmDtc);
|
|
||||||
if (trainingAreaId <= 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " Error getting trainingAreaId"
|
|
||||||
<< ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList filePaths_rough_to_fine = getFilenamesForTrainingArea(trainingAreaId);
|
|
||||||
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO
|
|
||||||
<< " END, filePaths_rough_to_fine=" << filePaths_rough_to_fine.join(QStringLiteral(";"));
|
|
||||||
return filePaths_rough_to_fine;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList LtsElevationManager::getFilenamesForTrainingArea(int trainingAreaId)
|
|
||||||
{
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START";
|
|
||||||
|
|
||||||
if (!d->m_asmDtc)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " no dtcs"
|
|
||||||
<< ", trainingAreaId=" << trainingAreaId;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList filePaths_rough_to_fine;
|
|
||||||
{
|
|
||||||
d->m_asmDtc->waitForHistoricalDataTrainingArea(1000);
|
|
||||||
const AssetManagement::TrainingArea& ta = d->m_asmDtc->trainingArea(trainingAreaId);
|
|
||||||
if (ta.id != trainingAreaId)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " Error on s_asmDtc->trainingArea"
|
|
||||||
<< ", trainingAreaId=" << trainingAreaId;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
const std::vector<AssetManagement::MapDescription>& mdVec = ta.elevation;
|
|
||||||
filePaths_rough_to_fine.reserve(mdVec.size());
|
|
||||||
|
|
||||||
for (const AssetManagement::MapDescription& md : std::as_const(mdVec))
|
|
||||||
{
|
|
||||||
|
|
||||||
QUrl url(QString::fromStdString(md.url));
|
|
||||||
QString filePathAbs = url.toLocalFile();
|
|
||||||
if (QDir::isRelativePath(filePathAbs))
|
|
||||||
filePathAbs = SituationMap::getResourcePath() + QStringLiteral("/elevation/") + filePathAbs;
|
|
||||||
|
|
||||||
filePaths_rough_to_fine.append(filePathAbs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO
|
|
||||||
<< " END, filePaths_rough_to_fine=" << filePaths_rough_to_fine.join(QStringLiteral(";"));
|
|
||||||
return filePaths_rough_to_fine;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
QStringList LtsElevationManager::getFilenamesForExercise(int /*exerciseId*/)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, getFilenamesForExercise not available";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList LtsElevationManager::getFilenamesForTrainingArea(int /*trainingAreaId*/)
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, getFilenamesForTrainingArea not available";
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool LtsElevationManager::init(const QStringList& filePaths_rough_to_fine)
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
delete d->m_elevationManager;
|
|
||||||
|
|
||||||
d->m_elevationManager = new SituationMap::ElevationMapManager();
|
|
||||||
int cnt = d->m_elevationManager->init(filePaths_rough_to_fine);
|
|
||||||
|
|
||||||
if (cnt != filePaths_rough_to_fine.size())
|
|
||||||
{
|
|
||||||
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
|
|
||||||
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
|
|
||||||
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
|
|
||||||
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
|
|
||||||
FATAL_LOG(m_logger) << Q_FUNC_INFO << " ERROR, not all files could be loaded !!!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
Q_UNUSED(filePaths_rough_to_fine);
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, init not available";
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
int LtsElevationManager::exerciseIdToTrainingAreaId(int exerciseId,
|
|
||||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc)
|
|
||||||
{
|
|
||||||
LOGGER_T logger = getLogger("LtsElevationManager");
|
|
||||||
|
|
||||||
if (!exmDtc)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " no dtcs"
|
|
||||||
<< ", exerciseId=" << exerciseId;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int trainingAreaId = -1;
|
|
||||||
{
|
|
||||||
exmDtc->waitForHistoricalDataExercise(1000);
|
|
||||||
|
|
||||||
const ExerciseManagement::Exercise& exm = exmDtc->exercise(exerciseId);
|
|
||||||
if (exm.id != exerciseId)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " Error on m_exmDtc->exercise"
|
|
||||||
<< ", exerciseId=" << exerciseId;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
trainingAreaId = exm.trainingAreaId;
|
|
||||||
|
|
||||||
if (trainingAreaId <= 0)
|
|
||||||
{
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " Error getting trainingAreaId"
|
|
||||||
<< ", exerciseId=" << exerciseId << ", trainingAreaId=" << trainingAreaId;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return trainingAreaId;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int LtsElevationManager::exerciseIdToTrainingAreaId(int exerciseId,
|
|
||||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc)
|
|
||||||
{
|
|
||||||
Q_UNUSED(exerciseId);
|
|
||||||
Q_UNUSED(exmDtc);
|
|
||||||
LOGGER_T logger = getLogger("LtsElevationManager");
|
|
||||||
ERROR_LOG(logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, cannot convert exerciseId to trainingAreaId";
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool LtsElevationManager::waitForInitialization()
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
if (!d->m_elevationManager)
|
|
||||||
return false;
|
|
||||||
return d->m_elevationManager->waitForInitialization();
|
|
||||||
#else
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, waitForInitialization not available";
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LtsElevationManager::isValid() const
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
if (!d->m_elevationManager)
|
|
||||||
return false;
|
|
||||||
return d->m_elevationManager->isValid();
|
|
||||||
#else
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, isValid not available";
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
double LtsElevationManager::elevation(double lon_rad, double lat_rad, double defaultValue, bool* bIsCovered) const
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
if (!d->m_elevationManager)
|
|
||||||
return defaultValue;
|
|
||||||
return d->m_elevationManager->elevation(lon_rad, lat_rad, defaultValue, bIsCovered);
|
|
||||||
#else
|
|
||||||
Q_UNUSED(lon_rad);
|
|
||||||
Q_UNUSED(lat_rad);
|
|
||||||
Q_UNUSED(bIsCovered);
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, elevation not available";
|
|
||||||
return defaultValue;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
LineOfSight LtsElevationManager::lineOfSightCalculation(const LtsUtils::QPoint3D& startPointGeo_absZ,
|
|
||||||
const LtsUtils::QPoint3D& endPointGeo_absZ)
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START"
|
|
||||||
<< ", startPointGeo_absZ = " << startPointGeo_absZ
|
|
||||||
<< ", endPointGeo_absZ = " << endPointGeo_absZ;
|
|
||||||
|
|
||||||
if (!isValid())
|
|
||||||
{
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " Error, LtsElevationManager not valid";
|
|
||||||
return LineOfSight::LOS_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
SituationMap::ElevationMapManager::LineOfSight eleMapMgrResult =
|
|
||||||
d->m_elevationManager->lineOfSightCalculation(startPointGeo_absZ, endPointGeo_absZ);
|
|
||||||
|
|
||||||
LtsElevation::LineOfSight result = static_cast<LtsElevation::LineOfSight>(eleMapMgrResult);
|
|
||||||
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END"
|
|
||||||
<< ", startPointGeo = " << startPointGeo_absZ << ", endPointGeo = " << endPointGeo_absZ
|
|
||||||
<< " -> LineOfSight " << result;
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
Q_UNUSED(startPointGeo_absZ);
|
|
||||||
Q_UNUSED(endPointGeo_absZ);
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, lineOfSightCalculation not available";
|
|
||||||
return LineOfSight::LOS_ERROR;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
LineOfSight LtsElevationManager::lineOfSightCalculation(const QPointF& startPointGeo, double startHat,
|
|
||||||
const QPointF& endPointGeo, double endHat)
|
|
||||||
{
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " START"
|
|
||||||
<< ", startPointGeo = " << startPointGeo << ", startHat = " << startHat
|
|
||||||
<< ", endPointGeo = " << endPointGeo << ", endHat = " << endHat;
|
|
||||||
|
|
||||||
SituationMap::ElevationMapManager::LineOfSight eleMapMgrResult =
|
|
||||||
d->m_elevationManager->lineOfSightCalculation(startPointGeo, startHat, endPointGeo, endHat);
|
|
||||||
|
|
||||||
LtsElevation::LineOfSight result = static_cast<LtsElevation::LineOfSight>(eleMapMgrResult);
|
|
||||||
|
|
||||||
TRACE_LOG(m_logger) << Q_FUNC_INFO << " END"
|
|
||||||
<< ", startPointGeo = " << startPointGeo << ", startHat = " << startHat
|
|
||||||
<< ", endPointGeo = " << endPointGeo << ", endHat = " << endHat << " -> LineOfSight "
|
|
||||||
<< static_cast<int>(eleMapMgrResult);
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
Q_UNUSED(startPointGeo);
|
|
||||||
Q_UNUSED(startHat);
|
|
||||||
Q_UNUSED(endPointGeo);
|
|
||||||
Q_UNUSED(endHat);
|
|
||||||
ERROR_LOG(m_logger) << Q_FUNC_INFO << " BUILD_RTI=OFF, lineOfSightCalculation not available";
|
|
||||||
return LineOfSight::LOS_ERROR;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString toString(const LineOfSight& value)
|
|
||||||
{
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case LineOfSight::LOS_UNDEFINED:
|
|
||||||
return QStringLiteral("LOS_UNDEFINED");
|
|
||||||
case LineOfSight::LOS_ERROR:
|
|
||||||
return QStringLiteral("LOS_ERROR");
|
|
||||||
case LineOfSight::LOS_VISIBLE:
|
|
||||||
return QStringLiteral("LOS_VISIBLE");
|
|
||||||
case LineOfSight::LOS_INVISIBLE:
|
|
||||||
return QStringLiteral("LOS_INVISIBLE");
|
|
||||||
}
|
|
||||||
Q_ASSERT(false);
|
|
||||||
return QStringLiteral("LineOfSightERROR");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& stream, const LineOfSight value)
|
|
||||||
{
|
|
||||||
stream << toString(value).toStdString();
|
|
||||||
return stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsElevation
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "ltselevation_export.h"
|
|
||||||
|
|
||||||
#include <LtsUtils/LtsUtilsCore/qpoint3d.h>
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QMap>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QPointer>
|
|
||||||
#include <QtCore/QStringList>
|
|
||||||
#include <iosfwd>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace LtsSession
|
|
||||||
{
|
|
||||||
class LtsSessionDataDds;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ExerciseManagement
|
|
||||||
{
|
|
||||||
namespace Interface
|
|
||||||
{
|
|
||||||
class Dtc;
|
|
||||||
}
|
|
||||||
} // namespace ExerciseManagement
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
namespace AssetManagement
|
|
||||||
{
|
|
||||||
namespace Interface
|
|
||||||
{
|
|
||||||
class Dtc;
|
|
||||||
}
|
|
||||||
} // namespace AssetManagement
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace LtsElevation
|
|
||||||
{
|
|
||||||
|
|
||||||
enum class LineOfSight { LOS_UNDEFINED, LOS_ERROR, LOS_VISIBLE, LOS_INVISIBLE };
|
|
||||||
|
|
||||||
class LtsElevationManager;
|
|
||||||
using LTS_ELEVATION_MANAGER_TYPE = QPointer<LtsElevationManager>;
|
|
||||||
|
|
||||||
class LTSELEVATION_EXPORT LtsElevationManager : public QObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
static LTS_ELEVATION_MANAGER_TYPE
|
|
||||||
createInstance(int exerciseId, const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc = {},
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc = {}
|
|
||||||
#else
|
|
||||||
const std::shared_ptr<void>& asmDtc = {}
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
static LTS_ELEVATION_MANAGER_TYPE getInstance(int exerciseId);
|
|
||||||
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
static LTS_ELEVATION_MANAGER_TYPE
|
|
||||||
createInstanceForTrainingAreaId(int trainingAreaId,
|
|
||||||
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc = nullptr);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void cleanupAll();
|
|
||||||
virtual ~LtsElevationManager();
|
|
||||||
|
|
||||||
bool waitForInitialization();
|
|
||||||
bool isValid() const;
|
|
||||||
|
|
||||||
double elevation(double lon_rad, double lat_rad, double defaultValue = std::numeric_limits<double>::min(),
|
|
||||||
bool* bIsCovered = nullptr) const;
|
|
||||||
|
|
||||||
LineOfSight lineOfSightCalculation(const LtsUtils::QPoint3D& startPointGeo_absZ,
|
|
||||||
const LtsUtils::QPoint3D& endPointGeo_absZ);
|
|
||||||
|
|
||||||
LineOfSight lineOfSightCalculation(const QPointF& startPointGeo, double startHat, const QPointF& endPointGeo,
|
|
||||||
double endHat);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit LtsElevationManager();
|
|
||||||
|
|
||||||
void initDDS(const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc,
|
|
||||||
#ifdef BUILD_RTI
|
|
||||||
const std::shared_ptr<AssetManagement::Interface::Dtc>& asmDtc
|
|
||||||
#else
|
|
||||||
const std::shared_ptr<void>& asmDtc
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
bool init(const QStringList& filePaths_rough_to_fine);
|
|
||||||
static int exerciseIdToTrainingAreaId(int exerciseId,
|
|
||||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc>& exmDtc);
|
|
||||||
|
|
||||||
QStringList getFilenamesForExercise(int exerciseId);
|
|
||||||
QStringList getFilenamesForTrainingArea(int trainingAreaId);
|
|
||||||
|
|
||||||
static LTS_ELEVATION_MANAGER_TYPE createInstanceUnitTest(int id, const QStringList& filePaths_rough_to_fine);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Private;
|
|
||||||
|
|
||||||
Private* d;
|
|
||||||
LOGGER_T m_logger;
|
|
||||||
};
|
|
||||||
|
|
||||||
LTSELEVATION_EXPORT const QString toString(const LtsElevation::LineOfSight& value);
|
|
||||||
|
|
||||||
LTSELEVATION_EXPORT std::ostream& operator<<(std::ostream& stream, const LtsElevation::LineOfSight value);
|
|
||||||
|
|
||||||
} // namespace LtsElevation
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
#
|
|
||||||
# Library which automatically provides Login/Logoff so that user data (rights for apps, etc.) is available before any app is started
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
# $HeadURL$
|
|
||||||
# $Author$
|
|
||||||
# Created by Mike Wille, SLSE, 2016-10-27
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
# LtsLogin
|
|
||||||
|
|
||||||
set(LtsLogin_SRCS
|
|
||||||
lts_login.cpp
|
|
||||||
logout_info_dialog.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_WRAP_UI(LtsLogin_SRCS
|
|
||||||
logout_info_dialog.ui
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(BUILD_RTI)
|
|
||||||
NGL_ADD_LIBRARY2(WS LtsLogin SHARED ${LtsLogin_SRCS})
|
|
||||||
NGL_TARGET_INCLUDE_DIRECTORIES(LtsLogin
|
|
||||||
PUBLIC
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
|
||||||
)
|
|
||||||
|
|
||||||
NGL_TARGET_LINK_LIBRARIES(LtsLogin
|
|
||||||
PRIVATE
|
|
||||||
LtsAppDescriptor
|
|
||||||
LtsPluginManager
|
|
||||||
LtsSession
|
|
||||||
LtsSessionData
|
|
||||||
LtsWidgets
|
|
||||||
LtsUtilsSettings
|
|
||||||
LtsUtilsCoreHeaderOnly
|
|
||||||
PUBLIC
|
|
||||||
OpmDataPluginInterface
|
|
||||||
SrmDataPluginInterface
|
|
||||||
AsmDataPluginInterface
|
|
||||||
Qt6::Core
|
|
||||||
)
|
|
||||||
ENDIF(BUILD_RTI)
|
|
||||||
@@ -1,92 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "logout_info_dialog.h"
|
|
||||||
|
|
||||||
#include "ui_logout_info_dialog.h"
|
|
||||||
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
|
|
||||||
namespace LtsLogin
|
|
||||||
{
|
|
||||||
|
|
||||||
LogoutInformationDialog::LogoutInformationDialog(int timeOut, AssetManagement::ShutdownAction shutdownAction,
|
|
||||||
QWidget* parent)
|
|
||||||
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal), m_ui(new Ui::LogoutInformationDialog),
|
|
||||||
m_timer(new QTimer(this)), m_timeOut(timeOut), m_secsLeft(timeOut)
|
|
||||||
{
|
|
||||||
m_ui->setupUi(this);
|
|
||||||
QString actionText;
|
|
||||||
switch (shutdownAction)
|
|
||||||
{
|
|
||||||
case AssetManagement::ShutdownAction::NoAction:
|
|
||||||
case AssetManagement::ShutdownAction::Logout:
|
|
||||||
actionText = tr("logout");
|
|
||||||
break;
|
|
||||||
case AssetManagement::ShutdownAction::Shutdown:
|
|
||||||
actionText = tr("shutdown");
|
|
||||||
break;
|
|
||||||
case AssetManagement::ShutdownAction::Reboot:
|
|
||||||
actionText = tr("reboot");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
setText(tr("A %1 was triggered by a remote workstation.").arg(actionText));
|
|
||||||
|
|
||||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this,
|
|
||||||
&LogoutInformationDialog::acceptClicked);
|
|
||||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this,
|
|
||||||
&LogoutInformationDialog::closeClicked);
|
|
||||||
connect(m_timer, &QTimer::timeout, this, &LogoutInformationDialog::onTimerTimeout);
|
|
||||||
|
|
||||||
m_timer->setInterval(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogoutInformationDialog::~LogoutInformationDialog()
|
|
||||||
{
|
|
||||||
delete m_ui;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogoutInformationDialog::setText(const QString& text)
|
|
||||||
{
|
|
||||||
m_ui->lblLogoutText->setText(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogoutInformationDialog::onTimerTimeout()
|
|
||||||
{
|
|
||||||
if (m_secsLeft > 0)
|
|
||||||
{
|
|
||||||
m_secsLeft--;
|
|
||||||
setCloseButtonText(m_secsLeft);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
acceptClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogoutInformationDialog::acceptClicked()
|
|
||||||
{
|
|
||||||
m_timer->stop();
|
|
||||||
accept();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogoutInformationDialog::closeClicked()
|
|
||||||
{
|
|
||||||
m_timer->stop();
|
|
||||||
reject();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogoutInformationDialog::setCloseButtonText(int secsLeft)
|
|
||||||
{
|
|
||||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close)->setText(tr("Abort [%1]").arg(secsLeft));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LogoutInformationDialog::showEvent(QShowEvent* event)
|
|
||||||
{
|
|
||||||
m_secsLeft = m_timeOut;
|
|
||||||
setCloseButtonText(m_secsLeft);
|
|
||||||
m_timer->start();
|
|
||||||
LtsWidgets::LtsFramelessDialog::showEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsLogin
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include <AssetManagement/asm.hpp>
|
|
||||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
class QTimer;
|
|
||||||
|
|
||||||
namespace Ui
|
|
||||||
{
|
|
||||||
class LogoutInformationDialog;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace LtsLogin
|
|
||||||
{
|
|
||||||
|
|
||||||
class LogoutInformationDialog : public LtsWidgets::LtsFramelessDialog
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
LogoutInformationDialog(int timeOut, AssetManagement::ShutdownAction shutdownAction, QWidget* parent = nullptr);
|
|
||||||
~LogoutInformationDialog();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
void onTimerTimeout();
|
|
||||||
void acceptClicked();
|
|
||||||
void closeClicked();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setText(const QString& text);
|
|
||||||
void setCloseButtonText(int secsLeft);
|
|
||||||
|
|
||||||
Ui::LogoutInformationDialog* m_ui;
|
|
||||||
QTimer* m_timer;
|
|
||||||
int m_timeOut;
|
|
||||||
int m_secsLeft;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void showEvent(QShowEvent* event) override final;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace LtsLogin
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>LogoutInformationDialog</class>
|
|
||||||
<widget class="QWidget" name="LogoutInformationDialog">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>400</width>
|
|
||||||
<height>165</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">Form</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QFrame" name="frame">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Raised</enum>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="lblLogoutText">
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"><logout information text></string>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::AutoText</enum>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="Line" name="line">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>LtsWidgets::LtsDialogButtonBox</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header>LtsWidgets/lts_dialog_button_box.h</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
||||||
@@ -1,282 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "lts_login.h"
|
|
||||||
|
|
||||||
#include "logout_info_dialog.h"
|
|
||||||
|
|
||||||
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
||||||
#include <LtsPluginManager/lts_plugin_manager.h>
|
|
||||||
#include <LtsSession/lts_session.h>
|
|
||||||
#include <LtsSession/lts_session_data.h>
|
|
||||||
#include <LtsSession/lts_session_manager.h>
|
|
||||||
#include <LtsUtils/LtsUtilsCore/dds_vector.h>
|
|
||||||
#include <LtsUtilsSettings/settings.h>
|
|
||||||
#include <LtsWidgets/lts_wait_dialog.h>
|
|
||||||
#include <QtCore/QCoreApplication>
|
|
||||||
#include <QtCore/QDebug>
|
|
||||||
#include <QtCore/QDir>
|
|
||||||
#include <QtWidgets/QMessageBox>
|
|
||||||
#include <QtCore/QProcess>
|
|
||||||
|
|
||||||
namespace LtsLogin
|
|
||||||
{
|
|
||||||
const int logoutShutdownTimeout = 2 * 60;
|
|
||||||
|
|
||||||
LtsLogin::LtsLogin()
|
|
||||||
: m_loginApp(nullptr), m_shutdownAction(AssetManagement::ShutdownAction::NoAction), m_isInLogoutDialog(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsLogin::~LtsLogin()
|
|
||||||
{
|
|
||||||
delete m_loginApp;
|
|
||||||
m_loginApp = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsLogin::login()
|
|
||||||
{
|
|
||||||
LtsAppDescriptor::PluginInfo opmDataPlugin;
|
|
||||||
opmDataPlugin.iid = QStringLiteral("opm");
|
|
||||||
opmDataPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo pdmDataPlugin;
|
|
||||||
pdmDataPlugin.iid = QStringLiteral("pdm");
|
|
||||||
pdmDataPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo asmDataPlugin;
|
|
||||||
asmDataPlugin.iid = QStringLiteral("asm");
|
|
||||||
asmDataPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo srmDataPlugin;
|
|
||||||
srmDataPlugin.iid = QStringLiteral("srm");
|
|
||||||
srmDataPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::DATA;
|
|
||||||
|
|
||||||
LtsAppDescriptor::PluginInfo guiPlugin;
|
|
||||||
guiPlugin.iid = m_loginPluginIid;
|
|
||||||
guiPlugin.type = LtsAppDescriptor::PluginInfo::PluginType::GUI;
|
|
||||||
guiPlugin.flags |= LtsAppDescriptor::PluginInfo::Flag::PAYLOAD;
|
|
||||||
|
|
||||||
QVector<LtsAppDescriptor::PluginInfo> plugins;
|
|
||||||
plugins.append(opmDataPlugin);
|
|
||||||
plugins.append(pdmDataPlugin);
|
|
||||||
plugins.append(asmDataPlugin);
|
|
||||||
plugins.append(srmDataPlugin);
|
|
||||||
plugins.append(guiPlugin);
|
|
||||||
|
|
||||||
LtsAppDescriptor::AppDescription app;
|
|
||||||
app.active = true;
|
|
||||||
app.appName = QStringLiteral("Login");
|
|
||||||
app.pluginInfos = plugins;
|
|
||||||
|
|
||||||
LtsSession::DdsConnectionParams connParams;
|
|
||||||
connParams.domainId = LtsSessionData::LtsSessionData::getInstance()->getDomainIdPreset();
|
|
||||||
connParams.tcpConnectionUrl = LtsSessionData::LtsSessionData::getInstance()->getTcpConnectionUrl();
|
|
||||||
connParams.partitionType = IDL::PartitionType::Global;
|
|
||||||
connParams.partitionId = 0;
|
|
||||||
|
|
||||||
m_loginApp = new LtsPluginManager::LtsPluginManager();
|
|
||||||
bool result = m_loginApp->startApp(app, true, connParams);
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
qWarning() << "no login plugin - probably an offline project";
|
|
||||||
emit signalLoginDone();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(m_loginApp, &LtsPluginManager::LtsPluginManager::signalInitializationFinished, this, [this]() {
|
|
||||||
disconnect(m_loginApp, &LtsPluginManager::LtsPluginManager::signalInitializationFinished, this, nullptr);
|
|
||||||
|
|
||||||
LtsSession::LtsSession* session = getAdminSession();
|
|
||||||
|
|
||||||
if (!session)
|
|
||||||
{
|
|
||||||
qCritical() << "I cannot find the Admin Session :( - abort!";
|
|
||||||
QMessageBox::critical(nullptr, tr("Error loading login app"), tr("Could not load login app - abort."));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->isInitializationDone())
|
|
||||||
QMetaObject::invokeMethod(this, &LtsLogin::slotLoginDone);
|
|
||||||
else
|
|
||||||
connect(session, &LtsSession::LtsSession::signalDoneInitializingSession, this, &LtsLogin::slotLoginDone,
|
|
||||||
Qt::UniqueConnection);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsLogin::slotLoginDone()
|
|
||||||
{
|
|
||||||
LtsSession::LtsSession* session = getAdminSession();
|
|
||||||
|
|
||||||
if (session != nullptr)
|
|
||||||
{
|
|
||||||
disconnect(session, &LtsSession::LtsSession::signalDoneInitializingSession, this, &LtsLogin::slotLoginDone);
|
|
||||||
|
|
||||||
if (session->getDtc<AssetManagement::DataInterface>(m_asmDtc))
|
|
||||||
{
|
|
||||||
m_asmDtc->enableWorkstationLogout();
|
|
||||||
connect(m_asmDtc.get(), &AssetManagement::Interface::Dtc::workstationLogoutChanged, this,
|
|
||||||
&LtsLogin::slotLogoutShutdown);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
qWarning() << "LtsLogin: no asm dtc, no remote logout/shutdown!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qCritical() << "LtsLogin: no admin session for login!!";
|
|
||||||
QMessageBox::critical(nullptr, tr("Login error"), tr("Could not finalize login - abort."));
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
emit signalLoginDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsLogin::showLogoutInformationDialog(AssetManagement::ShutdownAction action)
|
|
||||||
{
|
|
||||||
LogoutInformationDialog* lid = new LogoutInformationDialog(logoutShutdownTimeout, action, nullptr);
|
|
||||||
connect(lid, &LogoutInformationDialog::accepted, this, [this, action]() {
|
|
||||||
m_shutdownAction = action;
|
|
||||||
m_isInLogoutDialog = false;
|
|
||||||
emit signalLogout();
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(lid, &LogoutInformationDialog::rejected, this, [this]() { m_isInLogoutDialog = false; });
|
|
||||||
|
|
||||||
lid->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsLogin::slotLogoutShutdown(const AssetManagement::WorkstationLogout& data, DataModification modType)
|
|
||||||
{
|
|
||||||
if (m_isInLogoutDialog)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_asmDtc == nullptr || modType != DataModification::eAdded)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!m_asmDtc->isAssetEnabled())
|
|
||||||
m_asmDtc->enableAsset();
|
|
||||||
for (int id : data.ids)
|
|
||||||
{
|
|
||||||
if (QString::fromStdString(m_asmDtc->asset(id).name)
|
|
||||||
.compare(LtsSession::LtsSession::workstationName(), Qt::CaseInsensitive) == 0)
|
|
||||||
{
|
|
||||||
m_isInLogoutDialog = true;
|
|
||||||
showLogoutInformationDialog(data.shutdownAction);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsSession::LtsSession* LtsLogin::getAdminSession()
|
|
||||||
{
|
|
||||||
return m_loginApp->m_sessionManager->getSession(IDL::PartitionType::Global, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LtsLogin::logoff()
|
|
||||||
{
|
|
||||||
if (m_loginApp == nullptr)
|
|
||||||
{
|
|
||||||
qCritical() << "LtsLogin::logoff: missing login app!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LtsSession::LtsSession* datSession = getAdminSession();
|
|
||||||
|
|
||||||
if (!datSession)
|
|
||||||
{
|
|
||||||
qCritical() << "LtsLogin::logoff: no admin session for logout!";
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
|
||||||
int workstationId = LtsSessionData::LtsSessionData::getInstance()->getWorkstationId();
|
|
||||||
|
|
||||||
LtsSessionData::LtsSessionData::getInstance()->clear();
|
|
||||||
|
|
||||||
std::shared_ptr<OperatorManagement::Interface::Ftc> opmFtc;
|
|
||||||
if (operatorId == -1 || !datSession->getFtc<OperatorManagement::DataInterface>(opmFtc))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
|
|
||||||
LtsUtils::OperatorSettings* os = LtsUtils::OperatorSettings::getInstance();
|
|
||||||
|
|
||||||
const QByteArray settings = os->exportSettings();
|
|
||||||
|
|
||||||
const auto vec(LtsUtils::convert<std::vector<uint8_t>>(settings));
|
|
||||||
os->clear();
|
|
||||||
opmFtc->operatorGetSetSettingsRequest(OperatorManagement::OperatorGetSetSettingsRequest(operatorId, vec));
|
|
||||||
}
|
|
||||||
catch (const std::runtime_error& err)
|
|
||||||
{
|
|
||||||
qCritical() << "Saving operator settings failed!" << err.what();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<SituationReplayManagement::ForeignDataInterface> srmIfc;
|
|
||||||
if (datSession->getForeignDataInterface<SituationReplayManagement::DataInterface>(srmIfc))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
srmIfc->removeReplayPartitionsWorkstation(workstationId);
|
|
||||||
}
|
|
||||||
catch (const std::runtime_error& err)
|
|
||||||
{
|
|
||||||
qCritical() << "Removing reply partitions from this workstation failed!" << err.what();
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
srmIfc->removeReplayPartitionsOperator(operatorId);
|
|
||||||
}
|
|
||||||
catch (const std::runtime_error& err)
|
|
||||||
{
|
|
||||||
qCritical() << "Removing reply partitions from this operator failed!" << err.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
opmFtc->operatorLogoutRequest(OperatorManagement::OperatorLogoutRequest(operatorId));
|
|
||||||
}
|
|
||||||
catch (const std::runtime_error& err)
|
|
||||||
{
|
|
||||||
qCritical() << "Logout failed!" << err.what();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_loginApp->deleteLater();
|
|
||||||
m_loginApp = nullptr;
|
|
||||||
|
|
||||||
QString cmd;
|
|
||||||
switch (m_shutdownAction)
|
|
||||||
{
|
|
||||||
case AssetManagement::ShutdownAction::Shutdown:
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
cmd = QStringLiteral("xeyes");
|
|
||||||
#else
|
|
||||||
cmd = QStringLiteral("systemctl poweroff");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case AssetManagement::ShutdownAction::Reboot:
|
|
||||||
#ifdef LTS_DEBUG
|
|
||||||
cmd = QStringLiteral("kcalc");
|
|
||||||
#else
|
|
||||||
cmd = QStringLiteral("systemctl reboot");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case AssetManagement::ShutdownAction::Logout:
|
|
||||||
case AssetManagement::ShutdownAction::NoAction:
|
|
||||||
emit signalLogoffDone();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!cmd.isEmpty())
|
|
||||||
{
|
|
||||||
QProcess::startDetached(cmd);
|
|
||||||
QCoreApplication::quit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace LtsLogin
|
|
||||||
Loaded 100 of 14140 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user