- Formatted all CodeGen module files (9 files) - Formatted LtsAppDescriptor module files - Formatted LtsAppManager/AppChooser files - Applied clang-format to all DTC and enum headers across modules - Removed coordTransTests from CommonUnitTestsPlaceholder (moved to tests/) Cosmetic changes only, no functional modifications. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
401 lines
13 KiB
C++
401 lines
13 KiB
C++
|
|
|
|
#include "bdv_controller.h"
|
|
|
|
#include "bdv_bgviewer_widget_container.h"
|
|
#include "bdv_dds_controller.h"
|
|
|
|
#include <Common/bdv_communication_interface_internal.h>
|
|
#include <Common/bdv_plugin_provider.h>
|
|
#include <LtsAppManager/lts_app_manager.h>
|
|
#include <LtsPluginManager/lts_plugin_manager.h>
|
|
#include <LtsSession/lts_session.h>
|
|
#include <QDir>
|
|
#include <QMessageBox>
|
|
#include <ngltools/ngltools_filesystem.h>
|
|
#include <utility>
|
|
|
|
namespace BuildingViewer
|
|
{
|
|
static int argc_dummy = 1;
|
|
static char* argv_dummy[] = {(char*)"Dummy"};
|
|
|
|
BgViewerController::BgViewerController(QObject* parent)
|
|
: QObject(parent), m_mainloop(argc_dummy, argv_dummy, nullptr), m_widgetStolen(false), m_comIfc(nullptr),
|
|
m_pBgViewerDDSController(nullptr), m_bgvApp(nullptr), m_tickTimer(new QTimer(this))
|
|
{
|
|
m_tickTimer->setInterval(1000 / 25);
|
|
connect(m_tickTimer, &QTimer::timeout, this, [this]() { m_mainloop.tick(); });
|
|
|
|
m_mainloop.getViewerInterface()->getMainWindow()->setMinimumSize(200, 200);
|
|
|
|
m_viewerInterface = m_mainloop.getViewerInterface();
|
|
m_comIfc = new CommunicationInterfaceInternal(m_viewerInterface);
|
|
m_viewerInterface->SetViewerCallback(m_comIfc);
|
|
|
|
m_pBgViewerDDSController = new BuildingViewerDdsController(m_comIfc, m_viewerInterface);
|
|
|
|
connect(m_pBgViewerDDSController, &BuildingViewerDdsController::signalDdsInitFinished, this,
|
|
[this]() { m_initExerciseWasSuccessful = true; });
|
|
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalBgViewerInitFinished, this,
|
|
&BgViewerController::signalBgViewerInitFinished);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalReceivedBuildingList, this,
|
|
&BgViewerController::signalReceivedBuildingList);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalReceivedViewState, this,
|
|
&BgViewerController::signalReceivedViewState);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalPlayerPicked, this,
|
|
&BgViewerController::signalPlayerPicked);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalAssetPicked, this, &BgViewerController::signalAssetPicked);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerEventWidgetClosed, this,
|
|
&BgViewerController::signalViewerEventWidgetClosed);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerEventWidgetMaximized, this,
|
|
&BgViewerController::signalViewerEventWidgetMaximized);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerEventWidgetMinimized, this,
|
|
&BgViewerController::signalViewerEventWidgetMinimized);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerEventWidgetFocused, this,
|
|
&BgViewerController::signalViewerEventWidgetFocused);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerEventRoomNameClicked, this,
|
|
&BgViewerController::signalViewerEventRoomNameClicked);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerZoomChanged, this,
|
|
&BgViewerController::signalViewerZoomChanged);
|
|
connect(m_comIfc, &CommunicationInterfaceInternal::signalViewerEventButton, this,
|
|
&BgViewerController::signalViewerEventButton);
|
|
}
|
|
|
|
BgViewerController::~BgViewerController()
|
|
{
|
|
delete m_tickTimer;
|
|
|
|
if (m_bgvApp != nullptr)
|
|
{
|
|
m_bgvApp->disconnect();
|
|
delete m_bgvApp;
|
|
}
|
|
|
|
delete m_pBgViewerDDSController;
|
|
delete m_comIfc;
|
|
|
|
m_bgvApp = nullptr;
|
|
m_comIfc = nullptr;
|
|
m_pBgViewerDDSController = nullptr;
|
|
}
|
|
|
|
void BgViewerController::excConnect(const std::vector<std::string>& paths, const QString& strXMLFile)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excConnect(paths, strXMLFile);
|
|
}
|
|
|
|
void BgViewerController::excGetBuildingList()
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excGetBuildingList();
|
|
}
|
|
|
|
void BgViewerController::excGetViewState()
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excGetViewState();
|
|
}
|
|
|
|
void BgViewerController::excHighlightView(const QString& strFeatureID)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excHighlightView(strFeatureID);
|
|
}
|
|
|
|
void BgViewerController::excRestoreViewState(const QJsonValue& state)
|
|
{
|
|
if (m_comIfc)
|
|
{
|
|
m_comIfc->excRestoreViewState(state);
|
|
m_comIfc->excGetBuildingList();
|
|
}
|
|
}
|
|
|
|
void BgViewerController::excSetGlobalDotsMode(bool useDots)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excSetGlobalDotsMode(useDots);
|
|
}
|
|
|
|
void BgViewerController::excSetGlobalTransparency(double transparency)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excSetGlobalTransparency(transparency);
|
|
}
|
|
|
|
void BgViewerController::excSetGlobalViewMode(bool useOrtho)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excSetGlobalViewMode(useOrtho);
|
|
}
|
|
|
|
void BgViewerController::excSetHitlineDuration(uint32_t duration_s)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excSetHitlineDuration(duration_s);
|
|
}
|
|
|
|
void BgViewerController::excStartRecording(const QString& strPathOutputFolder, const QString& strFeatureID, int w,
|
|
int h, int framerate, int quality)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excStartRecording(strPathOutputFolder, strFeatureID, w, h, framerate, quality);
|
|
}
|
|
|
|
void BgViewerController::excStopRecording(const QString& strFeatureID)
|
|
{
|
|
if (m_comIfc)
|
|
m_comIfc->excStopRecording(strFeatureID);
|
|
}
|
|
|
|
QString BgViewerController::buildingModelPath()
|
|
{
|
|
QVector<QString> directoriesToSearch = NGL::directories(NGL::FileType::ConfigFile);
|
|
#ifndef WIN32
|
|
directoriesToSearch += QStringLiteral("/opt");
|
|
#endif
|
|
|
|
for (const QString& d : std::as_const(directoriesToSearch))
|
|
{
|
|
const QDir dir(d + QStringLiteral("/BuildingModels/StaticMeshes/"));
|
|
if (dir.exists() && dir.isReadable())
|
|
return dir.absolutePath();
|
|
INFO_LOG(getLogger("BgViewerController"))
|
|
<< "Map path '" << dir.absolutePath() << "' either does not exist or is not readable - skipping";
|
|
}
|
|
return QString();
|
|
}
|
|
|
|
void BgViewerController::clearInterfaces(const LtsSession::DdsConnectionParams& conParams)
|
|
{
|
|
DEBUG_LOG(m_logger) << "BgViewerControllerSingleton::clearInterfaces()";
|
|
if (m_pBgViewerDDSController && m_currentDdsConnParams == conParams)
|
|
{
|
|
m_pBgViewerDDSController->uninitialize();
|
|
m_currentDdsConnParams = LtsSession::DdsConnectionParams();
|
|
}
|
|
}
|
|
|
|
void BgViewerController::hideLiveVideo() {}
|
|
|
|
bool BgViewerController::isBgViewerApplicationRunning() const
|
|
{
|
|
return (m_bgvApp != nullptr);
|
|
}
|
|
|
|
LtsSession::DdsConnectionParams BgViewerController::currentDdsConnParams() const
|
|
{
|
|
return m_currentDdsConnParams;
|
|
}
|
|
|
|
PluginProvider* BgViewerController::activeSession() const
|
|
{
|
|
return m_pBgViewerDDSController->activeSession();
|
|
}
|
|
|
|
bool BgViewerController::init(PluginProvider* pSession, bool bStartRendering, const QString& modelPath)
|
|
{
|
|
DEBUG_LOG(m_logger) << "getDdsController init: " << pSession->toString();
|
|
|
|
if (m_currentDdsConnParams == pSession->connParams())
|
|
{
|
|
if (m_initExerciseWasSuccessful)
|
|
{
|
|
DEBUG_LOG(m_logger) << "BgViewerControllerSingleton::init Already initialized";
|
|
slotLoadBuilding();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
m_currentDdsConnParams = pSession->connParams();
|
|
m_initExerciseWasSuccessful = false;
|
|
if (!m_pBgViewerDDSController->init(m_bgViewerBaseLayoutWidget, modelPath, pSession))
|
|
return false;
|
|
if (bStartRendering)
|
|
{
|
|
m_bgvAppIsInitialized = true;
|
|
m_tickTimer->start();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool BgViewerController::forceInit(PluginProvider* pSession)
|
|
{
|
|
delete m_pBgViewerDDSController;
|
|
m_pBgViewerDDSController = new BuildingViewerDdsController(m_comIfc, m_viewerInterface);
|
|
|
|
DEBUG_LOG(m_logger) << "FORCE INIT! with " << pSession;
|
|
return (m_pBgViewerDDSController->init(m_bgViewerBaseLayoutWidget, buildingModelPath(), pSession));
|
|
}
|
|
|
|
void BgViewerController::showBgViewerInfoMessageBox()
|
|
{
|
|
static bool showMsgBox = true;
|
|
|
|
if (!showMsgBox)
|
|
return;
|
|
|
|
QMessageBox msgbox;
|
|
msgbox.setText(
|
|
tr("BuildingViewer is currently used by another application.\nPlease close the corresponding application."));
|
|
msgbox.setIcon(QMessageBox::Information);
|
|
msgbox.addButton(QMessageBox::Ok);
|
|
|
|
QCheckBox* cb = new QCheckBox(tr("Do not show this message again."));
|
|
msgbox.setCheckBox(cb);
|
|
|
|
connect(cb, &QCheckBox::stateChanged, [](int state) { showMsgBox = state != Qt::Checked; });
|
|
|
|
msgbox.exec();
|
|
}
|
|
|
|
bool BgViewerController::startBgViewerAppInSession(PluginProvider* pStartingSession)
|
|
{
|
|
DEBUG_LOG(m_logger) << std::hex << this << " startBgViewerAppInSession "
|
|
<< (m_currentDdsConnParams == pStartingSession->connParams());
|
|
|
|
if (m_bgvApp && (m_currentDdsConnParams == pStartingSession->connParams()))
|
|
{
|
|
INFO_LOG(m_logger) << std::hex << this << " BuildingViewer already opened. Doing nothing...";
|
|
return true;
|
|
}
|
|
|
|
if (!m_bgvApp && m_widgetStolen)
|
|
{
|
|
showBgViewerInfoMessageBox();
|
|
return false;
|
|
}
|
|
|
|
if (m_bgvApp)
|
|
{
|
|
DEBUG_LOG(m_logger) << std::hex << this << " Releasing m_bgvApp";
|
|
delete m_bgvApp;
|
|
m_bgvApp = nullptr;
|
|
|
|
clearInterfaces(m_currentDdsConnParams);
|
|
m_comIfc->excCloseAllViews();
|
|
}
|
|
|
|
m_bgvAppIsInitialized = false;
|
|
m_bgvApp = LtsAppManager::LtsAppManager::getInstance()->createApp(LtsAppDescriptor::App::BuildingViewer,
|
|
pStartingSession->connParams());
|
|
if (!m_bgvApp || !m_bgvApp->sessions().size())
|
|
{
|
|
ERROR_LOG(m_logger) << std::hex << this << " m_bgvApp is nullptr or has no associated session!";
|
|
return false;
|
|
}
|
|
|
|
connect(m_bgvApp, &LtsPluginManager::LtsPluginManager::signalInitializationFinished, this,
|
|
[this, pStartingSession]() {
|
|
m_tickTimer->start();
|
|
m_bgvAppIsInitialized = true;
|
|
|
|
QWidget* w = nullptr;
|
|
if (m_bgvApp)
|
|
{
|
|
LtsSession::LtsSession* session = m_bgvApp->getSession(pStartingSession->connParams().partitionType,
|
|
pStartingSession->connParams().partitionId);
|
|
w = session->baseLayoutWidget();
|
|
}
|
|
m_bgViewerBaseLayoutWidget = w;
|
|
|
|
slotLoadBuilding();
|
|
emit bgvAppIsInitialized();
|
|
});
|
|
|
|
connect(m_bgvApp, &LtsPluginManager::LtsPluginManager::destroyed, this, [this]() {
|
|
DEBUG_LOG(m_logger) << std::hex << this << " LtsPluginManager destroyed m_bgvApp";
|
|
m_tickTimer->stop();
|
|
clearInterfaces(m_currentDdsConnParams);
|
|
m_comIfc->excCloseAllViews();
|
|
m_bgvAppIsInitialized = false;
|
|
m_bgvApp = nullptr;
|
|
m_bgViewerBaseLayoutWidget = nullptr;
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
QWidget* BgViewerController::getBgViewerWidget()
|
|
{
|
|
if (m_widgetStolen)
|
|
{
|
|
showBgViewerInfoMessageBox();
|
|
return nullptr;
|
|
}
|
|
|
|
BgViewerWidgetContainer* pDummy = new BgViewerWidgetContainer(m_mainloop.getViewerInterface()->getMainWindow());
|
|
|
|
m_widgetStolen = true;
|
|
connect(pDummy, &BgViewerWidgetContainer::signalWidgetReleased, this, &BgViewerController::slotWidgetReleased);
|
|
return pDummy;
|
|
}
|
|
|
|
void BgViewerController::slotWidgetReleased()
|
|
{
|
|
m_widgetStolen = false;
|
|
}
|
|
|
|
void BgViewerController::openBuilding(const QString& strBuildingFeatureId)
|
|
{
|
|
m_buildingsToShow.push_back(strBuildingFeatureId.toStdString());
|
|
slotLoadBuilding();
|
|
}
|
|
|
|
void BgViewerController::closeBuilding(const QString& strBuildingFeatureId)
|
|
{
|
|
if (!strBuildingFeatureId.isEmpty())
|
|
{
|
|
const std::string s = strBuildingFeatureId.toStdString();
|
|
m_buildingsToShow.erase(std::remove_if(m_buildingsToShow.begin(), m_buildingsToShow.end(),
|
|
[s](const std::string& str) { return s == str; }),
|
|
m_buildingsToShow.end());
|
|
}
|
|
else
|
|
m_buildingsToShow.clear();
|
|
|
|
if (m_comIfc)
|
|
{
|
|
if (strBuildingFeatureId.isEmpty())
|
|
m_comIfc->excCloseAllViews();
|
|
else
|
|
m_comIfc->excCloseView({strBuildingFeatureId.toStdString()});
|
|
m_comIfc->excGetBuildingList();
|
|
}
|
|
}
|
|
|
|
void BgViewerController::updatePlayerSymbols(int size)
|
|
{
|
|
m_pBgViewerDDSController->updatePlayerSymbols(size);
|
|
}
|
|
|
|
void BgViewerController::closeAll()
|
|
{
|
|
m_bgvApp->deleteLater();
|
|
}
|
|
|
|
void BgViewerController::slotLoadBuilding()
|
|
{
|
|
if (!m_bgvAppIsInitialized)
|
|
return;
|
|
m_comIfc->excOpenView(m_buildingsToShow);
|
|
m_comIfc->excGetBuildingList();
|
|
m_buildingsToShow.clear();
|
|
}
|
|
|
|
void BgViewerController::slotStartRecording(const QString& strFolderPath, const QJsonValue& state)
|
|
{
|
|
excRestoreViewState(state);
|
|
excStartRecording(strFolderPath, QStringLiteral("all"), 800, 600, 15, 40);
|
|
}
|
|
|
|
void BgViewerController::slotStopRecording()
|
|
{
|
|
excStopRecording();
|
|
}
|
|
|
|
} // namespace BuildingViewer
|