remove all unneeded module listed from Niklas #1
No files matched your search
@@ -1,168 +0,0 @@
|
||||
#
|
||||
# THP-Viewer
|
||||
#
|
||||
# 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()
|
||||
|
||||
|
||||
ADD_SUBDIRECTORY(THP-Starter)
|
||||
|
||||
# Make VLC optional - only try to find it if user explicitly enables it
|
||||
OPTION(WITH_VLC "Enable VLC support" OFF)
|
||||
IF(WITH_VLC)
|
||||
FIND_PACKAGE(VLC)
|
||||
IF(VLC_FOUND)
|
||||
SET(THP_HAS_VLC TRUE)
|
||||
SET(THP_VLC_SOURCES
|
||||
thpwidgets/thp_audio_video_widget.cpp
|
||||
thpwidgets/thp_audio_video_widget.h
|
||||
thpwidgets/thp_audio_video_widget_p.h
|
||||
thpwidgets/thp_audio_video_widget.ui
|
||||
)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "VLC requested but not found - building without VLC support")
|
||||
SET(THP_HAS_VLC FALSE)
|
||||
SET(THP_VLC_SOURCES "")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
SET(THP_HAS_VLC FALSE)
|
||||
SET(THP_VLC_SOURCES "")
|
||||
ENDIF()
|
||||
|
||||
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
|
||||
|
||||
${THP_VLC_SOURCES}
|
||||
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
|
||||
${THP_VLC_SOURCES}
|
||||
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)
|
||||
IF(VLC_FOUND)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(thp_viewer
|
||||
PRIVATE
|
||||
${VLC_INCLUDE_DIR}
|
||||
)
|
||||
NGL_TARGET_COMPILE_DEFINITIONS(thp_viewer
|
||||
PRIVATE
|
||||
)
|
||||
ENDIF()
|
||||
if(QT6_GUI_AVAILABLE)
|
||||
NGL_TARGET_LINK_LIBRARIES(thp_viewer
|
||||
ArcGISQt5Hack # make sure it's loaded *before* libEsriCommonQt.so
|
||||
|
||||
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
|
||||
$<IF:$<TARGET_EXISTS:svcIsmClient>,svcIsmClient,>
|
||||
svcPpmClient
|
||||
svcPdmClient
|
||||
svcAlmClient
|
||||
)
|
||||
endif()
|
||||
IF(VLC_FOUND)
|
||||
NGL_TARGET_LINK_LIBRARIES(thp_viewer
|
||||
$<$<TARGET_EXISTS:PkgConfig::VLC>:PkgConfig::VLC>
|
||||
)
|
||||
ENDIF()
|
||||
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
|
||||
|
||||
$<IF:$<TARGET_EXISTS:ddsconnector>,ddsconnector,>
|
||||
Qt6::Core
|
||||
nglapplication
|
||||
SitmapDds
|
||||
|
||||
AsbForeignDataPluginThp
|
||||
BuildingViewerCommon
|
||||
FltAesGuiCommon
|
||||
IsmDataPluginThp
|
||||
|
||||
svcFlmCommon
|
||||
|
||||
svcAesClient
|
||||
svcBldClient
|
||||
svcCesClient
|
||||
svcGimClient
|
||||
$<IF:$<TARGET_EXISTS:svcIsmClient>,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");
|
||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
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 <QtWidgets/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 <QtCore/QUrl>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtWidgets/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"));
|
||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
|
||||
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 <QtCore/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 <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QKeyEvent>
|
||||
#include <QPrintDialog>
|
||||
#include <QPrinter>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QTextDocument>
|
||||
#include <QScreen>
|
||||
#include <QDesktopServices>
|
||||
#include <QDomElement>
|
||||
#include <QDomDocument>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QRect>
|
||||
#include <QtCore/QSize>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
#include <QSettings>
|
||||
#include <QInputDialog>
|
||||
#include <QtCore/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();
|
||||
|
||||
const QStringRef ext = lpath.splitRef(QLatin1Char('.')).last();
|
||||
const QStringRef 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") &&
|
||||
lpath.midRef(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;
|
||||
QString errorStr;
|
||||
int errorLine, errorColumn;
|
||||
if (!doc.setContent(&file, true, &errorStr, &errorLine, &errorColumn))
|
||||
{
|
||||
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 <QtWidgets/QMainWindow>
|
||||
#include <QtCore/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>
|
||||
-772
@@ -1,772 +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 <QtCore/QCoreApplication>
|
||||
#include <QDirIterator>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QMutex>
|
||||
#include <QScreen>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QGuiApplication>
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef THP_HAS_VLC
|
||||
#include <vlc/libvlc_version.h>
|
||||
#endif
|
||||
|
||||
namespace THP
|
||||
{
|
||||
|
||||
#ifdef THP_HAS_VLC
|
||||
|
||||
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
|
||||
|
||||
#else // THP_HAS_VLC - Stub implementation when VLC is not available
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
AudioVideoWidget::Private::Private(QFrame *parent)
|
||||
: m_vlcinstance(nullptr)
|
||||
, m_mPlayer(nullptr)
|
||||
, m_mListPlayer(nullptr)
|
||||
, m_mediaList(nullptr)
|
||||
, currentSpeedIdx(2)
|
||||
, m_parent(parent)
|
||||
, m_timer(nullptr)
|
||||
, m_initThread(nullptr)
|
||||
, ui(new Ui::audioVideoWidget())
|
||||
, m_logger(NGL::INGLLogger::Instance())
|
||||
{
|
||||
m_logger.Log("AudioVideoWidget: VLC not available, using stub implementation", NGL::eLogWarning);
|
||||
ui->setupUi(m_parent);
|
||||
}
|
||||
|
||||
AudioVideoWidget::Private::~Private()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::initVLCInstance(bool /*bInInitThread*/)
|
||||
{
|
||||
m_logger.Log("AudioVideoWidget::initVLCInstance: VLC not available", NGL::eLogWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::uninitVLCInstance()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::initVLCPlayer()
|
||||
{
|
||||
m_logger.Log("AudioVideoWidget::initVLCPlayer: VLC not available", NGL::eLogWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::uninitVLCPlayer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::playVLC(const QUrl & /*url*/)
|
||||
{
|
||||
m_logger.Log("AudioVideoWidget::playVLC: VLC not available", NGL::eLogWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::stopVLC()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::setAV(bool /*isAudio*/)
|
||||
{
|
||||
m_logger.Log("AudioVideoWidget::setAV: VLC not available", NGL::eLogWarning);
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onSlower()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onFaster()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::on100pct()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onPlay()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onStop()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onPositionChanged(int /*pos*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onVolumeChanged(int /*vol*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onUpdateGUI()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onVLCInstanceInitializd()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::clearMediaList()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::playVLCInternal()
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::onUpdateGUIWithState(libvlc_state_t /*overwrite_state*/)
|
||||
{
|
||||
}
|
||||
|
||||
bool AudioVideoWidget::Private::init()
|
||||
{
|
||||
m_logger.Log("AudioVideoWidget::init: VLC not available", NGL::eLogWarning);
|
||||
return false;
|
||||
}
|
||||
|
||||
void AudioVideoWidget::Private::setRate()
|
||||
{
|
||||
}
|
||||
|
||||
libvlc_state_t AudioVideoWidget::Private::getState() const
|
||||
{
|
||||
return libvlc_NothingSpecial;
|
||||
}
|
||||
|
||||
AudioVideoInitThread::AudioVideoInitThread(AudioVideoWidget::Private *p)
|
||||
: m_private(p)
|
||||
{
|
||||
}
|
||||
|
||||
void AudioVideoInitThread::run()
|
||||
{
|
||||
}
|
||||
|
||||
#endif // THP_HAS_VLC
|
||||
|
||||
} // namespace THP
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handle Audio/Video output for thp through libvlc
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/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>
|
||||
-108
@@ -1,108 +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
|
||||
|
||||
#ifdef THP_HAS_VLC
|
||||
#include <vlc/vlc.h>
|
||||
#endif
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QThread>
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "thp_audio_video_widget.h"
|
||||
|
||||
class QUrl;
|
||||
class QFrame;
|
||||
class QTimer;
|
||||
namespace Ui
|
||||
{
|
||||
class audioVideoWidget;
|
||||
}
|
||||
|
||||
// Forward declarations for VLC types when VLC is not available
|
||||
#ifndef THP_HAS_VLC
|
||||
typedef int libvlc_state_t;
|
||||
#define libvlc_NothingSpecial 0
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
#ifdef THP_HAS_VLC
|
||||
libvlc_instance_t *m_vlcinstance;
|
||||
libvlc_media_player_t *m_mPlayer;
|
||||
libvlc_media_list_player_t *m_mListPlayer;
|
||||
libvlc_media_list_t *m_mediaList;
|
||||
#else
|
||||
void *m_vlcinstance;
|
||||
void *m_mPlayer;
|
||||
void *m_mListPlayer;
|
||||
void *m_mediaList;
|
||||
#endif
|
||||
|
||||
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 <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 <QtWidgets/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 <QtCore/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 QStringRef ext = lpath.splitRef(QLatin1Char('.')).last();
|
||||
const QStringRef ext2Chars = ext.left(2);
|
||||
if (ext == QLatin1String("html") &&
|
||||
lpath.midRef(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 <QtWidgets/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 <QtWidgets/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 <QtCore/QFileInfo>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QtCore/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.m_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.m_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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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 <QtWidgets/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;
|
||||
};
|
||||
}
|
||||
-650
@@ -1,650 +0,0 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Handle situation display in thp
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
#include "thp_situation_widget.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_situation_filter_building_components.h"
|
||||
#include "thp_plugin_provider.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QKeyEvent>
|
||||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QSvgRenderer>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/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 : qAsConst(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.m_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.m_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 <QtWidgets/QLabel>
|
||||
#include <QtWidgets/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 <QtWidgets/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
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2016-03-17
|
||||
#
|
||||
|
||||
# Make ${Qt6_Widgets} optional
|
||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
||||
set(Qt6_Widgets ${Qt6_Widgets})
|
||||
else()
|
||||
set(Qt6_Widgets "")
|
||||
endif()
|
||||
|
||||
|
||||
SET(pre_script_gui_SRCS
|
||||
pre_script_gui_plugin.cpp
|
||||
pre_script_gui_plugin.h
|
||||
pre_script_dialog.h
|
||||
pre_script_dialog.cpp
|
||||
pre_storyboard.cpp
|
||||
pre_storyboard.h
|
||||
pre_journal_types.h
|
||||
pre_journal_types.cpp
|
||||
pre_journal_dialog.h
|
||||
pre_journal_dialog.cpp
|
||||
pre_screen.h
|
||||
pre_screen.cpp
|
||||
filter_topic.h
|
||||
filter_topic.cpp
|
||||
)
|
||||
|
||||
QT5_WRAP_UI(pre_script_gui_SRCS
|
||||
pre_storyboard.ui
|
||||
pre_script_dialog.ui
|
||||
pre_journal_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS PreScriptGuiPlugin MODULE ${pre_script_gui_SRCS})
|
||||
if(QT6_GUI_AVAILABLE)
|
||||
NGL_TARGET_LINK_LIBRARIES(PreScriptGuiPlugin
|
||||
NGLLogger
|
||||
LtsSession
|
||||
PreDataPluginInterface
|
||||
PrePresentationGuiPluginInterface
|
||||
PreGuiCommon
|
||||
PreGuiScriptCommon
|
||||
svcPreCommon
|
||||
${Qt6_Widgets}
|
||||
LtsWidgets
|
||||
LtsDataView
|
||||
LtsUtilsGuiDds
|
||||
LtsSessionData
|
||||
ProjectConfig
|
||||
LtsScriptTimeline
|
||||
LtsMultiMonitor
|
||||
|
||||
LtsAppManager # start replay app
|
||||
LtsSessionData # set partition preset for replay app
|
||||
TopicEditorInterface
|
||||
TopicEditorBase
|
||||
LtsPluginManager # manipulate apps
|
||||
|
||||
# for Topics
|
||||
EvlGuiPluginInterface
|
||||
|
||||
|
||||
SrmDataPluginInterface # start playback
|
||||
LtsPrinting
|
||||
SituationMapGuiPluginInterface
|
||||
|
||||
# Script Player Controls:
|
||||
SrpGuiPluginInterface
|
||||
|
||||
# file topic
|
||||
FlmExplorerGuiPluginInterface
|
||||
# building topic
|
||||
BdvViewerGuiPluginInterface
|
||||
# report topic
|
||||
RepGuiPluginInterface
|
||||
LtsReportDisplay
|
||||
MrkCommon # for ApplyFilter @ SitmapFilter
|
||||
LtsUtilsSettings
|
||||
ngltools # DTG
|
||||
situationMap # set time string on map
|
||||
ExportBdvTopicSetting
|
||||
)
|
||||
endif()
|
||||
|
||||
NGL_INSTALL_TARGET(PreScriptGuiPlugin)
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
#include "filter_topic.h"
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
FilterTopic::~FilterTopic()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
FilterTopic::FilterTopic(const FilterTopic &other)
|
||||
{
|
||||
mainTopicId = other.mainTopicId;
|
||||
filterTopic = other.filterTopic;
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <LtsScriptTimeline/track_entry.h>
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
class FilterTopic
|
||||
{
|
||||
public:
|
||||
FilterTopic()
|
||||
: mainTopicId(-1)
|
||||
, filterTopic(nullptr)
|
||||
{}
|
||||
|
||||
FilterTopic(int _mainTopicId, LtsScriptTimeline::TrackEntry *_filterTopic)
|
||||
: mainTopicId(_mainTopicId)
|
||||
, filterTopic(_filterTopic)
|
||||
{}
|
||||
|
||||
FilterTopic(const FilterTopic &other);
|
||||
|
||||
~FilterTopic();
|
||||
|
||||
int mainTopicId;
|
||||
LtsScriptTimeline::TrackEntry *filterTopic;
|
||||
};
|
||||
}
|
||||
-82
@@ -1,82 +0,0 @@
|
||||
#include "pre_journal_dialog.h"
|
||||
#include <utility>
|
||||
#include "ui_pre_journal_dialog.h"
|
||||
|
||||
#include <LtsPrinting/printing.h>
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
JournalDialog::JournalDialog(LtsSession::LtsSession *session, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent)
|
||||
, m_ui(new Ui::JournalDialog)
|
||||
, m_journal(nullptr)
|
||||
, m_session(session)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &JournalDialog::slotPrint);
|
||||
}
|
||||
|
||||
|
||||
JournalDialog::~JournalDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void JournalDialog::slotPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->listWidget);
|
||||
}
|
||||
|
||||
|
||||
bool JournalDialog::init(MainJournal *journal)
|
||||
{
|
||||
m_journal = journal;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void JournalDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Script Journal"));
|
||||
fillJournal();
|
||||
}
|
||||
|
||||
|
||||
void JournalDialog::fillJournal()
|
||||
{
|
||||
m_ui->listWidget->clear();
|
||||
|
||||
if (!m_journal)
|
||||
return;
|
||||
|
||||
m_ui->listWidget->addItem(m_journal->getText());
|
||||
for (const Journal *j : std::as_const(m_journal->journalList))
|
||||
m_ui->listWidget->addItem(j->getText());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "pre_journal_types.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class JournalDialog;
|
||||
}
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
class JournalDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit JournalDialog(LtsSession::LtsSession *session, QWidget *parent);
|
||||
~JournalDialog();
|
||||
bool init(MainJournal *journal);
|
||||
void retranslate() override final;
|
||||
|
||||
private slots:
|
||||
void slotPrint();
|
||||
|
||||
private:
|
||||
void fillJournal();
|
||||
|
||||
Ui::JournalDialog *m_ui;
|
||||
MainJournal *m_journal;
|
||||
LtsSession::LtsSession *m_session;
|
||||
};
|
||||
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>JournalDialog</class>
|
||||
<widget class="QWidget" name="JournalDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>707</width>
|
||||
<height>464</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Script Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
#include "pre_journal_types.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
QString ttt(qint64 msecsSinceEpoch)
|
||||
{
|
||||
return DTG::toStringMSec(msecsSinceEpoch);
|
||||
}
|
||||
|
||||
|
||||
QString pttt(int presentationTime)
|
||||
{
|
||||
return QTime::fromMSecsSinceStartOfDay(presentationTime * 1000).toString();
|
||||
}
|
||||
|
||||
|
||||
Journal::Journal()
|
||||
: m_started(QDateTime::currentMSecsSinceEpoch())
|
||||
{}
|
||||
|
||||
|
||||
QString Journal::started() const
|
||||
{
|
||||
return ttt(m_started);
|
||||
}
|
||||
|
||||
|
||||
MainJournal::~MainJournal()
|
||||
{
|
||||
qDeleteAll(journalList);
|
||||
}
|
||||
|
||||
|
||||
QString MainJournal::getText() const
|
||||
{
|
||||
return Journal::tr("Script Player started on %1").arg(ttt(started));
|
||||
}
|
||||
|
||||
|
||||
NextTopicJournal::NextTopicJournal(int presentationTime, bool isFilter, const QString &topicTypeName, int length)
|
||||
: Journal()
|
||||
, m_isFilter(isFilter)
|
||||
, m_topicTypeName(topicTypeName)
|
||||
, m_length(length)
|
||||
, m_presentationTime(presentationTime)
|
||||
{}
|
||||
|
||||
|
||||
QString NextTopicJournal::getText() const
|
||||
{
|
||||
return Journal::tr("%1 '%2' started at %3 for %4 seconds on %5").arg(m_isFilter ? tr("FilterTopic") : tr("Topic"),
|
||||
m_topicTypeName, pttt(m_presentationTime)).arg(m_length).arg(started());
|
||||
}
|
||||
|
||||
|
||||
QString PlayJournal::getText() const
|
||||
{
|
||||
return Journal::tr("Started / resumed script at %1 on %2").arg(pttt(m_presentationTime), started());
|
||||
}
|
||||
|
||||
|
||||
QString PauseJournal::getText() const
|
||||
{
|
||||
return Journal::tr("Paused script at %1 on %2").arg(pttt(m_presentationTime), started());
|
||||
}
|
||||
|
||||
|
||||
QString EndedJournal::getText() const
|
||||
{
|
||||
return Journal::tr("Script ended at %1 on %2").arg(pttt(m_presentationTime), started());
|
||||
}
|
||||
|
||||
|
||||
QString StopJournal::getText() const
|
||||
{
|
||||
return Journal::tr("Script stopped at %1 on %2").arg(pttt(m_presentationTime), started());
|
||||
}
|
||||
|
||||
|
||||
QString SetTimeJournal::getText() const
|
||||
{
|
||||
return Journal::tr("Position time set to %1 on %2").arg(pttt(m_toPresentationTime), started());
|
||||
}
|
||||
|
||||
}
|
||||
-131
@@ -1,131 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
class Journal
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Journal)
|
||||
|
||||
public:
|
||||
Journal();
|
||||
virtual ~Journal() = default;
|
||||
QString started() const;
|
||||
virtual QString getText() const = 0;
|
||||
qint64 m_started;
|
||||
};
|
||||
|
||||
|
||||
class MainJournal
|
||||
{
|
||||
public:
|
||||
~MainJournal();
|
||||
QString getText() const;
|
||||
|
||||
qint64 started = 0;
|
||||
QVector<Journal *> journalList;
|
||||
};
|
||||
|
||||
|
||||
class NextTopicJournal : public Journal
|
||||
{
|
||||
public:
|
||||
NextTopicJournal(int presentationTime, bool isFilter, const QString &topicTypeName, int length);
|
||||
QString getText() const override final;
|
||||
|
||||
bool m_isFilter;
|
||||
|
||||
QString m_topicTypeName;
|
||||
int m_length;
|
||||
int m_presentationTime;
|
||||
};
|
||||
|
||||
|
||||
class PlayJournal : public Journal
|
||||
{
|
||||
public:
|
||||
explicit PlayJournal(int presentationTime)
|
||||
: Journal()
|
||||
, m_presentationTime(presentationTime)
|
||||
{}
|
||||
|
||||
QString getText() const override final;
|
||||
|
||||
int m_presentationTime;
|
||||
};
|
||||
|
||||
|
||||
class PauseJournal : public Journal
|
||||
{
|
||||
public:
|
||||
explicit PauseJournal(int presentationTime)
|
||||
: Journal()
|
||||
, m_presentationTime(presentationTime)
|
||||
{}
|
||||
|
||||
QString getText() const override final;
|
||||
|
||||
int m_presentationTime;
|
||||
};
|
||||
|
||||
|
||||
class EndedJournal : public Journal
|
||||
{
|
||||
public:
|
||||
explicit EndedJournal(int presentationTime)
|
||||
: Journal()
|
||||
, m_presentationTime(presentationTime)
|
||||
{}
|
||||
|
||||
QString getText() const override final;
|
||||
|
||||
int m_presentationTime;
|
||||
};
|
||||
|
||||
|
||||
class StopJournal : public Journal
|
||||
{
|
||||
public:
|
||||
explicit StopJournal(int presentationTime)
|
||||
: Journal()
|
||||
, m_presentationTime(presentationTime)
|
||||
{}
|
||||
|
||||
QString getText() const override final;
|
||||
|
||||
int m_presentationTime;
|
||||
};
|
||||
|
||||
|
||||
class SetTimeJournal : public Journal
|
||||
{
|
||||
public:
|
||||
explicit SetTimeJournal(int toPresentationTime)
|
||||
: Journal()
|
||||
, m_toPresentationTime(toPresentationTime)
|
||||
{}
|
||||
|
||||
QString getText() const override final;
|
||||
|
||||
int m_toPresentationTime;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
#include "pre_screen.h"
|
||||
|
||||
#include <QStyleOption>
|
||||
#include <QtGui/QPainter>
|
||||
|
||||
|
||||
Screen::Screen()
|
||||
: QWidget()
|
||||
{
|
||||
setBgColor(QColor("black"));
|
||||
setContentsMargins(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
Screen::~Screen()
|
||||
{
|
||||
const auto p1Widgets = findChildren<QWidget *>(QString(), Qt::FindDirectChildrenOnly);
|
||||
for (QWidget *w : p1Widgets)
|
||||
w->setParent(nullptr);
|
||||
}
|
||||
|
||||
|
||||
void Screen::setBgColor(const QColor &color)
|
||||
{
|
||||
setStyleSheet(QStringLiteral("Screen { background: %1; background-color: %1; }").arg(color.name()));
|
||||
}
|
||||
|
||||
|
||||
void Screen::paintEvent(QPaintEvent *)
|
||||
{
|
||||
QStyleOption opt;
|
||||
opt.init(this);
|
||||
QPainter p(this);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
|
||||
class Screen : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Screen();
|
||||
virtual ~Screen();
|
||||
|
||||
void setBgColor(const QColor &color);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *) override;
|
||||
};
|
||||
-3351
File diff suppressed because it is too large.
Load diff
-392
@@ -1,392 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "pre_screen.h"
|
||||
#include "pre_journal_types.h"
|
||||
#include "pre_storyboard.h"
|
||||
#include "filter_topic.h"
|
||||
|
||||
#include <Core/core_dtc.h>
|
||||
#include <PluginInterfaces/topic_replay_interface.h>
|
||||
#include <LtsPluginManager/lts_plugin_manager.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtils/LtsUtilsGui/LtsUtilsGuiDds/request_helper.h>
|
||||
#include <LtsScriptTimeline/track_entry_painters.h>
|
||||
#include <LtsScriptTimeline/temporary_pointer_vector.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <PresentationManagement/Common/topic_assignment.h>
|
||||
#include <PresentationManagement/pre_dtc.h>
|
||||
#include <PresentationManagement/pre_ftc.h>
|
||||
#include <PresentationManagement/logger.h>
|
||||
#include <SituationReplayManagement/srm_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
|
||||
|
||||
|
||||
#include <SituationReplay/srp_gui_plugin_interface.h>
|
||||
#include <SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QMap>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace TakeHomePackageGenerator
|
||||
{
|
||||
class ExportProcess;
|
||||
}
|
||||
namespace Ui
|
||||
{
|
||||
class ScriptDialog;
|
||||
}
|
||||
namespace LtsScriptTimeline
|
||||
{
|
||||
class TrackEntry;
|
||||
}
|
||||
namespace SituationReplayManagement
|
||||
{
|
||||
class ForeignDataInterface;
|
||||
}
|
||||
namespace LtsPluginManager
|
||||
{
|
||||
class LtsPluginManager;
|
||||
}
|
||||
namespace Ui
|
||||
{
|
||||
class ScriptPlayerDialog;
|
||||
}
|
||||
namespace LtsScriptTimeline
|
||||
{
|
||||
class TrackEntry;
|
||||
}
|
||||
namespace LtsUtils
|
||||
{
|
||||
class Promise;
|
||||
}
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
class TopicDesigner;
|
||||
|
||||
namespace Interface
|
||||
{
|
||||
class Ftc;
|
||||
}
|
||||
|
||||
|
||||
class ScriptDialog : public LtsWidgets::LtsDialog
|
||||
, protected PresentationManagement::Interface::Ftc::PresentationModifyReplyHandler
|
||||
, protected PresentationManagement::Interface::Ftc::GetPresentationContentReplyHandler
|
||||
, protected SituationReplayManagement::Interface::Ftc::ReplayPartitionCreateReplyHandler
|
||||
, protected SituationReplayManagement::Interface::Ftc::ReplayPartitionRemoveReplyHandler
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ScriptDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ScriptDialog();
|
||||
|
||||
LtsSession::LtsSession *eVSession() { return m_essentialsViewSession; }
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
const int scriptId,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<SituationReplayManagement::ForeignDataInterface> &srmForeign,
|
||||
const std::shared_ptr<Core::Interface::Dtc> &coreDtc,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc);
|
||||
|
||||
void loadScript();
|
||||
TopicEditorBase::TopicEditor *createTopic(const TopicAssignment &ta);
|
||||
TopicEditorBase::TopicEditor *createTopic(const LtsScriptTimeline::TrackEntry &data);
|
||||
void createTopicFromTrackEntry(LtsScriptTimeline::TrackEntry *data);
|
||||
|
||||
bool topicStringToType(const QString &typeName, LtsScriptTimeline::TrackEntryType &tet) const;
|
||||
int getCurrentScriptEndTime() const;
|
||||
bool isEssentialsViewOpened() const;
|
||||
|
||||
static LtsScriptTimeline::TrackEntry *trackEntryFromContent(const PresentationManagement::PresentationContent &content,
|
||||
int topicId,
|
||||
LtsScriptTimeline::TrackEntryType trackType);
|
||||
|
||||
bool importTrackEntries(const QVector<LtsScriptTimeline::TrackEntry *> &tes);
|
||||
|
||||
std::shared_ptr<SituationReplay::ForeignGuiInterface> getReplayGuiIfc() const
|
||||
{
|
||||
return m_essentialsViewsSrpGuiIfc;
|
||||
}
|
||||
|
||||
private:
|
||||
enum class ProjectionWidget
|
||||
{
|
||||
Unknown = 0,
|
||||
Screen1,
|
||||
Screen2,
|
||||
};
|
||||
|
||||
|
||||
enum class SpecialTopicType
|
||||
{
|
||||
NonSpecial = 0,
|
||||
ReplayTopic,
|
||||
FilterTopic,
|
||||
};
|
||||
|
||||
|
||||
class PlayingTopic
|
||||
{
|
||||
public:
|
||||
PlayingTopic() = default;
|
||||
|
||||
~PlayingTopic()
|
||||
{
|
||||
if (topicReplayIfc != nullptr)
|
||||
{
|
||||
topicReplayIfc->playbackStop();
|
||||
delete topicReplayIfc;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
QString topicTypeName;
|
||||
LtsScriptTimeline::TrackEntry *topic = nullptr;
|
||||
TopicReplay::Interface *topicReplayIfc = nullptr;
|
||||
QWidget *replayWidget = nullptr;
|
||||
LtsScriptTimeline::TrackEntryType trackEntryType = LtsScriptTimeline::TrackEntryType::INVALID;
|
||||
bool isFilter = false;
|
||||
};
|
||||
|
||||
|
||||
void onPresentationModifyReply(const Core::FunctionReplyObject &replyObject) override { if (m_requestHelper != nullptr) m_requestHelper->requestReply(replyObject); }
|
||||
void onGetPresentationContentReply(const GetPresentationContentReply &reply) override { if (m_requestHelper != nullptr) m_requestHelper->requestReply(reply); }
|
||||
void onReplayPartitionCreateReply(const Core::FunctionReplyObject &reply) override { if (m_requestHelper != nullptr) m_requestHelper->requestReply(reply); }
|
||||
void onReplayPartitionRemoveReply(const Core::FunctionReplyObject &) override { }
|
||||
|
||||
void retranslate() override;
|
||||
bool apply() override;
|
||||
void aboutToClose() override;
|
||||
void getPresentationContent();
|
||||
TopicEditorBase::TopicEditor *createTopicEditor(LtsScriptTimeline::TrackEntry *te);
|
||||
bool topicTypeOnEssentialsView(LtsScriptTimeline::TrackEntryType tet) const;
|
||||
void startEssentialsViewStage2(const Core::ReplayPartition &replay);
|
||||
bool tryAddTopics(QStringList &resultList);
|
||||
void fillTopicVector();
|
||||
void createSitMapApp();
|
||||
void startReplaySession();
|
||||
void exportPresentationContent(const Core::FunctionReply &baseReply);
|
||||
void disableSessionDialog(LtsSession::LtsSession *pSession, bool disable);
|
||||
void deletePlayingTopic(PlayingTopic *playingTopic);
|
||||
static QString toReadableTime(qint64 seconds);
|
||||
ProjectionWidget identifyProjectionWidget(LtsScriptTimeline::TrackEntry *topic) const;
|
||||
bool usesAvsWindow(LtsScriptTimeline::TrackEntryType trackEntryType) const;
|
||||
void playTopic(LtsScriptTimeline::TrackEntry *topic);
|
||||
bool enableFireEventFlash(bool enable);
|
||||
void pausePlayingTopics();
|
||||
static bool isFilter(LtsScriptTimeline::TrackEntryType tet);
|
||||
void initProjectionWidget(Screen **pointerToWidgetPointer);
|
||||
void deleteProjectionWidget(Screen **pointerToWidgetPointer);
|
||||
bool _tryAddTopic(LtsScriptTimeline::TrackEntryType trackEntryType,
|
||||
const std::shared_ptr<TopicEditorBase::Interface> &topicEditorIfc,
|
||||
const std::shared_ptr<TopicReplay::Factory> &topicReplayFactory,
|
||||
const std::shared_ptr<TopicReplay::Factory> &topicExportFactory,
|
||||
QStringList &resultList,
|
||||
const SpecialTopicType &specialTopicType = SpecialTopicType::NonSpecial);
|
||||
void initFailed(int reason);
|
||||
void setFreestanding(bool freestanding, const ProjectionWidget &pw);
|
||||
void setReplayWidgetFreestanding(PlayingTopic *playingTopic, bool freestanding);
|
||||
void printCurrentlyPlayingTopics();
|
||||
void addReplayWidget(PlayingTopic *playingTopic, QWidget *replayWidget);
|
||||
Screen *getProjectionWidget(const ScriptDialog::ProjectionWidget &projectionWidget);
|
||||
bool isScreenFreestanding(const ProjectionWidget &pw) const;
|
||||
void previewSecond(int time, int ignoreTopicForReplay = -1);
|
||||
void setReplayWidgetPosition(PlayingTopic *playingTopic);
|
||||
void avsFreestandingHack(bool freestanding, QWidget *projectionWidget, QWidget **parentForScreen);
|
||||
void avsVisibilityHack(QWidget *parentForScreen, bool visible);
|
||||
void stop(bool ended = false, bool ignoreFireEventFlashing = false);
|
||||
void changelogCheck();
|
||||
int previousTopicTime() const;
|
||||
bool hasPreviousTopic() const { return previousTopicTime() > -1; }
|
||||
int nextTopicTime() const;
|
||||
bool hasNextTopic() const { return nextTopicTime() > -1; }
|
||||
void setPositionTime(int positionTime, bool setByUser = false);
|
||||
void setPositionTimeActive(int positionTime, bool setByUser = false);
|
||||
|
||||
|
||||
template <typename TopicEditorInterface>
|
||||
std::shared_ptr<TopicEditorBase::Interface> getTopicEditorIfc(LtsScriptTimeline::TrackEntryType trackEntryType)
|
||||
{
|
||||
std::shared_ptr<TopicEditorBase::Interface> topicEditorIfc;
|
||||
|
||||
if (!m_exerciseSession->interfaceFromGui<TopicEditorInterface>(topicEditorIfc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "getTopicEditorIfc failed: Cannot add topic type "
|
||||
<< LtsScriptTimeline::trackEntryTypeName(trackEntryType)
|
||||
<< " because topic editor ifc is missing.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return topicEditorIfc;
|
||||
}
|
||||
|
||||
|
||||
template <typename TopicReplayInterface>
|
||||
std::shared_ptr<TopicReplay::Factory> getTopicReplayFactory(LtsScriptTimeline::TrackEntryType trackEntryType)
|
||||
{
|
||||
std::shared_ptr<TopicReplay::Factory> topicReplayFactory;
|
||||
|
||||
if (!m_replaySession->interfaceFromGui<TopicReplayInterface>(topicReplayFactory))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "getTopicIfcFactory failed: Cannot add topic type "
|
||||
<< LtsScriptTimeline::trackEntryTypeName(trackEntryType)
|
||||
<< " because topic ifc factory is missing.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return topicReplayFactory;
|
||||
}
|
||||
|
||||
|
||||
template <typename TopicEditorGuiInterface,
|
||||
typename TopicReplayFactory = TopicReplay::Factory,
|
||||
typename TopicExportFactory = TopicReplayFactory>
|
||||
bool tryAddTopic(LtsScriptTimeline::TrackEntryType trackEntryType,
|
||||
QStringList &resultList,
|
||||
const SpecialTopicType &specialTopicType = SpecialTopicType::NonSpecial)
|
||||
{
|
||||
std::shared_ptr<TopicEditorBase::Interface> topicEditorIfc;
|
||||
std::shared_ptr<TopicReplay::Factory> topicReplayFactory;
|
||||
std::shared_ptr<TopicReplay::Factory> topicExportFactory;
|
||||
|
||||
if (!std::is_same<TopicEditorBase::Interface, TopicEditorGuiInterface>::value)
|
||||
{
|
||||
topicEditorIfc = getTopicEditorIfc<TopicEditorGuiInterface>(trackEntryType);
|
||||
|
||||
if (topicEditorIfc == nullptr)
|
||||
{
|
||||
resultList.append(LtsScriptTimeline::trackEntryTypeName(trackEntryType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!std::is_same<TopicReplay::Factory, TopicReplayFactory>::value)
|
||||
{
|
||||
topicReplayFactory = getTopicReplayFactory<TopicReplayFactory>(trackEntryType);
|
||||
|
||||
if (topicReplayFactory == nullptr)
|
||||
{
|
||||
resultList.append(LtsScriptTimeline::trackEntryTypeName(trackEntryType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!std::is_same<TopicReplay::Factory, TopicExportFactory>::value)
|
||||
{
|
||||
topicExportFactory = getTopicReplayFactory<TopicExportFactory>(trackEntryType);
|
||||
|
||||
if (topicExportFactory == nullptr)
|
||||
{
|
||||
resultList.append(LtsScriptTimeline::trackEntryTypeName(trackEntryType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
topicExportFactory = topicReplayFactory;
|
||||
|
||||
return _tryAddTopic(trackEntryType, topicEditorIfc, topicReplayFactory, topicExportFactory, resultList, specialTopicType);
|
||||
}
|
||||
|
||||
|
||||
Ui::ScriptDialog *m_ui;
|
||||
LtsSession::LtsSession *m_essentialsViewSession;
|
||||
std::shared_ptr<SituationReplay::ForeignGuiInterface> m_essentialsViewsSrpGuiIfc;
|
||||
std::shared_ptr<PresentationManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<PresentationManagement::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<SituationReplayManagement::ForeignDataInterface> m_srmForeign;
|
||||
std::shared_ptr<Core::Interface::Dtc> m_coreDtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
|
||||
QString m_menuGroup;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
int m_selectedTeId;
|
||||
TopicEditorBase::TopicEditor *m_currentTopicEditor;
|
||||
int m_scriptId;
|
||||
QMap<QString, TopicAssignment> m_trackEntryAssignments;
|
||||
QMap<LtsScriptTimeline::TrackEntryType, TopicAssignment> m_trackEntryToTopicAssignment;
|
||||
LtsPluginManager::LtsPluginManager *m_essentialsViewApp;
|
||||
QString m_scriptName;
|
||||
QString m_scriptOwner;
|
||||
qint64 m_lastModified = 0;
|
||||
QVector<LtsScriptTimeline::TrackEntry *> m_topicVector;
|
||||
QMultiMap<int, LtsScriptTimeline::TrackEntry *> m_topicMap;
|
||||
QVector<FilterTopic> m_filterTopicVector;
|
||||
TakeHomePackageGenerator::ExportProcess *m_exportProcess;
|
||||
LtsSession::LtsSession *m_exerciseSession;
|
||||
LtsSession::LtsSession *m_replaySession;
|
||||
QTimer *m_presentationTimer;
|
||||
int m_lowestTime;
|
||||
int m_highestTime;
|
||||
int m_positionTime;
|
||||
int m_duration;
|
||||
int m_nextPauseTime;
|
||||
QVector<PlayingTopic *> m_currentlyPlayingTopics;
|
||||
Screen *m_projectionWidget1;
|
||||
Screen *m_projectionWidget2;
|
||||
MainJournal m_journal;
|
||||
int m_scriptsExerciseId;
|
||||
QString m_exerciseName;
|
||||
LtsPluginManager::LtsPluginManager *m_sitMapApp;
|
||||
LtsSession::LtsSession *m_sitMapSession;
|
||||
bool m_currentlyFreestandingTopicsScreen1;
|
||||
bool m_currentlyFreestandingTopicsScreen2;
|
||||
TopicReplay::Interface *m_sitMapTopicIfc;
|
||||
bool m_firstPlayAfterStop;
|
||||
bool m_enableApply;
|
||||
bool m_stopAfterPlayingFilterTopic;
|
||||
QWidget *m_previousParentForScreen1;
|
||||
QWidget *m_previousParentForScreen2;
|
||||
int m_ignoreTopicForReplay;
|
||||
QPointer<TopicDesigner> m_currentTopicDesigner;
|
||||
bool m_avsVisibilityHackActive;
|
||||
QPointer<StoryboardDialog> m_storyboardDialog;
|
||||
bool m_ignoreChanges;
|
||||
bool m_scriptRunning;
|
||||
bool m_bTimerTickRecursionGuard;
|
||||
bool m_isPlayTopicMethodStillRunning;
|
||||
private slots:
|
||||
void slotEditEntry(const int topicId);
|
||||
void slotTrackEntrySelectionChanged(LtsScriptTimeline::TrackEntry *);
|
||||
void slotChangesWereMade();
|
||||
void slotTrackEntryModified();
|
||||
void slotNull(QObject *obj);
|
||||
void slotDiscard();
|
||||
void slotStartEssentialsView();
|
||||
void slotLoadScript();
|
||||
void slotExportScript();
|
||||
void slotExportSuccessful(const QString &path, const QString &failedTopics);
|
||||
void slotBurnDvD(const QString &strExportPath);
|
||||
void slotBurningFinished(bool success);
|
||||
void slotPlay();
|
||||
void slotPause();
|
||||
void slotStop();
|
||||
void slotTimerTick();
|
||||
void slotShowStoryboard();
|
||||
void slotShowJournal();
|
||||
void slotToNextTopic();
|
||||
void slotToPreviousTopic();
|
||||
void slotPlayUntilNextTopic();
|
||||
void slotSetTopicPosition(QWidget *previewWidget, int ignoreTopicForReplay);
|
||||
void slotTrackEntryDeleted(const int topicId);
|
||||
void slotEditSelectedEntry();
|
||||
void slotCheckNewTopicLength(int newLength, LtsUtils::Promise *promise);
|
||||
void slotAddFakeLegacyPlanTopic();
|
||||
|
||||
void slotChangesMade();
|
||||
};
|
||||
|
||||
}
|
||||
-320
@@ -1,320 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ScriptDialog</class>
|
||||
<widget class="QWidget" name="ScriptDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1010</width>
|
||||
<height>587</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Script Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="999,0">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="LtsScriptTimeline::ScriptTimeline" name="widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="replayControls">
|
||||
<property name="title">
|
||||
<string>Replay Controls</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<widget class="QWidget" name="replayControlsWidget" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,999">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="replayControlsLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="replayControlsMainLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="replayControlsScreensLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbInitScr1">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Set Screen 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbInitScr2">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Set Screen 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbStop">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Stop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPause">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pause</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPlay">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Play</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="replayControlsJumpLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbUntilNextTopic">
|
||||
<property name="text">
|
||||
<string>Play Until Next Topic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPreviousTopic">
|
||||
<property name="text">
|
||||
<string>Previous Topic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbNextTopic">
|
||||
<property name="text">
|
||||
<string>Next Topic</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="replayInfoLayout">
|
||||
<property name="horizontalSpacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="verticalSpacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="durationLabel">
|
||||
<property name="text">
|
||||
<string>Presentation duration:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblDuration">
|
||||
<property name="text">
|
||||
<string notr="true"> - </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="posLabel">
|
||||
<property name="text">
|
||||
<string>Pos:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSlider" name="posSlider">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::TicksBelow</enum>
|
||||
</property>
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="currentPosLabel">
|
||||
<property name="text">
|
||||
<string>Current position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="currentositionLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblPos">
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="slashLabel">
|
||||
<property name="text">
|
||||
<string>/</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblMax">
|
||||
<property name="text">
|
||||
<string notr="true">0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<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>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="statusLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="text">
|
||||
<string>Status:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="lwStatus">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="showDropIndicator" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="movement">
|
||||
<enum>QListView::Free</enum>
|
||||
</property>
|
||||
<property name="isWrapping" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsScriptTimeline::ScriptTimeline</class>
|
||||
<extends>QWidget</extends>
|
||||
<header location="global">LtsScriptTimeline/script_timeline.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
-369
@@ -1,369 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "pre_script_gui_plugin.h"
|
||||
#include "pre_script_dialog.h"
|
||||
|
||||
#include <OperatorManagement/opm_data_plugin_interface.h>
|
||||
#include <PresentationManagement/Script/Common/ScriptChooser/script_chooser.h>
|
||||
#include <PresentationManagement/Common/pre_edit_dialog.h>
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_manager.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsWidgets/lts_background_widget.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <LtsScriptTimeline/track_entry.h>
|
||||
#include <LtsScriptTimeline/temporary_pointer_vector.h>
|
||||
#include <Common/TopicEditorBase/topic_editor_base.h>
|
||||
|
||||
|
||||
#include <SituationReplay/srp_gui_plugin_interface.h>
|
||||
#include <SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <BuildingViewer/bdv_viewer_gui_plugin_interface.h>
|
||||
#include <AudioVideoManagement/avm_menu_edit_gui_plugin_interface.h>
|
||||
#include <SituationMapPlugin/situation_map_script_filter_gui_plugin_interface.h>
|
||||
#include <MarkerManagement/mrk_gui_plugin_interface.h>
|
||||
#include <Evaluations/evl_gui_plugin_interface.h>
|
||||
#include <ReportManagement/rep_gui_plugin_interface.h>
|
||||
#include <PlanOverlays/plan_overlays_plugin_interface.h>
|
||||
#include <PresentationManagement/pre_operator_rights.h>
|
||||
#include <PresentationManagement/pre_dtc.h>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QJsonParseError>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtWidgets/QProgressDialog>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Pre.Script"))
|
||||
, m_dtc(nullptr)
|
||||
, m_opmDtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_repForeign(nullptr)
|
||||
, m_scriptDialog(nullptr)
|
||||
, m_scriptId(0)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
{
|
||||
connect(this, &InterfaceImpl::signalSuccess, m_session, &LtsSession::LtsSession::slotExecuteNextPayload, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
{
|
||||
LtsWidgets::PluginData data;
|
||||
data.menuGroup = menuGroup();
|
||||
data.identifier = QStringLiteral("PresentationManagement.ScriptDialog");
|
||||
data.menuText = tr("Show Script Editor");
|
||||
|
||||
if (getFlags().testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN))
|
||||
{
|
||||
data.layoutArea = LtsWidgets::LayoutArea::eMainTab;
|
||||
data.createInstant = LtsWidgets::CreateInstantType::CreateInstantAndDiscardAction;
|
||||
data.closable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data.layoutArea = LtsWidgets::LayoutArea::eDialogTab;
|
||||
}
|
||||
data.operatorRight = OperatorRights::ScriptEditorShow;
|
||||
data.createWidgetFunc = [this](QWidget *parent)
|
||||
{
|
||||
return onShowScriptDialog(parent);
|
||||
};
|
||||
|
||||
ret.append(data);
|
||||
}
|
||||
|
||||
{
|
||||
LtsWidgets::PluginData data;
|
||||
data.menuGroup = menuGroup();
|
||||
data.identifier = QLatin1String("PresentationManagement.ScriptDialog.ImportScript");
|
||||
data.menuIcon = QIcon(QLatin1String("icon:import_documents.svg"));
|
||||
data.menuText = tr("Insert Script");
|
||||
data.operatorRight = OperatorRights::ScriptEditorEdit;
|
||||
data.directFunc = [this](const LtsWidgets::PluginData &)
|
||||
{
|
||||
return onImportScript();
|
||||
};
|
||||
data.createWidgetFunc = nullptr;
|
||||
|
||||
ret.append(data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<PresentationManagement::DataInterface>(m_dtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getDtc for PresentationManagement::DataInterface failed.";
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getFtc<PresentationManagement::DataInterface>(m_ftc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getFtc for PresentationManagement::DataInterface failed.";
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getDtc<OperatorManagement::DataInterface>(m_opmDtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getDtc for OperatorManagement::DataInterface failed.";
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getDtc<SituationReplayManagement::DataInterface>(m_coreDtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getDtc for SituationReplayManagement::DataInterface failed.";
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getForeignDataInterface<SituationReplayManagement::DataInterface>(m_repForeign))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "getForeignDataInterface for SituationReplayManagement::DataInterface failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_repForeign = nullptr;
|
||||
m_coreDtc = nullptr;
|
||||
m_opmDtc = nullptr;
|
||||
m_ftc = nullptr;
|
||||
m_dtc = nullptr;
|
||||
}
|
||||
|
||||
|
||||
QString InterfaceImpl::menuGroup() const
|
||||
{
|
||||
return tr("Presentation");
|
||||
}
|
||||
|
||||
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowScriptDialog(QWidget *parent)
|
||||
{
|
||||
m_scriptDialog = new ScriptDialog(menuGroup(), parent);
|
||||
|
||||
if (!m_scriptDialog->init(m_session, m_scriptId, m_dtc, m_ftc, m_repForeign, m_coreDtc, m_opmDtc))
|
||||
{
|
||||
m_scriptDialog->deleteLater();
|
||||
m_scriptDialog = nullptr;
|
||||
|
||||
|
||||
emit m_session->signalClose();
|
||||
}
|
||||
|
||||
return m_scriptDialog.data();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::onImportScript()
|
||||
{
|
||||
ScriptChooser *scriptChooser = new ScriptChooser(m_dtc, m_opmDtc, false, true);
|
||||
scriptChooser->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
connect(scriptChooser, &ScriptChooser::signalSelectScript,
|
||||
this, &InterfaceImpl::slotImportScript, Qt::QueuedConnection);
|
||||
|
||||
connect(scriptChooser, &ScriptChooser::signalQuit,
|
||||
m_session, &LtsSession::LtsSession::signalQuit);
|
||||
|
||||
if (!LtsSessionData::LtsSessionData::getInstance()->isTablet())
|
||||
scriptChooser->setModal(true);
|
||||
scriptChooser->show();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::slotNewScript()
|
||||
{
|
||||
|
||||
PresentationModifyRequest req;
|
||||
req.name(tr("New Script").toStdString());
|
||||
req.description(tr("No description available.").toStdString());
|
||||
req.operatorId(LtsSessionData::LtsSessionData::getInstance()->getOperatorId());
|
||||
req.lastModified(QDateTime::currentMSecsSinceEpoch());
|
||||
req.fileStatus(FileStatus::Valid);
|
||||
|
||||
if (m_requestHelper->startSingleRequest([this, req]()
|
||||
{
|
||||
return m_ftc->presentationModifyRequest(req, this);
|
||||
}))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::slotAddScript()
|
||||
{
|
||||
PresentationEditDialog *dialog = new PresentationEditDialog(nullptr);
|
||||
if (!dialog->init(-1 , m_dtc, m_ftc, m_opmDtc))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
|
||||
QObject::connect(dialog, &PresentationEditDialog::rejected, dialog, &PresentationEditDialog::deleteLater);
|
||||
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::executePayload(LtsWidgets::LtsBackgroundWidget *mainBackground)
|
||||
{
|
||||
Q_UNUSED(mainBackground);
|
||||
|
||||
if (m_session->partitionType() != IDL::PartitionType::Exercise)
|
||||
{
|
||||
emit signalSuccess();
|
||||
return;
|
||||
}
|
||||
|
||||
int scriptId = m_session->getSavegame()[QStringLiteral("ScriptId")].toInt();
|
||||
if (scriptId > 0)
|
||||
{
|
||||
slotSelectScript(scriptId);
|
||||
return;
|
||||
}
|
||||
|
||||
ScriptChooser *scriptChooser = new ScriptChooser(m_dtc, m_opmDtc, false, false, mainBackground);
|
||||
scriptChooser->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
connect(scriptChooser, &ScriptChooser::signalSelectScript,
|
||||
this, &InterfaceImpl::slotSelectScript, Qt::QueuedConnection);
|
||||
|
||||
connect(scriptChooser, &ScriptChooser::signalQuit,
|
||||
m_session, &LtsSession::LtsSession::signalQuit);
|
||||
|
||||
connect(scriptChooser, &ScriptChooser::signalNewScript,
|
||||
this, &InterfaceImpl::slotAddScript);
|
||||
|
||||
if (!LtsSessionData::LtsSessionData::getInstance()->isTablet())
|
||||
scriptChooser->setModal(true);
|
||||
|
||||
scriptChooser->show();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::slotSelectScript(int scriptId)
|
||||
{
|
||||
m_scriptId = scriptId;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
emit signalSuccess();
|
||||
}
|
||||
|
||||
|
||||
void InterfaceImpl::slotImportScript(int scriptId)
|
||||
{
|
||||
if (m_scriptId == scriptId)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Not possible to import same script!";
|
||||
LtsWidgets::LtsMessageDialog::showMessage(m_session->baseLayout(), tr("Not possible to import same script!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!importScript(scriptId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Failed to import script Id " << scriptId;
|
||||
LtsWidgets::LtsMessageDialog::showMessage(m_session->baseLayout(), tr("Failed to import Script Id %1").arg(scriptId));
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "Succesfully imported script Id " << scriptId ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceImpl::importScript(int idSource)
|
||||
{
|
||||
if (!m_scriptDialog)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "no script dialog open for import script";
|
||||
return false;
|
||||
}
|
||||
|
||||
PresentationManagement::Presentation preSource = m_dtc->presentation(idSource);
|
||||
|
||||
if (preSource.id() < 1)
|
||||
return false;
|
||||
|
||||
|
||||
std::function<void(const Core::FunctionReply &baseReply)> importPresentationContent = [&](const Core::FunctionReply &baseReply)
|
||||
{
|
||||
const GetPresentationContentReply &reply = static_cast<const GetPresentationContentReply &>(baseReply);
|
||||
const auto &contentList = reply.content();
|
||||
|
||||
if (contentList.size() < 1)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "No Presentation Content for Script Id " << reply.id();
|
||||
return;
|
||||
}
|
||||
|
||||
LtsScriptTimeline::TemporaryPointerVector<LtsScriptTimeline::TrackEntry *> importedTes;
|
||||
|
||||
for (const PresentationManagement::PresentationContent &content : contentList)
|
||||
{
|
||||
LtsScriptTimeline::TrackEntryType tet = LtsScriptTimeline::TrackEntryType::INVALID;
|
||||
|
||||
if (!m_scriptDialog->topicStringToType(QString::fromStdString(content.presentationTopicType()), tet))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Topic ignored - invalid topic type for presentation's content id " << content.id();
|
||||
continue;
|
||||
}
|
||||
|
||||
importedTes.append(ScriptDialog::trackEntryFromContent(content, 0, tet));
|
||||
}
|
||||
|
||||
if (m_scriptDialog->importTrackEntries(importedTes))
|
||||
importedTes.setDiscardable(false);
|
||||
};
|
||||
|
||||
|
||||
GetPresentationContentRequest req(idSource);
|
||||
req.presentationId(idSource);
|
||||
|
||||
if (!m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->getPresentationContentRequest(req, this);
|
||||
}, importPresentationContent))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(m_session->baseLayout(), tr("There is no content to import for this script."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PresentationManagement/logger.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <PresentationManagement/pre_data_plugin_interface.h>
|
||||
#include <PresentationManagement/pre_script_gui_plugin_interface.h>
|
||||
#include <PresentationManagement/pre_ftc.h>
|
||||
#include <OperatorManagement/opm_dtc.h>
|
||||
#include <SituationReplayManagement/srm_data_plugin_interface.h>
|
||||
#include <Lts/Common/ProjectConfig/project_defines.h>
|
||||
#include <LtsUtils/LtsUtilsGui/LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
#include <LtsScriptTimeline/track_entry_painters.h>
|
||||
#include "pre_script_dialog.h"
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <PluginInterfaces/topic_replay_interface.h>
|
||||
#include <PresentationManagement/Common/topic_assignment.h>
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "gui:3:pre.script.edit")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
public:
|
||||
explicit GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return ForeignScriptDialogGuiInterface::pluginName(); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{ return (partition == IDL::PartitionType::Exercise); }
|
||||
};
|
||||
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface
|
||||
, protected PresentationManagement::Interface::Ftc::PresentationModifyReplyHandler
|
||||
, protected PresentationManagement::Interface::Ftc::GetPresentationContentReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
QString menuGroup() const override;
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{ return partition == IDL::PartitionType::Exercise; }
|
||||
|
||||
|
||||
int executionPriority() const override { return 9999; }
|
||||
void executePayload(LtsWidgets::LtsBackgroundWidget *mainBackground) override;
|
||||
|
||||
protected:
|
||||
void onPresentationModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onGetPresentationContentReply(const GetPresentationContentReply &reply) override { m_requestHelper->requestReply(reply); }
|
||||
|
||||
private:
|
||||
LtsWidgets::LtsDialog *onShowScriptDialog(QWidget *parent);
|
||||
void onImportScript();
|
||||
bool importScript(int idSource);
|
||||
|
||||
std::shared_ptr<PresentationManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
|
||||
std::shared_ptr<PresentationManagement::Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<SituationReplayManagement::ForeignDataInterface> m_repForeign;
|
||||
std::shared_ptr<Core::Interface::Dtc> m_coreDtc;
|
||||
|
||||
QPointer<PresentationManagement::ScriptDialog> m_scriptDialog;
|
||||
int m_scriptId;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
signals:
|
||||
void signalSuccess();
|
||||
|
||||
private slots:
|
||||
void slotSelectScript(int scriptId);
|
||||
void slotNewScript();
|
||||
void slotImportScript(int scriptId);
|
||||
void slotAddScript();
|
||||
};
|
||||
|
||||
}
|
||||
-153
@@ -1,153 +0,0 @@
|
||||
#include "pre_storyboard.h"
|
||||
#include <utility>
|
||||
#include "ui_pre_storyboard.h"
|
||||
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <LtsScriptTimeline/track_entry.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
|
||||
using namespace LtsScriptTimeline;
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
StoryboardDialog::StoryboardDialog(QWidget *parent, LtsSession::LtsSession *session)
|
||||
: LtsWidgets::LtsDialog(parent)
|
||||
, m_ui(new Ui::StoryboardDialog)
|
||||
, m_session(session)
|
||||
, m_alreadyTranslated(false)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &StoryboardDialog::slotPrint);
|
||||
}
|
||||
|
||||
|
||||
StoryboardDialog::~StoryboardDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void StoryboardDialog::slotPrint()
|
||||
{
|
||||
QString headingHtml = (QStringLiteral("<H1>"));
|
||||
headingHtml.append (tr("Scriptname:"));
|
||||
headingHtml.append(m_scriptName);
|
||||
headingHtml.append(QStringLiteral("</H1>"));
|
||||
headingHtml.append(QStringLiteral("<H3>"));
|
||||
headingHtml.append(tr("Script Owner: "));
|
||||
headingHtml.append(m_scriptOwner);
|
||||
headingHtml.append(QStringLiteral("</H3>"));
|
||||
headingHtml.append(QStringLiteral("<H3>"));
|
||||
headingHtml.append(tr("Last modified: "));
|
||||
headingHtml.append(DTG::toStringMSec(m_lastModified));
|
||||
headingHtml.append(QStringLiteral("<br>"));
|
||||
headingHtml.append(tr("Duration: "));
|
||||
QString durationStr = m_duration;
|
||||
headingHtml.append(durationStr);
|
||||
headingHtml.append(QStringLiteral("</H3><br>"));
|
||||
|
||||
LtsPrinting::printView(m_session, this, m_ui->listWidget, headingHtml);
|
||||
}
|
||||
|
||||
|
||||
bool StoryboardDialog::init(const QVector<LtsScriptTimeline::TrackEntry *> &topicVector,
|
||||
const QVector<FilterTopic> &filterTopicVector,
|
||||
const QString &scriptName,
|
||||
const QString &scriptOwner,
|
||||
const qint64 lastModified,
|
||||
const QString duration)
|
||||
{
|
||||
m_topicVector = topicVector;
|
||||
m_filterTopicVector = filterTopicVector;
|
||||
m_scriptName = scriptName;
|
||||
m_scriptOwner = scriptOwner;
|
||||
m_lastModified = lastModified;
|
||||
m_duration = duration;
|
||||
|
||||
|
||||
std::sort(m_topicVector.begin(), m_topicVector.end(), [](const TrackEntry *a, const TrackEntry *b) -> bool
|
||||
{
|
||||
return a->m_startTime < b->m_startTime;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void StoryboardDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Script Storyboard"));
|
||||
|
||||
if (m_alreadyTranslated)
|
||||
return;
|
||||
|
||||
fillStoryboard();
|
||||
m_alreadyTranslated = true;
|
||||
}
|
||||
|
||||
|
||||
void StoryboardDialog::fillStoryboard()
|
||||
{
|
||||
m_ui->listWidget->clear();
|
||||
|
||||
QVector<FilterTopic> correspondingFilterTopics;
|
||||
int ii1 = 1;
|
||||
for (const LtsScriptTimeline::TrackEntry *te : std::as_const(m_topicVector))
|
||||
{
|
||||
QString itemText = tr("Topic %1: %2 - %3 (%4 seconds)\n Type: %5").arg(
|
||||
ii1).arg(QTime::fromMSecsSinceStartOfDay(te->m_startTime * 1000).toString(),
|
||||
QTime::fromMSecsSinceStartOfDay((te->m_startTime + te->m_length) * 1000).toString()).arg(
|
||||
te->m_length).arg(LtsScriptTimeline::translateTrackEntryType(te->m_type));
|
||||
|
||||
if (!te->m_description.isEmpty())
|
||||
itemText += QStringLiteral("\n ") + tr("Description: %1").arg(te->m_description);
|
||||
|
||||
m_ui->listWidget->addItem(itemText);
|
||||
|
||||
|
||||
|
||||
correspondingFilterTopics.clear();
|
||||
for (const FilterTopic &_ft : std::as_const(m_filterTopicVector))
|
||||
{
|
||||
if (_ft.mainTopicId != te->m_topicId)
|
||||
continue;
|
||||
|
||||
correspondingFilterTopics.append(_ft);
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::sort(correspondingFilterTopics.begin(), correspondingFilterTopics.end(), [](const FilterTopic &a, const FilterTopic &b) -> bool
|
||||
{
|
||||
return a.filterTopic->m_startTime < b.filterTopic->m_startTime;
|
||||
});
|
||||
|
||||
|
||||
int ii2 = 1;
|
||||
for (const FilterTopic &_ft : std::as_const(correspondingFilterTopics))
|
||||
{
|
||||
if (_ft.mainTopicId != te->m_topicId)
|
||||
continue;
|
||||
|
||||
const LtsScriptTimeline::TrackEntry *fte = _ft.filterTopic;
|
||||
|
||||
QString filterItemText = tr(" > Filter %1: %2 - %3 (%4 seconds)\n Type: %5").arg(
|
||||
ii2).arg(QTime::fromMSecsSinceStartOfDay(fte->m_startTime * 1000).toString(),
|
||||
QTime::fromMSecsSinceStartOfDay((fte->m_startTime + te->m_length) * 1000).toString()).arg(
|
||||
fte->m_length).arg(LtsScriptTimeline::translateTrackEntryType(te->m_type));
|
||||
|
||||
if (!fte->m_description.isEmpty())
|
||||
filterItemText += QStringLiteral("\n ") + tr("Description: %1").arg(fte->m_description);
|
||||
|
||||
m_ui->listWidget->addItem(filterItemText);
|
||||
|
||||
ii2++;
|
||||
}
|
||||
|
||||
ii1++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "filter_topic.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsScriptTimeline/track_entry.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
#include <QtCore/QVector>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class StoryboardDialog;
|
||||
}
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
class StoryboardDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StoryboardDialog(QWidget *parent, LtsSession::LtsSession *session);
|
||||
~StoryboardDialog();
|
||||
bool init(const QVector<LtsScriptTimeline::TrackEntry *> &topicVector,
|
||||
const QVector<FilterTopic> &filterTopicVector,
|
||||
const QString &scriptName,
|
||||
const QString &scriptOwner,
|
||||
const qint64 lastModified,
|
||||
const QString duration);
|
||||
void fillStoryboard();
|
||||
void retranslate() override final;
|
||||
|
||||
private:
|
||||
Ui::StoryboardDialog *m_ui;
|
||||
QVector<LtsScriptTimeline::TrackEntry *> m_topicVector;
|
||||
QVector<FilterTopic> m_filterTopicVector;
|
||||
LtsSession::LtsSession *m_session;
|
||||
QString m_scriptName = QString();
|
||||
QString m_scriptOwner = QString();
|
||||
qint64 m_lastModified = 0;
|
||||
QString m_duration = QString();
|
||||
bool m_alreadyTranslated;
|
||||
|
||||
public slots:
|
||||
void slotPrint();
|
||||
};
|
||||
|
||||
}
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>StoryboardDialog</class>
|
||||
<widget class="QWidget" name="StoryboardDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>707</width>
|
||||
<height>464</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Script Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "pre_topic_designer_dialog.h"
|
||||
#include "ui_pre_topic_designer_dialog.h"
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
TopicDesignerDialog::TopicDesignerDialog(QWidget *parent)
|
||||
: LtsDialog(parent)
|
||||
, m_ui(new Ui::TopicDesignerDialog)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
connect(m_ui->widget, &TopicDesigner::signalTopicSelected,
|
||||
this, &TopicDesignerDialog::signalTopicSelected);
|
||||
connect(m_ui->widget, &TopicDesigner::signalDeleteTrackEntry,
|
||||
this, &TopicDesignerDialog::signalDeleteTrackEntry);
|
||||
connect(m_ui->widget, &TopicDesigner::signalUnselect,
|
||||
this, &TopicDesignerDialog::signalUnselect);
|
||||
connect(m_ui->widget, &TopicDesigner::signalChangesMade,
|
||||
this, &LtsWidgets::LtsDialog::signalChangesMade);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TopicDesignerDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Topic Designer"));
|
||||
}
|
||||
|
||||
|
||||
TopicDesignerDialog::~TopicDesignerDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsScriptTimeline::TrackEntry *> TopicDesignerDialog::exportTopicList() const
|
||||
{
|
||||
return m_ui->widget->exportTopicList();
|
||||
}
|
||||
|
||||
|
||||
void TopicDesignerDialog::selectTopic(int topicId)
|
||||
{
|
||||
m_ui->widget->selectTopic(topicId);
|
||||
}
|
||||
|
||||
|
||||
void TopicDesignerDialog::loadTopicList(const QVector<LtsScriptTimeline::TrackEntry *> &topicsList)
|
||||
{
|
||||
m_ui->widget->loadTopicList(topicsList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <QtCore/QVector>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class TopicDesignerDialog;
|
||||
}
|
||||
|
||||
namespace LtsScriptTimeline
|
||||
{
|
||||
class TrackEntry;
|
||||
}
|
||||
|
||||
|
||||
namespace PresentationManagement
|
||||
{
|
||||
|
||||
class TopicDesignerDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
public:
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TopicDesignerDialog(QWidget *parent = nullptr);
|
||||
~TopicDesignerDialog();
|
||||
|
||||
void loadTopicList(const QVector<LtsScriptTimeline::TrackEntry *> &topicsList);
|
||||
QVector<LtsScriptTimeline::TrackEntry *> exportTopicList() const;
|
||||
void selectTopic(int topicId);
|
||||
|
||||
signals:
|
||||
void signalTopicSelected(int topicId);
|
||||
void signalDeleteTrackEntry(int topicId);
|
||||
void signalUnselect();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
|
||||
Ui::TopicDesignerDialog *m_ui;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
-122
@@ -1,122 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TopicDesignerDialog</class>
|
||||
<widget class="QWidget" name="TopicDesignerDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>338</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Script Editor</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string notr="true">Some text</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbToFront">
|
||||
<property name="text">
|
||||
<string>To Front</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbIncIdx">
|
||||
<property name="text">
|
||||
<string>Inc Idx</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbDecIdx">
|
||||
<property name="text">
|
||||
<string>Dec Idx</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbToBack">
|
||||
<property name="text">
|
||||
<string>To Back</string>
|
||||
</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>
|
||||
<item>
|
||||
<widget class="PresentationManagement::TopicDesigner" name="widget" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>300</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>PresentationManagement::TopicDesigner</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>topic_designer.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Mike Wille, SLSE, 2016-03-30
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(Data)
|
||||
ADD_SUBDIRECTORY(Gui)
|
||||
|
||||
#
|
||||
# Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(ScmGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scm_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
GuiPluginInterface
|
||||
)
|
||||
|
||||
#
|
||||
# Data Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(ScmDataPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/scm_data_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
DataPluginInterface
|
||||
svcScmCommon
|
||||
)
|
||||
@@ -1,20 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Mike Wille, SLSE, 2016-09-06
|
||||
#
|
||||
|
||||
#
|
||||
# Data Plugin
|
||||
#
|
||||
NGL_ADD_LIBRARY(WS ScmDataPlugin MODULE scm_data_plugin.cpp scm_data_plugin.h)
|
||||
set_target_properties(ScmDataPlugin PROPERTIES AUTOMOC ON)
|
||||
NGL_TARGET_LINK_LIBRARIES(ScmDataPlugin
|
||||
Qt6::Core
|
||||
ScmDataPluginInterface
|
||||
svcScmClient
|
||||
NGLLogger
|
||||
LtsSessionDataDds
|
||||
)
|
||||
NGL_INSTALL_TARGET(ScmDataPlugin)
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "scm_data_plugin.h"
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <LtsSession/lts_session_data_dds.h>
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
std::shared_ptr<DataPluginBase::Interface> DataPlugin::createDataInterface(LtsSession::LtsSessionDataDds *session)
|
||||
{
|
||||
std::shared_ptr<ServiceManagement::Interface::Dtc> dtc;
|
||||
std::shared_ptr<ServiceManagement::Interface::Ftc> ftc;
|
||||
if (!session->createTopicClient(dtc, ftc, false ,true))
|
||||
return std::shared_ptr<DataPluginBase::Interface>();
|
||||
return std::make_shared<DataInterfaceImpl>(dtc, ftc);
|
||||
}
|
||||
|
||||
DataInterfaceImpl::DataInterfaceImpl(const std::shared_ptr<ServiceManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ServiceManagement::Interface::Ftc> &ftc)
|
||||
: DataInterface()
|
||||
, m_dtc(dtc)
|
||||
, m_ftc(ftc)
|
||||
{}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ServiceManagement/scm_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
|
||||
class DataPlugin final : public DataPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "data:3:scm")
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPlugin() = default;
|
||||
~DataPlugin() = default;
|
||||
|
||||
QString pluginName() const override { return QStringLiteral("ServiceManagement"); }
|
||||
std::shared_ptr<DataPluginBase::Interface> createDataInterface(LtsSession::LtsSessionDataDds *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Global;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class DataInterfaceImpl final : public DataInterface
|
||||
{
|
||||
public:
|
||||
explicit DataInterfaceImpl(const std::shared_ptr<ServiceManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ServiceManagement::Interface::Ftc> &ftc);
|
||||
|
||||
std::shared_ptr<ServiceManagement::Interface::Dtc> getDtc() override { return m_dtc; }
|
||||
std::shared_ptr<ServiceManagement::Interface::Ftc> getFtc() override { return m_ftc; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<ServiceManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<ServiceManagement::Interface::Ftc> m_ftc;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Mike Wille, SLSE, 2016-03-30
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(ServiceEdit)
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Mike Wille, SLSE, 2016-03-30
|
||||
#
|
||||
|
||||
# Make ${Qt6_Widgets} optional
|
||||
if(QT6_GUI_AVAILABLE AND TARGET Qt6::Widgets)
|
||||
set(Qt6_Widgets ${Qt6_Widgets})
|
||||
else()
|
||||
set(Qt6_Widgets "")
|
||||
endif()
|
||||
|
||||
|
||||
SET(scm_edit_gui_SRCS
|
||||
scm_edit_gui_plugin.cpp
|
||||
scm_edit_gui_plugin.h
|
||||
scm_dialog.cpp
|
||||
scm_dialog.h
|
||||
scm_dialog_service.cpp
|
||||
scm_dialog_service.h
|
||||
scm_dialog_group.cpp
|
||||
scm_dialog_group.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(scm_edit_gui_SRCS
|
||||
scm_dialog.ui
|
||||
scm_dialog_service.ui
|
||||
scm_dialog_group.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS ScmEditGuiPlugin MODULE ${scm_edit_gui_SRCS})
|
||||
if(QT6_GUI_AVAILABLE)
|
||||
NGL_TARGET_LINK_LIBRARIES(ScmEditGuiPlugin
|
||||
NGLLogger
|
||||
ScmGuiPluginInterface
|
||||
ScmDataPluginInterface
|
||||
LtsSession
|
||||
${Qt6_Widgets}
|
||||
LtsWidgets
|
||||
LtsUtilsGuiDds
|
||||
svcScmCommon
|
||||
svcExmClient
|
||||
)
|
||||
endif()
|
||||
|
||||
NGL_INSTALL_TARGET(ScmEditGuiPlugin)
|
||||
-358
@@ -1,358 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
#include "scm_dialog.h"
|
||||
#include "ui_scm_dialog.h"
|
||||
|
||||
#include "scm_dialog_group.h"
|
||||
#include "scm_dialog_service.h"
|
||||
|
||||
#include <LtsUtils/LtsUtilsCore/data_modification_enum.h>
|
||||
|
||||
#include <QtWidgets/QVBoxLayout>
|
||||
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
|
||||
|
||||
|
||||
ServiceManagementDialog::ServiceManagementDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_ui(new Ui::ServiceManagementDialog)
|
||||
, m_dtcExm(nullptr)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
|
||||
m_ui->lbGroupsIndicator->hide();
|
||||
m_ui->lbExercise->hide();
|
||||
m_ui->lbServer->hide();
|
||||
m_ui->cbServer->hide();
|
||||
m_ui->cbExercise->hide();
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Administrator-Service_Management"));
|
||||
}
|
||||
|
||||
ServiceManagementDialog::~ServiceManagementDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void ServiceManagementDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Service Management"));
|
||||
}
|
||||
|
||||
|
||||
bool ServiceManagementDialog::init(const std::shared_ptr<ServiceManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ServiceManagement::Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &dtcExm)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
m_dtcExm = dtcExm;
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::groupInformationChanged,
|
||||
this, &ServiceManagementDialog::slotGroupInformationChanged);
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::serviceInformationChanged,
|
||||
this, &ServiceManagementDialog::slotServiceInformationChanged);
|
||||
|
||||
const QMap<qint32, ServiceManagement::GroupInformation> groupInfo = m_dtc->groupInformations();
|
||||
|
||||
if (groupInfo.isEmpty())
|
||||
{
|
||||
INFO_LOG(m_logger) << "initModel - no groups!";
|
||||
return true;
|
||||
}
|
||||
|
||||
m_ui->lbNoServices->hide();
|
||||
|
||||
INFO_LOG(m_logger) << "initModel - #group information: " << groupInfo.size();
|
||||
|
||||
|
||||
|
||||
QVector<int> servicesList;
|
||||
for (const ServiceManagement::GroupInformation &gi : groupInfo)
|
||||
{
|
||||
|
||||
|
||||
const int server = gi.domainId();
|
||||
const int exercise = gi.exercisePartitionId();
|
||||
const int32_t replayPartitionId = gi.replayPartitionId();
|
||||
const QString groupName = groupEnumToGroupName(gi.type());
|
||||
long long timestamp = gi.timestamp();
|
||||
|
||||
servicesList.clear();
|
||||
servicesList.reserve(gi.services().size());
|
||||
for (auto service : gi.services())
|
||||
servicesList.append(service);
|
||||
|
||||
addGroup(gi.type(), server, exercise, replayPartitionId, groupName, timestamp, servicesList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
auto cbSvc = [this](const ServiceManagement::ServiceInformation & svc)
|
||||
{
|
||||
addService(svc);
|
||||
};
|
||||
m_dtc->serviceInformations(cbSvc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
GroupWidget *ServiceManagementDialog::addGroup(const Core::ServiceGroupType &groupType, int server, int exercise, int32_t replayPartitionId,
|
||||
const QString &groupName, long long timestamp, const QVector<int> &servicesList)
|
||||
{
|
||||
|
||||
|
||||
QString exName = QString::fromStdString(m_dtcExm.get()->exercise(exercise).name());
|
||||
GroupWidget *group = new GroupWidget(groupType, server, exercise, replayPartitionId, exName, timestamp, servicesList);
|
||||
|
||||
QString groupObjectName = craftGroupName(server, exercise, groupName);
|
||||
group->setObjectName(groupObjectName);
|
||||
|
||||
|
||||
connect(group, &GroupWidget::signalRestartGroup, this, &ServiceManagementDialog::slotRestartGroup);
|
||||
connect(group, &GroupWidget::signalStartGroup, this, &ServiceManagementDialog::slotStartGroup);
|
||||
connect(group, &GroupWidget::signalStopGroup, this, &ServiceManagementDialog::slotStopGroup);
|
||||
|
||||
QVBoxLayout *l = qobject_cast<QVBoxLayout *>(m_ui->groupLayoutWidget->layout());
|
||||
if (!l)
|
||||
WARNING_LOG(m_logger) << "ServiceManagementDialog::addGroup: group layout failed, cannot add group";
|
||||
else
|
||||
l->addWidget(group, 0, Qt::AlignTop);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
|
||||
void ServiceManagementDialog::slotRestartService(int serviceID)
|
||||
{
|
||||
const RestartServiceRequest req(serviceID);
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->restartServiceRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
static int s_requestId = 0;
|
||||
void ServiceManagementDialog::slotRestartGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId)
|
||||
{
|
||||
const GroupRequest req(groupType,
|
||||
exercise,
|
||||
server,
|
||||
replayPartitionId,
|
||||
++s_requestId,
|
||||
{});
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->restartGroupRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void ServiceManagementDialog::slotStartGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId)
|
||||
{
|
||||
const GroupRequest req(groupType,
|
||||
exercise,
|
||||
server,
|
||||
replayPartitionId,
|
||||
++s_requestId,
|
||||
{});
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->startGroupRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
void ServiceManagementDialog::slotStopGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId)
|
||||
{
|
||||
const GroupRequest req(groupType,
|
||||
exercise,
|
||||
server,
|
||||
replayPartitionId,
|
||||
++s_requestId,
|
||||
{});
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->stopGroupRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ServiceManagementDialog::slotGroupInformationChanged(ServiceManagement::GroupInformation info, DataModification mod)
|
||||
{
|
||||
|
||||
|
||||
|
||||
int server = info.domainId();
|
||||
int exercise = info.exercisePartitionId();
|
||||
int32_t replayPartitionId = info.replayPartitionId();
|
||||
QString groupName = groupEnumToGroupName(info.type());
|
||||
long long timestamp = info.timestamp();
|
||||
|
||||
QString findGroupName = craftGroupName(server, exercise, groupName);
|
||||
|
||||
GroupWidget *gw = m_ui->groupLayoutWidget->findChild<GroupWidget *>(findGroupName);
|
||||
|
||||
if (!gw)
|
||||
{
|
||||
|
||||
|
||||
QVector<int> servicesList;
|
||||
servicesList.reserve(info.services().size());
|
||||
for (auto service : info.services())
|
||||
servicesList << service;
|
||||
|
||||
m_ui->lbNoServices->hide();
|
||||
addGroup(info.type(), server, exercise, replayPartitionId, groupName, timestamp, servicesList);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
|
||||
|
||||
m_ui->lbNoServices->hide();
|
||||
|
||||
gw->setType(info.type());
|
||||
gw->setServer(server);
|
||||
gw->setExercise(exercise);
|
||||
gw->setTimestamp(timestamp);
|
||||
break;
|
||||
}
|
||||
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
|
||||
|
||||
if (m_ui->groupLayoutWidget->findChildren<GroupWidget *>().isEmpty())
|
||||
m_ui->lbNoServices->show();
|
||||
|
||||
delete gw;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ServiceManagementDialog::addService(const ServiceManagement::ServiceInformation &svc)
|
||||
{
|
||||
const int id = svc.id();
|
||||
const long long pid = svc.pid();
|
||||
const QString name(QString::fromStdString(svc.name()));
|
||||
const Core::RunningState &state = svc.state();
|
||||
const QString errorString(QString::fromStdString(svc.errorString()));
|
||||
|
||||
ServiceWidget *service = new ServiceWidget(id, pid, name, state, errorString);
|
||||
service->setObjectName(QLatin1String("service.") + QString::number(id));
|
||||
connect(service, &ServiceWidget::signalRestartService, this, &ServiceManagementDialog::slotRestartService);
|
||||
|
||||
|
||||
const auto groupList = findChildren<GroupWidget *>();
|
||||
for (GroupWidget *gw : groupList)
|
||||
gw->addService(service);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ServiceManagementDialog::slotServiceInformationChanged(ServiceManagement::ServiceInformation info, DataModification mod)
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
int32_t serviceId = info.id();
|
||||
QString errorString = QString::fromStdString(info.errorString());
|
||||
QString serviceName = QString::fromStdString(info.name());
|
||||
long long pid = info.pid();
|
||||
const Core::RunningState &state = info.state();
|
||||
long long timestamp = info.timestamp();
|
||||
|
||||
QString findServiceName = QLatin1String("service.") + QString::number(serviceId);
|
||||
|
||||
const auto serviceList = findChildren<ServiceWidget *>(findServiceName);
|
||||
|
||||
if (serviceList.isEmpty() || mod == DataModification::eAdded)
|
||||
{
|
||||
|
||||
|
||||
addService(info);
|
||||
}
|
||||
|
||||
for (ServiceWidget *serviceWidget : serviceList)
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case DataModification::eModified:
|
||||
{
|
||||
|
||||
|
||||
serviceWidget->setErrorString(errorString);
|
||||
serviceWidget->setName(serviceName);
|
||||
serviceWidget->setPid(pid);
|
||||
serviceWidget->setState(state);
|
||||
serviceWidget->setTimestamp(timestamp);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
|
||||
|
||||
delete serviceWidget;
|
||||
serviceWidget = nullptr;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
const auto groupList = findChildren<GroupWidget *>();
|
||||
for (GroupWidget *groupWidget : groupList)
|
||||
groupWidget->checkStatus();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
-94
@@ -1,94 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "scm_dialog_group.h"
|
||||
|
||||
#include <ServiceManagement/scm_ftc.h>
|
||||
#include <ServiceManagement/scm_dtc.h>
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <ServiceManagement/logger.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtils/LtsUtilsGui/LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ServiceManagementDialog;
|
||||
}
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
|
||||
|
||||
|
||||
|
||||
class ServiceManagementDialog : public LtsWidgets::LtsDialog
|
||||
, protected ServiceManagement::Interface::Ftc::RestartServiceReplyHandler
|
||||
, protected ServiceManagement::Interface::Ftc::RestartGroupReplyHandler
|
||||
, protected ServiceManagement::Interface::Ftc::StartGroupReplyHandler
|
||||
, protected ServiceManagement::Interface::Ftc::StopGroupReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ServiceManagementDialog(QWidget *parent = nullptr);
|
||||
~ServiceManagementDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &dtcExm);
|
||||
|
||||
virtual void onRestartServiceReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
virtual void onRestartGroupReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
virtual void onStartGroupReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
virtual void onStopGroupReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
|
||||
static QString groupEnumToGroupName(const Core::ServiceGroupType &type)
|
||||
{
|
||||
QMap<QString, Core::ServiceGroupType_def::type> groupNameMapping;
|
||||
groupNameMapping.insert(QLatin1String("Master"), Core::ServiceGroupType_def::Master);
|
||||
groupNameMapping.insert(QLatin1String("Core"), Core::ServiceGroupType_def::Core);
|
||||
groupNameMapping.insert(QLatin1String("ExercisePreparation"), Core::ServiceGroupType_def::ExercisePreparation);
|
||||
groupNameMapping.insert(QLatin1String("ExerciseExecution"), Core::ServiceGroupType_def::ExerciseExecution);
|
||||
groupNameMapping.insert(QLatin1String("ExercisePaused"), Core::ServiceGroupType_def::ExercisePaused);
|
||||
groupNameMapping.insert(QLatin1String("ExerciseAfterActionReview"), Core::ServiceGroupType_def::ExerciseAfterActionReview);
|
||||
groupNameMapping.insert(QLatin1String("Playback"), Core::ServiceGroupType_def::Playback);
|
||||
|
||||
return groupNameMapping.key(type.underlying());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
void retranslate() override;
|
||||
|
||||
static QString craftBaseName(const QString &server, const QString &exercise) { return server + QLatin1Char('.') + exercise + QLatin1Char('.'); }
|
||||
|
||||
GroupWidget *addGroup(const Core::ServiceGroupType &groupType, int server, int exercise, int32_t replayPartitionId,
|
||||
const QString &groupName, long long timestamp, const QVector<int> &servicesList);
|
||||
void addService(const ServiceInformation &svc);
|
||||
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
public:
|
||||
static QString craftGroupName(int server, int exercise, const QString &groupName) { return craftBaseName(QString::number(server), QString::number(exercise)) + groupName; }
|
||||
static QString craftServiceName(int server, int exercise, const QString &groupName, int serviceId) { return craftGroupName(server, exercise, groupName) + QLatin1Char('.') + QString::number(serviceId); }
|
||||
static QString craftWildcardedServiceName(int serviceId) { return craftBaseName(QLatin1String("*"), QLatin1String("*")) + QString::number(serviceId); }
|
||||
|
||||
Ui::ServiceManagementDialog *m_ui;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_dtcExm;
|
||||
std::shared_ptr<ServiceManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<ServiceManagement::Interface::Ftc> m_ftc;
|
||||
private slots:
|
||||
void slotRestartService(int serviceID);
|
||||
void slotRestartGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId);
|
||||
void slotStartGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId);
|
||||
void slotStopGroup(const Core::ServiceGroupType &groupType, int exercise, int server, int32_t replayPartitionId);
|
||||
|
||||
void slotGroupInformationChanged(ServiceManagement::GroupInformation, DataModification);
|
||||
void slotServiceInformationChanged(ServiceManagement::ServiceInformation, DataModification);
|
||||
};
|
||||
}
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ServiceManagementDialog</class>
|
||||
<widget class="QWidget" name="ServiceManagementDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Service Management</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbServer">
|
||||
<property name="text">
|
||||
<string>Server:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QComboBox" name="cbServer">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lbExercise">
|
||||
<property name="text">
|
||||
<string>Exercise:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cbExercise">
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbNoServices">
|
||||
<property name="text">
|
||||
<string>There are no Services available to view.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbGroupsIndicator">
|
||||
<property name="text">
|
||||
<string>Groups of 'Server.Exercise':</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="groupLayoutWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>588</width>
|
||||
<height>376</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>25</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
-168
@@ -1,168 +0,0 @@
|
||||
#include "scm_dialog.h"
|
||||
#include "scm_dialog_group.h"
|
||||
#include "ui_scm_dialog_group.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
GroupWidget::GroupWidget(const Core::ServiceGroupType &groupType, int server, int exercise,
|
||||
int32_t replayPartitionId,
|
||||
const QString &groupName , long long timestamp,
|
||||
const QVector<int> &neededServices, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::GroupWidget)
|
||||
, m_status(ServiceWidget::UNKNOWN)
|
||||
, m_server(server)
|
||||
, m_exercise(exercise)
|
||||
, m_groupName(groupName)
|
||||
, m_replayPartitionId(replayPartitionId)
|
||||
, m_neededServices(neededServices)
|
||||
{
|
||||
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbRestart, &QToolButton::clicked, this, &GroupWidget::slotRestartGroup);
|
||||
connect(m_ui->pbStart, &QToolButton::clicked, this, &GroupWidget::slotStartGroup);
|
||||
connect(m_ui->pbStop, &QToolButton::clicked, this, &GroupWidget::slotStopGroup);
|
||||
|
||||
setType(groupType);
|
||||
setServer(server);
|
||||
setExercise(exercise);
|
||||
setTimestamp(timestamp);
|
||||
|
||||
if (getStatus() != ServiceWidget::STOPPED)
|
||||
setStatus(ServiceWidget::STARTED);
|
||||
}
|
||||
|
||||
|
||||
GroupWidget::~GroupWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::addService(ServiceWidget *service)
|
||||
{
|
||||
m_ui->lbNoServices->hide();
|
||||
|
||||
|
||||
|
||||
if (m_neededServices.contains(service->id()))
|
||||
{
|
||||
|
||||
|
||||
if (!findChild<ServiceWidget *>(service->objectName()))
|
||||
{
|
||||
|
||||
|
||||
m_ui->servicesLayout->addWidget(service);
|
||||
checkStatus();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::checkStatus()
|
||||
{
|
||||
|
||||
|
||||
m_status = ServiceWidget::UNKNOWN;
|
||||
|
||||
|
||||
const QList<ServiceWidget *> serviceList = findChildren<ServiceWidget *>();
|
||||
|
||||
if (serviceList.isEmpty())
|
||||
m_ui->lbNoServices->show();
|
||||
|
||||
for (const ServiceWidget *serviceWidget : serviceList)
|
||||
{
|
||||
if (serviceWidget->getStatus() != ServiceWidget::STARTED)
|
||||
setStatus(ServiceWidget::STOPPED);
|
||||
}
|
||||
|
||||
if (getStatus() != ServiceWidget::STOPPED)
|
||||
setStatus(ServiceWidget::STARTED);
|
||||
}
|
||||
|
||||
|
||||
ServiceWidget::Status GroupWidget::getStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::setStatus(ServiceWidget::Status status)
|
||||
{
|
||||
m_status = status;
|
||||
|
||||
QString newCss;
|
||||
switch (m_status)
|
||||
{
|
||||
case ServiceWidget::STARTED:
|
||||
newCss = QLatin1String("background-color: rgb(124, 189, 124);");
|
||||
break;
|
||||
case ServiceWidget::STOPPED:
|
||||
newCss = QLatin1String("background-color: rgb(189, 106, 98);");
|
||||
break;
|
||||
case ServiceWidget::STARTING:
|
||||
case ServiceWidget::STOPPING:
|
||||
case ServiceWidget::UNKNOWN:
|
||||
break;
|
||||
}
|
||||
m_ui->frStatus->setStyleSheet(newCss);
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::slotRestartGroup()
|
||||
{
|
||||
emit signalRestartGroup(m_groupType, m_exercise, m_server, m_replayPartitionId);
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::slotStartGroup()
|
||||
{
|
||||
emit signalStartGroup(m_groupType, m_exercise, m_server, m_replayPartitionId);
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::slotStopGroup()
|
||||
{
|
||||
emit signalStopGroup(m_groupType, m_exercise, m_server, m_replayPartitionId);
|
||||
}
|
||||
|
||||
|
||||
void GroupWidget::setType(Core::ServiceGroupType type)
|
||||
{
|
||||
m_groupType = type;
|
||||
m_ui->lbGroupName->setText(QStringLiteral("<html><head/><body><p>%1<span style='font-weight:600;'> %2</span></p></body></html>")
|
||||
.arg(tr("Services of %1").arg(ServiceManagement::ServiceManagementDialog::groupEnumToGroupName(type)), m_groupName));
|
||||
}
|
||||
|
||||
void GroupWidget::setServer(int server)
|
||||
{
|
||||
m_server = server;
|
||||
}
|
||||
|
||||
void GroupWidget::setExercise(int exercise)
|
||||
{
|
||||
m_exercise = exercise;
|
||||
}
|
||||
|
||||
void GroupWidget::setTimestamp(long long timestamp)
|
||||
{
|
||||
if (timestamp < 1)
|
||||
{
|
||||
m_ui->lbTimestamp->setText(QString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui->lbTimestamp->setText(QStringLiteral("<html><head/><body><p>%1:<br/>%2</p></body></html>")
|
||||
.arg(tr("Last Heartbeat"), QDateTime::fromMSecsSinceEpoch(timestamp).toString()));
|
||||
}
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "scm_dialog_service.h"
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class GroupWidget;
|
||||
}
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
class GroupWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GroupWidget(const Core::ServiceGroupType &groupType, int server, int exercise,
|
||||
int32_t replayPartitionId,
|
||||
const QString &groupName, long long timestamp,
|
||||
const QVector<int> &neededServices, QWidget *parent = nullptr);
|
||||
~GroupWidget();
|
||||
|
||||
void addService(ServiceWidget *service);
|
||||
|
||||
void setType(Core::ServiceGroupType type);
|
||||
void setServer(int server);
|
||||
void setExercise(int exercise);
|
||||
void setTimestamp(long long timestamp);
|
||||
|
||||
ServiceWidget::Status getStatus() const;
|
||||
void setStatus(ServiceWidget::Status status);
|
||||
|
||||
void checkStatus();
|
||||
|
||||
private:
|
||||
Ui::GroupWidget *m_ui;
|
||||
ServiceWidget::Status m_status;
|
||||
Core::ServiceGroupType m_groupType;
|
||||
int m_server;
|
||||
int m_exercise;
|
||||
QString m_groupName;
|
||||
int32_t m_replayPartitionId;
|
||||
QVector<int> m_neededServices;
|
||||
|
||||
private slots:
|
||||
void slotRestartGroup();
|
||||
void slotStartGroup();
|
||||
void slotStopGroup();
|
||||
|
||||
signals:
|
||||
void signalRestartGroup(const Core::ServiceGroupType &groupType, int, int, int32_t replayPartitionId);
|
||||
void signalStartGroup(const Core::ServiceGroupType &groupType, int, int, const int32_t replayPartitionId);
|
||||
void signalStopGroup(const Core::ServiceGroupType &groupType, int, int, const int32_t replayPartitionId);
|
||||
};
|
||||
}
|
||||
-222
@@ -1,222 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>GroupWidget</class>
|
||||
<widget class="QWidget" name="GroupWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<height>55</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<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>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frStatus">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbGroupName">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbTimestamp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbRestart">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Restart this Group of Services (Restarts every Service inside this Group)</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">R</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/arrow_back.svg</normaloff>:/style/arrow_back.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbStart">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Start this Group of Services (Starts Services inside this Group, that are currently stopped)</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">S</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/media-play-slower.svg</normaloff>:/style/media-play-slower.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbStop">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Stop this Group of Services (Stops Services inside this Group, that are currently running / started)</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">E</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/application-exit.svg</normaloff>:/style/application-exit.svg</iconset>
|
||||
</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>
|
||||
<layout class="QVBoxLayout" name="servicesLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbNoServices">
|
||||
<property name="text">
|
||||
<string>No Services available in this Group.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../Styles/Dark/resources/rme_dark_style.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
-134
@@ -1,134 +0,0 @@
|
||||
#include "scm_dialog_service.h"
|
||||
#include "ui_scm_dialog_service.h"
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
ServiceWidget::ServiceWidget(int32_t id, long long pid, const QString &name,
|
||||
const Core::RunningState &state, const QString &errorString, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::ServiceWidget)
|
||||
, m_status(ServiceWidget::UNKNOWN)
|
||||
, m_id(id)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbRestart, &QToolButton::clicked, this, &ServiceWidget::slotRestartService);
|
||||
|
||||
setName(name);
|
||||
setPid(pid);
|
||||
setErrorString(errorString);
|
||||
setState(state);
|
||||
}
|
||||
|
||||
|
||||
ServiceWidget::~ServiceWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::setName(const QString &name)
|
||||
{
|
||||
m_ui->lbServiceName->setText(name);
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::setPid(long long pid)
|
||||
{
|
||||
m_ui->lbPID->setText(QStringLiteral("<html><head/><body><p>%1:<br/>%2</p></body></html>")
|
||||
.arg(tr("Process ID")).arg(pid));
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::setTimestamp(long long timestamp)
|
||||
{
|
||||
if (timestamp < 1)
|
||||
{
|
||||
m_ui->lbTimestamp->setText(QString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui->lbTimestamp->setText(QStringLiteral("<html><head/><body><p>%1:<br/>%2</p></body></html>")
|
||||
.arg(tr("Last Heartbeat"), QDateTime::fromMSecsSinceEpoch(timestamp).toString()));
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::setErrorString(const QString &errorString)
|
||||
{
|
||||
if (errorString.isEmpty())
|
||||
{
|
||||
m_ui->lbError->setText(QString());
|
||||
return;
|
||||
}
|
||||
|
||||
m_ui->lbError->setText(QStringLiteral("<html><head/><body><p><span style='color:#aa0000;'>%1:<br/>%2</span></p></body></html>").arg(tr("Error"), errorString));
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::setState(Core::RunningState state)
|
||||
{
|
||||
auto status = ServiceWidget::UNKNOWN;
|
||||
switch (state.underlying())
|
||||
{
|
||||
|
||||
case Core::RunningState::inner_enum::Starting:
|
||||
status = ServiceWidget::STARTING;
|
||||
break;
|
||||
|
||||
|
||||
case Core::RunningState::inner_enum::Running:
|
||||
status = ServiceWidget::STARTED;
|
||||
break;
|
||||
|
||||
|
||||
case Core::RunningState::inner_enum::Stopping:
|
||||
status = ServiceWidget::STOPPING;
|
||||
break;
|
||||
|
||||
|
||||
case Core::RunningState::inner_enum::StartingError:
|
||||
case Core::RunningState::inner_enum::NotYetStarted:
|
||||
case Core::RunningState::inner_enum::StoppedNormally:
|
||||
case Core::RunningState::inner_enum::StoppedError:
|
||||
status = ServiceWidget::STOPPED;
|
||||
break;
|
||||
}
|
||||
setStatus(status);
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::setStatus(const Status status)
|
||||
{
|
||||
m_status = status;
|
||||
|
||||
switch (m_status)
|
||||
{
|
||||
case ServiceWidget::STARTED:
|
||||
m_ui->frStatus->setStyleSheet(greenStyleSheet());
|
||||
break;
|
||||
|
||||
case ServiceWidget::STOPPED:
|
||||
m_ui->frStatus->setStyleSheet(redStyleSheet());
|
||||
break;
|
||||
|
||||
default:
|
||||
m_ui->frStatus->setStyleSheet(orangeStyleSheet());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ServiceWidget::Status ServiceWidget::getStatus() const
|
||||
{
|
||||
return m_status;
|
||||
}
|
||||
|
||||
|
||||
void ServiceWidget::slotRestartService()
|
||||
{
|
||||
emit signalRestartService(m_id);
|
||||
}
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <ServiceManagement/scm_dtc.h>
|
||||
|
||||
#include <QtWidgets/QWidget>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ServiceWidget;
|
||||
}
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
class ServiceWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Status
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
STARTING,
|
||||
STARTED,
|
||||
STOPPING,
|
||||
STOPPED,
|
||||
};
|
||||
|
||||
ServiceWidget(int32_t id, long long pid, const QString &name,
|
||||
const Core::RunningState &state, const QString &errorString, QWidget *parent = nullptr);
|
||||
~ServiceWidget();
|
||||
|
||||
void setPid(long long pid);
|
||||
void setName(const QString &name);
|
||||
void setTimestamp(long long timestamp);
|
||||
void setState(Core::RunningState state);
|
||||
void setErrorString(const QString &errorString);
|
||||
|
||||
|
||||
void setStatus(const Status status);
|
||||
Status getStatus() const;
|
||||
int32_t id() const { return m_id; }
|
||||
|
||||
private:
|
||||
Ui::ServiceWidget *m_ui;
|
||||
Status m_status;
|
||||
int32_t m_id;
|
||||
|
||||
static QString greenStyleSheet() { return QLatin1String("background-color: rgb(124, 189, 124);"); }
|
||||
static QString orangeStyleSheet() { return QLatin1String("background-color: rgb(212, 190, 128);"); }
|
||||
static QString redStyleSheet() { return QLatin1String("background-color: rgb(202, 122, 122);"); }
|
||||
|
||||
signals:
|
||||
void signalRestartService(int id);
|
||||
|
||||
private slots:
|
||||
void slotRestartService();
|
||||
};
|
||||
}
|
||||
-234
@@ -1,234 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ServiceWidget</class>
|
||||
<widget class="QWidget" name="ServiceWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>767</width>
|
||||
<height>50</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</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>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="frStatus">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbServiceName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Service Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="pbRestart">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>28</horstretch>
|
||||
<verstretch>28</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>28</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Restart Service</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">R</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../Styles/Dark/resources/rme_dark_style.qrc">
|
||||
<normaloff>:/style/arrow_back.svg</normaloff>:/style/arrow_back.svg</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonIconOnly</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbTimestamp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>250</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><br/></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbPID">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbError">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../Styles/Dark/resources/rme_dark_style.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "scm_edit_gui_plugin.h"
|
||||
#include "scm_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <ServiceManagement/scm_operator_rights.h>
|
||||
#include <ExerciseManagement/exm_data_plugin_interface.h>
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Scm.Edit"))
|
||||
, m_dtcExm(nullptr)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<DataInterface>(m_dtc))
|
||||
return false;
|
||||
if (!m_session->getFtc<DataInterface>(m_ftc))
|
||||
return false;
|
||||
if (!m_session->getDtc<ExerciseManagement::DataInterface>(m_dtcExm))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_ftc = nullptr;
|
||||
m_dtc = nullptr;
|
||||
}
|
||||
|
||||
|
||||
QString InterfaceImpl::menuGroup() const
|
||||
{
|
||||
return tr("Services");
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Service Management");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:service.svg"));
|
||||
plData.identifier = QLatin1String("scmServiceEdit");
|
||||
plData.operatorRight = OperatorRights::ServicesEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
m_dtc->enableGroupInformation();
|
||||
m_dtc->enableServiceInformation();
|
||||
|
||||
m_ftc->enableRestartService();
|
||||
|
||||
m_ftc->enableStopGroup();
|
||||
m_ftc->enableStartGroup();
|
||||
m_ftc->enableRestartGroup();
|
||||
|
||||
return LtsWidgets::initDialog(new ServiceManagementDialog(parent),
|
||||
m_dtc, m_ftc, m_dtcExm);
|
||||
};
|
||||
ret.append(plData);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include <ServiceManagement/logger.h>
|
||||
#include <ServiceManagement/scm_ftc.h>
|
||||
#include <ServiceManagement/scm_dtc.h>
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <ServiceManagement/scm_data_plugin_interface.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:scm")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QStringLiteral("ServiceManagement"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Global);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
QString menuGroup() const override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Global; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_dtcExm;
|
||||
std::shared_ptr<ServiceManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<ServiceManagement::Interface::Ftc> m_ftc;
|
||||
};
|
||||
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PluginInterfaces/data_plugin_interface.h>
|
||||
#include <ServiceManagement/scm_dtc.h>
|
||||
#include <ServiceManagement/scm_ftc.h>
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
|
||||
|
||||
class DataInterface : public DataPluginBase::Interface
|
||||
{
|
||||
public:
|
||||
using DataPluginBase::Interface::Interface;
|
||||
|
||||
virtual std::shared_ptr<ServiceManagement::Interface::Dtc> getDtc() = 0;
|
||||
virtual std::shared_ptr<ServiceManagement::Interface::Ftc> getFtc() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ServiceManagement
|
||||
{
|
||||
class ForeignGuiInterface
|
||||
{
|
||||
public:
|
||||
ForeignGuiInterface() = default;
|
||||
virtual ~ForeignGuiInterface() = default;
|
||||
};
|
||||
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLTE, 2020-03-23
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(Common)
|
||||
ADD_SUBDIRECTORY(ThpManagement)
|
||||
ADD_SUBDIRECTORY(ThpUsbManagement)
|
||||
|
||||
ADD_INTERFACE_LIBRARY(TpmGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/tpm_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
GuiPluginInterface
|
||||
)
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
#
|
||||
# $Id: CMakeLists.txt 51804 2020-07-31 04:47:28Z fritsche_h $
|
||||
# $HeadURL: svn://slssvn/TDS/branches/product/iterations/21_03_salted_caramel/Lts/Plugins/TakeHomePackageManager/CMakeLists.txt $
|
||||
# $Author: fritsche_h $
|
||||
#
|
||||
# Created by Mike Wille, SLTE, 2020-03-23
|
||||
#
|
||||
|
||||
SET(src
|
||||
logger.cpp
|
||||
logger.h
|
||||
tpm_exported_scripts_model.cpp
|
||||
tpm_exported_scripts_model.h
|
||||
tpm_process_dialog.cpp
|
||||
tpm_process_dialog.h
|
||||
)
|
||||
|
||||
QT5_WRAP_UI(src
|
||||
tpm_process_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS ThpCommon SHARED ${src})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(ThpCommon
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../ # export file
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(ThpCommon
|
||||
Qt6::Core
|
||||
Qt6::Concurrent
|
||||
NGLLogger
|
||||
LtsSession
|
||||
AsmDataPluginInterface
|
||||
ExmDataPluginInterface
|
||||
#nglcompression
|
||||
#nglsettings
|
||||
#ngltools
|
||||
#LtsSessionData
|
||||
#httq
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(ThpCommon)
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "TPM.Common.";
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
typedef NGL::INGLLogger &LOGGER_T;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
}
|
||||
-602
@@ -1,602 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "tpm_exported_scripts_model.h"
|
||||
#include <utility>
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QJsonArray>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
|
||||
ExportedScriptsModel::ExportedScriptsModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<ExportedScriptInformation>(
|
||||
{ tr("id"), tr("Exercise"), tr("Name"), tr("Created"), tr("Last downloaded"), tr("Location"), tr("Last uploaded"), tr("Server")}, parent)
|
||||
{}
|
||||
|
||||
bool ExportedScriptsModel::init(const QString &rootDirectoryToScan)
|
||||
{
|
||||
std::shared_ptr<int> _(nullptr, [this](int *) { endResetModel(); });
|
||||
m_rootDirectoryToScan = rootDirectoryToScan;
|
||||
beginResetModel();
|
||||
m_vecData.clear();
|
||||
|
||||
QVector <int> localExercises;
|
||||
DEBUG_LOG(m_logger) << "ExportedScriptsModel::init rootDirectoryToScan=" << rootDirectoryToScan
|
||||
;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Get all local exercises rootDirectoryToScan=" << rootDirectoryToScan ;
|
||||
QFile file(rootDirectoryToScan + QDir::separator() + QStringLiteral("exercises.json"));
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
WARNING_LOG(m_logger) << "Cannot open " << file.fileName() << " for read/write: " << file.errorString();
|
||||
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(file.readAll()));
|
||||
const QJsonObject obj = doc.object();
|
||||
const QJsonArray arr = obj[QStringLiteral("Exercises")].toArray();
|
||||
localExercises.reserve(arr.size());
|
||||
for (const auto &ele : arr)
|
||||
localExercises.append(ele.toInt());
|
||||
}
|
||||
|
||||
WARNING_LOG(m_logger) << "local exericses: " << localExercises.count();
|
||||
|
||||
|
||||
for (const int exId : std::as_const(localExercises))
|
||||
{
|
||||
const QString baseDir = exercisePath(rootDirectoryToScan, exId);
|
||||
QFile file(baseDir + QDir::separator() + QStringLiteral("data.json"));
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Cannot open " << file.fileName() << " for reading: " << file.errorString() << " - not critical";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(file.readAll()));
|
||||
const QJsonObject obj = doc.object();
|
||||
const QJsonArray presentations = obj[QStringLiteral("presentations")].toArray();
|
||||
|
||||
DEBUG_LOG(m_logger) << "exercise: " << exId << ", presentations: " << presentations.size();
|
||||
|
||||
for (const QJsonValue &val : presentations)
|
||||
{
|
||||
ExportedScriptInformation esi = ExportedScriptInformation::fromJson(val);
|
||||
DEBUG_LOG(m_logger) << "obj=" << QJsonDocument(obj).toJson(QJsonDocument::Compact);
|
||||
const QJsonObject presentationObj = val.toObject();
|
||||
DEBUG_LOG(m_logger) << "presentationObj=" << QJsonDocument(presentationObj).toJson(QJsonDocument::Compact);
|
||||
if (obj.contains(QStringLiteral("exerciseId")))
|
||||
{
|
||||
esi.exerciseId = obj[QStringLiteral("exerciseId")].toInt();
|
||||
esi.exerciseName = obj[QStringLiteral("exerciseName")].toString();
|
||||
if (presentationObj.contains(QStringLiteral("name")) )
|
||||
esi.scriptName = presentationObj[QStringLiteral("name")].toString();
|
||||
if (presentationObj.contains(QStringLiteral("displayName")) )
|
||||
esi.scriptName = presentationObj[QStringLiteral("displayName")].toString();
|
||||
}
|
||||
|
||||
esi.local = true;
|
||||
DEBUG_LOG(m_logger) << "push_back "
|
||||
<< " exportTime=" << esi.exportTime
|
||||
<< " scriptId=" << esi.scriptId
|
||||
<< " scriptName=" << esi.scriptName
|
||||
<< " exerciseId=" << esi.exerciseId
|
||||
<< " exerciseName=" << esi.exerciseName
|
||||
<< " local=" << esi.local;
|
||||
esi.uploaded = ThpUnknownUploadState;
|
||||
|
||||
esi.rootDirectory = rootDirectoryToScan;
|
||||
|
||||
m_vecData.push_back(esi);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ExportedScriptsModel::setServerContent(const QString &jsonArray)
|
||||
{
|
||||
if (jsonArray.isEmpty())
|
||||
return;
|
||||
|
||||
|
||||
|
||||
QMap<int, QVector<int>> exerciseContentScriptIds;
|
||||
QMap<int, QVector<int>> exerciseScriptIds;
|
||||
|
||||
DEBUG_LOG(m_logger) << "ExportedScriptsModel::setServerContent jsonArray =" << jsonArray;
|
||||
QJsonParseError err;
|
||||
const QJsonArray presentations = QJsonDocument::fromJson(jsonArray.toUtf8(), &err).array();
|
||||
DEBUG_LOG(m_logger) << "presentations.size() =" << presentations.size();
|
||||
|
||||
if (err.error != QJsonParseError::NoError)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "json array invalid at offset " << err.offset << ": " << err.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (const auto &data : std::as_const(m_vecData))
|
||||
{
|
||||
exerciseScriptIds[data.exerciseId].append(data.scriptId);
|
||||
DEBUG_LOG(m_logger) << "exerciseId=" << data.exerciseId
|
||||
<< " modelScriptIds.append: " << data.scriptId;
|
||||
}
|
||||
|
||||
|
||||
for (const QJsonValue &val : presentations)
|
||||
{
|
||||
const ExportedScriptInformation esi = ExportedScriptInformation::fromJson(val, false, ThpAlreadyUploaded);
|
||||
exerciseContentScriptIds[esi.exerciseId].append(esi.scriptId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = m_vecData.size() - 1; i >= 0; --i)
|
||||
{
|
||||
const auto &rowData = m_vecData[i];
|
||||
const QVector<int> contentScriptIds = exerciseContentScriptIds.value(rowData.exerciseId);
|
||||
DEBUG_LOG(m_logger) << "m_vecData.at(" << i << ").scriptId=" << rowData.scriptId
|
||||
<< " exerciseId=" << rowData.exerciseId
|
||||
<< " contentScriptIds.contains=" << contentScriptIds.contains(rowData.scriptId)
|
||||
<< " rowData.local=" << rowData.local
|
||||
<< " contentScriptIds.size()=" << contentScriptIds.size();
|
||||
|
||||
if (!contentScriptIds.contains(rowData.scriptId))
|
||||
{
|
||||
|
||||
if (rowData.local == false)
|
||||
{
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "removeRow(" << i << ")"
|
||||
<< " ScriptId=" << rowData.scriptId
|
||||
<< " ExerciseId=" << rowData.exerciseId;
|
||||
removeRow(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
setUploadState(i, ThpUploadNotActive, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (const QJsonValue &val : presentations)
|
||||
{
|
||||
ExportedScriptInformation esi = ExportedScriptInformation::fromJson(val, false, ThpAlreadyUploaded);
|
||||
QVector<int> modelScriptIds = exerciseScriptIds.value(esi.exerciseId);
|
||||
DEBUG_LOG(m_logger) << " exportTime=" << esi.exportTime
|
||||
<< " scriptId=" << esi.scriptId
|
||||
<< " exerciseId=" << esi.exerciseId
|
||||
<< " exerciseName=" << esi.exerciseName
|
||||
<< " scriptName=" << esi.scriptName
|
||||
<< " fileSize=" << esi.fileSize
|
||||
<< " modelScriptIds.size=" << modelScriptIds.size();
|
||||
|
||||
|
||||
if (!modelScriptIds.contains(esi.scriptId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "insertRow()";
|
||||
insertRow(esi);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < m_vecData.size(); i++)
|
||||
{
|
||||
const auto &rowData = m_vecData[i];
|
||||
if (rowData.scriptId == esi.scriptId &&
|
||||
rowData.exerciseId == esi.exerciseId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "setUploadState i=" << i
|
||||
<< " esi.scriptId=" << esi.scriptId
|
||||
<< " esi.exerciseId=" << esi.exerciseId
|
||||
<< " esi.fileSize=" << esi.fileSize
|
||||
<< " esi.uploadTime=" << esi.uploadTime;
|
||||
setUploadState(i, ThpAlreadyUploaded, esi.uploadTime, esi.fileSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
qint64 ExportedScriptsModel::downloadTime(const ExportedScriptInformation &val) const
|
||||
{
|
||||
if (!val.local)
|
||||
return 0;
|
||||
|
||||
QString filename(QStringLiteral("%1/THP-Download/Exercise_%2/%3/index.html").arg(QDir::tempPath()).arg(val.exerciseId).arg(val.scriptId));
|
||||
DEBUG_LOG(m_logger) << "downloadTime: filename " << filename;
|
||||
|
||||
QFileInfo fi(filename);
|
||||
if (!fi.exists())
|
||||
return 0;
|
||||
|
||||
return fi.lastModified().toMSecsSinceEpoch();
|
||||
}
|
||||
|
||||
|
||||
QVariant ExportedScriptsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const ExportedScriptInformation &val = m_vecData[index.row()];
|
||||
|
||||
switch (role)
|
||||
{
|
||||
case Qt::FontRole:
|
||||
{
|
||||
if (!m_isOC
|
||||
|
||||
|
||||
|
||||
|| !val.local
|
||||
|
||||
|
||||
|
||||
|| index.column() != ColUploadedTime
|
||||
|
||||
|| val.uploadTime <= (downloadTime(val) + (10 * 1000) ))
|
||||
|
||||
|
||||
break;
|
||||
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
return font;
|
||||
}
|
||||
|
||||
case Qt::DisplayRole:
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case ColId:
|
||||
return val.scriptId;
|
||||
case ColExercise:
|
||||
return val.exerciseName;
|
||||
case ColName:
|
||||
return val.scriptName;
|
||||
case ColCreated:
|
||||
return QDateTime::fromMSecsSinceEpoch(val.exportTime);
|
||||
case ColDownloaded:
|
||||
{
|
||||
qint64 dlTime = downloadTime(val);
|
||||
if (dlTime == 0)
|
||||
return QVariant();
|
||||
return QDateTime::fromMSecsSinceEpoch(dlTime);
|
||||
}
|
||||
case ColUploadedTime:
|
||||
return QDateTime::fromMSecsSinceEpoch(val.uploadTime);
|
||||
case ColLocation:
|
||||
return val.local ? tr("Local") : tr("Server");
|
||||
case ColUploaded:
|
||||
switch (val.uploaded)
|
||||
{
|
||||
case ThpConnectToHost:
|
||||
return tr("Connect to host");
|
||||
case ThpUploadActive:
|
||||
return tr("Upload Active");
|
||||
case ThpUploadError:
|
||||
return tr("Upload Error");
|
||||
case ThpUploadNotActive:
|
||||
return tr("Not uploaded");
|
||||
case ThpUnknownUploadState:
|
||||
return tr("Unknown upload status");
|
||||
case ThpAlreadyUploaded:
|
||||
return tr("Already uploaded");
|
||||
}
|
||||
}
|
||||
|
||||
case Qt::UserRole:
|
||||
{
|
||||
return val.scriptId;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool ExportedScriptsModel::createDataJson(const QString &rootDirectory,
|
||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc,
|
||||
const std::shared_ptr<AssetManagement::Interface::Dtc> &asmDtc,
|
||||
int exerciseId) const
|
||||
{
|
||||
const QString baseDir = exercisePath(rootDirectory, exerciseId);
|
||||
|
||||
if (!QDir().mkpath(baseDir))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Failed to create path " << baseDir;
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile file(baseDir + QStringLiteral("data.json"));
|
||||
DEBUG_LOG(m_logger) << "createDataJson=" << file.fileName();
|
||||
if (!file.open(QFile::ReadWrite))
|
||||
{
|
||||
QString msg(tr("Could not open data file in script directory: %1").arg(file.errorString()));
|
||||
ERROR_LOG(m_logger) << msg << " - " << file.fileName();
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonDocument doc(QJsonDocument::fromJson(file.readAll()));
|
||||
QJsonObject obj = doc.object();
|
||||
if (obj[QStringLiteral("exerciseId")].toInt() == exerciseId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << baseDir << " exists for exerciseId " << QString::number(exerciseId);
|
||||
return true;
|
||||
}
|
||||
|
||||
const ExerciseManagement::Exercise exercise = exmDtc->exercise(exerciseId);
|
||||
const AssetManagement::TrainingArea ta = asmDtc->trainingArea(exercise.trainingAreaId());
|
||||
|
||||
obj[QStringLiteral("title")] = QString::fromStdString(exercise.name());
|
||||
obj[QStringLiteral("exerciseId")] = exercise.id();
|
||||
obj[QStringLiteral("exerciseName")] = QString::fromStdString(exercise.name());
|
||||
obj[QStringLiteral("exerciseArea")] = QString::fromStdString(ta.name());
|
||||
obj[QStringLiteral("cycleTime")] = QString(QDateTime::fromMSecsSinceEpoch(exercise.beginTime()).toString() +
|
||||
QStringLiteral(" - ") + QDateTime::fromMSecsSinceEpoch(exercise.endTime()).toString());
|
||||
obj[QStringLiteral("exerciseStart")] = exercise.beginTime();
|
||||
obj[QStringLiteral("exerciseEnd")] = exercise.endTime();
|
||||
obj[QStringLiteral("exercisingForces")] = QString::fromStdString(exercise.forces());
|
||||
obj[QStringLiteral("exercisingPurpose")] = QString::fromStdString(exercise.description());
|
||||
|
||||
file.resize(0);
|
||||
file.write(QJsonDocument(obj).toJson());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ExportedScriptsModel::addDownloadData(const ExportedScriptInformation &esi)
|
||||
{
|
||||
|
||||
{
|
||||
|
||||
DEBUG_LOG(m_logger) << "Add exercise to ExportRootPath";
|
||||
|
||||
if (!QDir(esi.rootDirectory).exists())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Cannot modify exercises.json as the info's root directory '"<<esi.rootDirectory<<"' does not exist!";
|
||||
return;
|
||||
}
|
||||
|
||||
QFile file(esi.rootDirectory + QDir::separator() + QStringLiteral("exercises.json"));
|
||||
if (!file.open(QFile::ReadWrite))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not open " << file.fileName() << " for read/write: " << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString key = QStringLiteral("Exercises");
|
||||
QJsonDocument doc(QJsonDocument::fromJson(file.readAll()));
|
||||
QJsonObject obj = doc.object();
|
||||
QJsonArray arr = obj.value(key).toArray();
|
||||
|
||||
if (!arr.contains(esi.exerciseId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "arr.append Exercise=" << esi.exerciseId;
|
||||
arr.append(esi.exerciseId);
|
||||
}
|
||||
|
||||
obj.insert(key, arr);
|
||||
file.resize(0);
|
||||
file.write(QJsonDocument(obj).toJson());
|
||||
INFO_LOG(m_logger) << " file.write " << QJsonDocument(obj).toJson();
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
const QString baseDir = exercisePath(esi.rootDirectory, esi.exerciseId);
|
||||
if (!QDir().mkpath(baseDir))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Cannot create destination path " << baseDir;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QFile file(baseDir + QDir::separator() + QStringLiteral("data.json"));
|
||||
DEBUG_LOG(m_logger) << "File= " << file.fileName();
|
||||
if (!file.open(QFile::ReadWrite))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not open " << file.fileName() << " for read/write: " << file.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
const QString keyArray = QStringLiteral("presentations");
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(file.readAll()));
|
||||
QJsonObject obj = doc.object();
|
||||
QJsonArray arr = obj.value(keyArray).toArray();
|
||||
bool exported = false;
|
||||
DEBUG_LOG(m_logger) << "arr.size=" << arr.size();
|
||||
|
||||
for (int i = 0; i < arr.size(); ++i)
|
||||
{
|
||||
auto arresi = ExportedScriptInformation::fromJson(arr.at(i));
|
||||
if (arresi.scriptId == esi.scriptId &&
|
||||
arresi.exerciseId == esi.exerciseId)
|
||||
{
|
||||
arresi.jsonPath = esi.jsonPath;
|
||||
arr[i] = esi.toJson();
|
||||
exported = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exported)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "info scriptId=" << esi.scriptId
|
||||
<< " Name=" << esi.scriptName
|
||||
<< " Exercise=" << esi.exerciseName;
|
||||
arr.append(esi.toJson());
|
||||
}
|
||||
|
||||
obj.insert(keyArray, arr);
|
||||
auto content = QJsonDocument(obj).toJson();
|
||||
|
||||
DEBUG_LOG(m_logger) << "content =" << content;
|
||||
|
||||
file.resize(0);
|
||||
file.write(content);
|
||||
file.close();
|
||||
}
|
||||
|
||||
|
||||
bool ExportedScriptsModel::setLocalState(const int row, const bool localHost)
|
||||
{
|
||||
ExportedScriptInformation data = getRowData(row);
|
||||
|
||||
data.local = localHost;
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "setLocalState row=" << row
|
||||
<< " scriptId=" << data.scriptId
|
||||
<< " data.scriptName=" << data.scriptName
|
||||
<< " Exercise=" << data.exerciseName;
|
||||
|
||||
bool result = setRowData(row, data);
|
||||
if (result && localHost && m_rootDirectoryToScan.contains(QStringLiteral("Download")))
|
||||
{
|
||||
data.rootDirectory = m_rootDirectoryToScan;
|
||||
setRowData(row, data);
|
||||
addDownloadData(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ExportedScriptsModel::setUploadState(const int row,
|
||||
const UploadState uploadState,
|
||||
const qint64 uploadTime,
|
||||
const qint64 fileSize)
|
||||
{
|
||||
ExportedScriptInformation data = getRowData(row);
|
||||
data.uploaded = uploadState;
|
||||
data.uploadTime = uploadTime;
|
||||
data.fileSize = fileSize;
|
||||
return setRowData(row, data);
|
||||
}
|
||||
|
||||
bool ExportedScriptsModel::removeRow(int row)
|
||||
{
|
||||
ExportedScriptInformation data = getRowData(row);
|
||||
|
||||
if (!LtsWidgets::LtsAbstractTableModel<ExportedScriptInformation>::removeRow(row))
|
||||
return false;
|
||||
|
||||
QString baseDir = exercisePath(data.rootDirectory, data.exerciseId);
|
||||
QString filename = baseDir + QStringLiteral("data.json");
|
||||
DEBUG_LOG(m_logger) << "filename= '" << filename << "'";
|
||||
QFile file(baseDir + QStringLiteral("data.json"));
|
||||
|
||||
if (!file.open(QIODevice::ReadWrite))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "!file.open '" << filename << "'"
|
||||
<< " no local scripts";
|
||||
return true;
|
||||
}
|
||||
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(file.readAll()));
|
||||
QJsonObject obj = doc.object();
|
||||
const int exId = obj.value(QStringLiteral("exerciseId")).toInt();
|
||||
QJsonArray arr;
|
||||
|
||||
for (const auto &esi : std::as_const(m_vecData))
|
||||
{
|
||||
if (esi.exerciseId == exId)
|
||||
arr += esi.toJson();
|
||||
}
|
||||
|
||||
obj[QStringLiteral("presentations")] = arr;
|
||||
file.resize(0);
|
||||
auto content = QJsonDocument(obj).toJson();
|
||||
DEBUG_LOG(m_logger) << "content =" << content;
|
||||
|
||||
return file.write(QJsonDocument(obj).toJson());
|
||||
}
|
||||
|
||||
QString ExportedScriptsModel::exercisePath(const QString &rootDirectory, const int exerciseId) const
|
||||
{
|
||||
QString path = QStringLiteral("%1/Exercise_%2/").arg(rootDirectory).arg(exerciseId);
|
||||
#ifndef WIN32
|
||||
path.prepend(QStringLiteral("/"));
|
||||
#endif
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QJsonValue ExportedScriptInformation::toJson() const
|
||||
{
|
||||
return QJsonObject({
|
||||
{ QStringLiteral("displayName"), scriptName },
|
||||
{ QStringLiteral("path"), jsonPath },
|
||||
{ QStringLiteral("scriptId"), scriptId },
|
||||
{ QStringLiteral("exportTime"), exportTime },
|
||||
{ QStringLiteral("fileSize"), fileSize },
|
||||
{ QStringLiteral("uploadTime"), uploadTime },
|
||||
{ QStringLiteral("exerciseName"), exerciseName },
|
||||
{ QStringLiteral("exerciseId"), exerciseId }
|
||||
});
|
||||
}
|
||||
|
||||
ExportedScriptInformation ExportedScriptInformation::fromJson(const QJsonValue &val,
|
||||
const bool local,
|
||||
const UploadState uploadState)
|
||||
{
|
||||
const QJsonObject obj = val.toObject();
|
||||
|
||||
ExportedScriptInformation esi;
|
||||
esi.local = local;
|
||||
esi.scriptName = obj[QStringLiteral("displayName")].toString();
|
||||
if (esi.scriptName.isEmpty())
|
||||
esi.scriptName = obj[QStringLiteral("name")].toString();
|
||||
esi.jsonPath = obj[QStringLiteral("path")].toString();
|
||||
esi.scriptId = obj[QStringLiteral("scriptId")].toInt();
|
||||
esi.exportTime = qRound64(obj[QStringLiteral("exportTime")].toDouble());
|
||||
esi.fileSize = obj[QStringLiteral("fileSize")].toInt();
|
||||
esi.uploaded = uploadState;
|
||||
esi.uploadTime = qRound64(obj[QStringLiteral("uploadTime")].toDouble());
|
||||
esi.exerciseName = obj[QStringLiteral("exerciseName")].toString();
|
||||
esi.exerciseId = obj[QStringLiteral("exerciseId")].toInt();
|
||||
|
||||
Q_ASSERT(esi.scriptId != -1);
|
||||
Q_ASSERT(esi.exerciseId != -1);
|
||||
|
||||
if (esi.scriptId != -1 && esi.exerciseId != -1)
|
||||
esi.valid = true;
|
||||
|
||||
return esi;
|
||||
}
|
||||
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <logger.h>
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
#include <ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <AssetManagement/asm_data_plugin_interface.h>
|
||||
#include "thpcommon_export.h"
|
||||
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
|
||||
enum UploadState
|
||||
{
|
||||
ThpUnknownUploadState,
|
||||
ThpUploadNotActive,
|
||||
ThpConnectToHost,
|
||||
ThpUploadActive,
|
||||
ThpAlreadyUploaded,
|
||||
ThpUploadError,
|
||||
};
|
||||
|
||||
struct ExportedScriptInformation
|
||||
{
|
||||
bool valid { false };
|
||||
|
||||
QString exerciseName;
|
||||
QString scriptName;
|
||||
QString jsonPath;
|
||||
QString rootDirectory;
|
||||
qint64 exerciseId = -1;
|
||||
qint64 exportTime = 0;
|
||||
qint64 fileSize = 0;
|
||||
bool local = true;
|
||||
UploadState uploaded = ThpUnknownUploadState;
|
||||
qint64 uploadTime = 0;
|
||||
int scriptId = -1;
|
||||
|
||||
int id() const { return scriptId; }
|
||||
|
||||
QJsonValue toJson() const;
|
||||
static ExportedScriptInformation fromJson(const QJsonValue &val,
|
||||
const bool local = true,
|
||||
const UploadState uploadStates = ThpUnknownUploadState);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class THPCOMMON_EXPORT ExportedScriptsModel : public LtsWidgets::LtsAbstractTableModel<ExportedScriptInformation>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
ColId,
|
||||
ColExercise,
|
||||
ColName,
|
||||
ColCreated,
|
||||
ColDownloaded,
|
||||
ColLocation,
|
||||
ColUploadedTime,
|
||||
ColUploaded,
|
||||
};
|
||||
explicit ExportedScriptsModel(QObject *parent = nullptr);
|
||||
|
||||
bool init(const QString &rootDirectoryToScan);
|
||||
void setServerContent(const QString &jsonArray);
|
||||
void setOC(bool isOC) { m_isOC = isOC; }
|
||||
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
bool removeRow(int row) override;
|
||||
bool setLocalState(const int row, const bool localHost);
|
||||
bool setUploadState(const int row, const UploadState uploadState, const qint64 uploadTime, const qint64 fileSize);
|
||||
bool createDataJson(const QString &rootDirectory, const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc,
|
||||
const std::shared_ptr<AssetManagement::Interface::Dtc> &asmDtc,
|
||||
int exerciseId) const;
|
||||
void addDownloadData(const ExportedScriptInformation &esi);
|
||||
|
||||
private:
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
QString exercisePath(const QString &rootDirectory, const int exerciseId) const;
|
||||
qint64 downloadTime(const ExportedScriptInformation &val) const;
|
||||
|
||||
private:
|
||||
bool m_isOC { false };
|
||||
QString m_rootDirectoryToScan;
|
||||
};
|
||||
}
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
#include "tpm_process_dialog.h"
|
||||
#include "ui_tpm_process_dialog.h"
|
||||
|
||||
|
||||
namespace TakeHomePackageManager
|
||||
{
|
||||
ProcessOverlay::ProcessOverlay(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::ProcessOverlay)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbCancel, &QPushButton::clicked,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->pbCancel->setEnabled(false);
|
||||
emit signalCancel();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
ProcessOverlay::~ProcessOverlay()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void ProcessOverlay::setCancelEnabled(bool enabled)
|
||||
{
|
||||
m_ui->pbCancel->setEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
void ProcessOverlay::setStatus(const QString &text, qint64 totalFiles, qint64 curFile, qint64 totalSize, qint64 curPos, const QString &curName)
|
||||
{
|
||||
if (!text.isEmpty())
|
||||
m_ui->lblStatus->setText(text);
|
||||
|
||||
if (!curName.isEmpty())
|
||||
m_ui->lblFilename->setText(curName);
|
||||
|
||||
double progressBytes = (totalSize == 0) ? (double)0 : ((double)curPos / (double)totalSize);
|
||||
double progressFiles = (((double)curFile - 1) / (double)totalFiles);
|
||||
double progressTotal = progressFiles + (progressBytes / (double)totalFiles);
|
||||
|
||||
progressBytes = qRound(progressBytes * 100);
|
||||
progressFiles = qRound(progressFiles * 100);
|
||||
progressTotal = qRound(progressTotal * 100);
|
||||
|
||||
m_ui->pbarFiles->setValue(progressFiles);
|
||||
m_ui->pbarBytes->setValue(progressBytes);
|
||||
m_ui->pbarProgress->setValue(progressTotal);
|
||||
|
||||
QLocale l;
|
||||
|
||||
if (curFile == 0)
|
||||
m_ui->lblFiles->setText(QStringLiteral(" - "));
|
||||
else
|
||||
m_ui->lblFiles->setText(QStringLiteral("%1 / %2").arg(l.toString(curFile)).arg(l.toString(totalFiles)));
|
||||
|
||||
if (curPos == 0)
|
||||
m_ui->lblBytes->setText(QStringLiteral(" - "));
|
||||
else
|
||||
m_ui->lblBytes->setText(QStringLiteral("%1 / %2").arg(l.toString(curPos)).arg(l.toString(totalSize)));
|
||||
}
|
||||
}
|
||||
Loaded 100 of 895 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user