- training_area_telegrams.cpp: Fixed QJsonObject initializer syntax (Qt6 requires {{}} not ({}))
- training_area_telegrams.cpp: Fixed fromJson() methods to access m_* members directly
- training_area_telegrams.cpp: Fixed brace mismatches in multiple toJson() methods
- training_area_telegrams.h: Changed Header struct to public members for consistency
- tx_mixin.cpp: Fixed getEquipmentNumber() template for direct member access
- lts_coordinate.cpp: Added missing #include <iomanip>
- MIGRATION_STATUS.md: Added migration progress tracking document
C++17 constraint enforced due to RTI Connext DDS 7.7.0 incompatibility with C++20+
Build status: BUILD_RTI=OFF successful (0 errors, warnings only)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
498 lines
15 KiB
C++
498 lines
15 KiB
C++
/**
|
|
* @RDE_HEADER@
|
|
* Keeps the DDS Connector and common data about the session
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*
|
|
* Created by Mike Wille, SLSE, 2016-05-15
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "lts_session_data_dds.h"
|
|
#ifdef BUILD_RTI
|
|
#include "lts_session_manager.h"
|
|
#endif
|
|
|
|
#include <LtsAppDescriptor/lts_app_descriptor.h>
|
|
#include <LtsSession/ltssession_export.h>
|
|
#include <LtsWidgets/lts_base.h>
|
|
#include <QtCore/QDebug>
|
|
#include <QtCore/QJsonObject>
|
|
#include <QtCore/QMap>
|
|
#include <QtCore/QObject>
|
|
#include <QtCore/QPointer>
|
|
#include <QtCore/QVector>
|
|
#include <memory>
|
|
|
|
namespace LtsWidgets
|
|
{
|
|
class LtsBackgroundWidget;
|
|
class LtsTabWidget;
|
|
class LtsBaseLayoutWidget;
|
|
struct ExerciseData;
|
|
class LtsDialog;
|
|
class LtsDragIcon;
|
|
} // namespace LtsWidgets
|
|
|
|
namespace LtsNotification
|
|
{
|
|
class LtsNotification;
|
|
class LtsNotificationController;
|
|
} // namespace LtsNotification
|
|
|
|
namespace LtsPluginManager
|
|
{
|
|
struct PluginInstance;
|
|
struct AppPluginInstance;
|
|
} // namespace LtsPluginManager
|
|
|
|
namespace DeveloperTools
|
|
{
|
|
class DevDialog;
|
|
class AppWidget;
|
|
} // namespace DeveloperTools
|
|
|
|
namespace Core
|
|
{
|
|
namespace Interface
|
|
{
|
|
class Ftc;
|
|
}
|
|
} // namespace Core
|
|
|
|
namespace OnlineHelp
|
|
{
|
|
class ForeignOnlineHelpViewerGuiInterface;
|
|
}
|
|
|
|
namespace LtsSession
|
|
{
|
|
class LTSSESSION_EXPORT LtsSession : public LtsSessionDataDds
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
static bool s_valgrind;
|
|
static int s_nextSessionId;
|
|
|
|
enum class PluginInstanceStatus {
|
|
UNKNOWN = 0,
|
|
LOADED,
|
|
FAILED, // e.g. fetchInterfaces gone wrong
|
|
};
|
|
|
|
static QString appToString(LtsAppDescriptor::App app);
|
|
static QString appIconFilename(LtsAppDescriptor::App app);
|
|
static QIcon appToIcon(LtsAppDescriptor::App app);
|
|
|
|
#ifdef BUILD_RTI
|
|
explicit LtsSession(LtsSessionManager* sessionManager);
|
|
#else
|
|
explicit LtsSession();
|
|
#endif
|
|
~LtsSession();
|
|
|
|
QString toString() const;
|
|
|
|
#ifdef BUILD_RTI
|
|
LtsSessionManager* getSessionManager();
|
|
#endif
|
|
bool init(const DdsConnectionParams& connParams, const QVector<LtsPluginManager::AppPluginInstance>& dataPluginList,
|
|
const QVector<LtsPluginManager::AppPluginInstance>& guiPluginList, bool hidden);
|
|
#ifdef BUILD_RTI
|
|
bool init(const dds::domain::DomainParticipant& dp, const DdsConnectionParams& connParams,
|
|
const QVector<LtsPluginManager::AppPluginInstance>& dataPluginList,
|
|
const QVector<LtsPluginManager::AppPluginInstance>& guiPluginList);
|
|
#endif
|
|
#ifdef BUILD_RTI
|
|
void makeVisible();
|
|
#else
|
|
void makeVisible(); // no-op when BUILD_RTI=OFF
|
|
#endif
|
|
|
|
void setPayloadsEnabled()
|
|
{
|
|
m_payloads = true;
|
|
} // cannot be reverted
|
|
|
|
void aboutToClose();
|
|
|
|
bool isInitializationDone() const
|
|
{
|
|
return m_initDone;
|
|
}
|
|
|
|
void presetBaseLayoutAsSecondaryWidget()
|
|
{
|
|
m_presetBaseLayoutAsSecondaryWidget = true;
|
|
}
|
|
|
|
/**
|
|
* @brief addAction - IMPORTANT: Actions have to be translated on retranslate by adding the same action (with same
|
|
* identifier) but with translated text & menu group! This replaces the text & menu group only. The pointer to the
|
|
* action stays the same.
|
|
* @param plData
|
|
* @param isFirstRun
|
|
* @return
|
|
*/
|
|
LtsWidgets::LtsDragIcon* addAction(const LtsWidgets::PluginData& plData, bool isFirstRun = false);
|
|
void setMenuVisible(bool visible = true);
|
|
#ifdef BUILD_RTI
|
|
bool removeMenuAction(LtsWidgets::LtsDragIcon* icon);
|
|
#endif
|
|
int screenId() const;
|
|
int screenContainerId() const;
|
|
int screenTypeId() const;
|
|
LtsAppDescriptor::App app() const;
|
|
|
|
void setScreenIdPreset(int screenId)
|
|
{
|
|
m_screenIdPreset = screenId;
|
|
}
|
|
|
|
void setScreenContainerIdPreset(int screenPart)
|
|
{
|
|
m_screenContainerIdPreset = screenPart;
|
|
}
|
|
|
|
bool isForeverInvisible() const
|
|
{
|
|
return m_foreverInvisible;
|
|
}
|
|
|
|
LtsNotification::LtsNotification* createNotification(const QString& identifier);
|
|
|
|
/**
|
|
* @brief setExerciseData is called by the ExerciseManagement plugin and sets the human reabale name of the exercise
|
|
* and puts the text into all base layouts of this session
|
|
* @param exerciseData the human reable exercise name of the current exercise
|
|
*/
|
|
#ifdef BUILD_RTI
|
|
void setExerciseData(const LtsWidgets::ExerciseData& exerciseData);
|
|
const LtsWidgets::ExerciseData* exerciseData() const;
|
|
void setProfilePicture(const QPixmap& pixmap);
|
|
#else
|
|
void setExerciseData(const LtsWidgets::ExerciseData& exerciseData) { Q_UNUSED(exerciseData) }
|
|
const LtsWidgets::ExerciseData* exerciseData() const { return nullptr; }
|
|
void setProfilePicture(const QPixmap& pixmap) { Q_UNUSED(pixmap) }
|
|
#endif
|
|
|
|
void setBaseLayoutVisible()
|
|
{
|
|
m_hasBaseLayout = true;
|
|
} // cannot be reverted after base layout was created (creation begins after all payloads have been executed OR if
|
|
// makeVisible was called)!
|
|
|
|
bool isVisible() const
|
|
{
|
|
return (m_baseLayout != nullptr);
|
|
}
|
|
|
|
const QString& name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
void setName(const QString& name)
|
|
{
|
|
m_name = name;
|
|
}
|
|
|
|
/**
|
|
* @brief isChildOfSession can be used to check if a fiven QWidget is part of the current Session's application
|
|
*
|
|
* @param child widget to check against.
|
|
* @return true if widget is child of session baselayout
|
|
*/
|
|
bool isChildOfSession(QWidget* child);
|
|
|
|
#ifdef BUILD_RTI
|
|
LtsWidgets::LtsBaseLayoutWidget* baseLayout()
|
|
{
|
|
return m_baseLayout;
|
|
}
|
|
#else
|
|
void* baseLayout() const { return nullptr; }
|
|
#endif
|
|
|
|
QWidget* baseLayoutWidget(); // prevents some classes to include LtsBaseLayoutWidget.h just to specify the blw as a
|
|
// parent widget
|
|
|
|
void setMarkForDeletion()
|
|
{
|
|
m_markedForDeletion = true;
|
|
} // session not needed anymore after payloads? then mark for deletion and after payloads, this session will be
|
|
// deleted(Later)
|
|
|
|
void doneInitializingSession(); // TODO: private
|
|
bool notifyUnsavedChanges(); // true if NO unsaved changes
|
|
|
|
const QVector<LtsWidgets::LtsBackgroundWidget*>& bgWidgets() const
|
|
{
|
|
return m_bgWidgets;
|
|
}
|
|
|
|
// checks if a widget with the given data already exists
|
|
bool widgetExists(const QString& menuGroup, const QString& identifier, LtsWidgets::LayoutArea area) const;
|
|
/**
|
|
* @brief addWidget <exact copy of addWidget in LtsBaseLayoutWidget [is redirected to the coherent
|
|
* LtsBaseLayoutWidget]> keep identifier empty to prevent checking for existing tabs
|
|
* @return (see addWidget in LtsBaseLayoutWidget)
|
|
*/
|
|
bool addWidget(LtsWidgets::LtsDialog* widget, const QString& menuGroup, const QString& identifier,
|
|
LtsWidgets::LayoutArea area = LtsWidgets::LayoutArea::eUnknown, bool setClosable = true);
|
|
|
|
LtsWidgets::LtsDialog* getWidget(const QString& menuGroup, const QString& identifier, LtsWidgets::LayoutArea area);
|
|
bool focusTab(const QString& menuGroup, const QString& identifier, LtsWidgets::LayoutArea area);
|
|
|
|
/** WARNING: do not save the returned value, as baseLayouts can die (which kills LtsTabWidget also), so reuse this
|
|
* method instead of saving the pointer to the LtsTabWidget
|
|
* @brief locateWidget locates the given widget 'widget' and returning the TabWidget on which it is on - widgets can
|
|
* be available in one of many LayoutAreas (TabWidgets) of many LtsBaseLayoutWidgets
|
|
* @param widgetToLocate the widget to look for in the given layoutArea which is located in one of many
|
|
* LtsBaseLayoutWidget
|
|
* @param area the area the widget is located
|
|
* @return LtsTabWidget on which the widget is located
|
|
*/
|
|
LtsWidgets::LtsTabWidget* locateWidget(QWidget* widgetToLocate, LtsWidgets::LayoutArea area);
|
|
|
|
/**
|
|
* @brief enable/disable baseLayout menu
|
|
* @param on if true enable otherwise disable
|
|
*/
|
|
void enableBaseLayoutMenu(bool on = true);
|
|
|
|
/**
|
|
* @brief enable/disable LayoutArea
|
|
* @param area the area to enable/disable
|
|
* @param on if true enable otherwise disable
|
|
*/
|
|
void enableBaseLayoutArea(LtsWidgets::LayoutArea area, bool on = true);
|
|
|
|
/**
|
|
* @brief Return the workstation ip for this workstation (== full ipv4 adress) - workstation id comes later from Asm
|
|
*/
|
|
static int workstationIp(); // really in LtsSession?
|
|
/**
|
|
* @brief Return the workstation name
|
|
*/
|
|
static QString workstationName(); // really in LtsSession?
|
|
|
|
/**
|
|
* @brief missingRightActions Do not use.
|
|
* @return
|
|
*/
|
|
/*const*/ QVector<LtsWidgets::PluginData>& missingRightActions() /*const*/
|
|
{
|
|
return m_missingRightActions;
|
|
}
|
|
|
|
void setSavegame(const QJsonObject& sg)
|
|
{
|
|
m_savegame = sg;
|
|
}
|
|
|
|
const QJsonObject& getSavegame() const
|
|
{
|
|
return m_savegame;
|
|
}
|
|
|
|
void setHidden()
|
|
{
|
|
m_hidden = true;
|
|
}
|
|
|
|
const QString workspaceId() const;
|
|
void setWorkspaceId(const QString& newWorkspaceId);
|
|
|
|
#ifdef BUILD_RTI
|
|
LtsWidgets::ExcState exerciseState() const;
|
|
#else
|
|
LtsWidgets::ExcState exerciseState() const { return LtsWidgets::ExerciseState::eUnknown; }
|
|
#endif // BUILD_RTI
|
|
|
|
void setLoadedFromSavegame()
|
|
{
|
|
m_loadedFromSavegame = true;
|
|
}
|
|
|
|
bool isLoadedFromSavegame() const
|
|
{
|
|
return m_loadedFromSavegame;
|
|
}
|
|
|
|
void addDeveloperActions();
|
|
#ifdef BUILD_RTI
|
|
void refetchActions(); // Do not use.
|
|
#else
|
|
void refetchActions(); // Do not use. (no-op when BUILD_RTI=OFF)
|
|
#endif
|
|
void setDependency(LtsSession* session)
|
|
{
|
|
#ifdef BUILD_RTI
|
|
if (m_dependency)
|
|
{
|
|
ERROR_LOG(m_logger) << "Tried to set session dependency on self";
|
|
return;
|
|
}
|
|
m_dependency = session;
|
|
#else
|
|
Q_UNUSED(session)
|
|
#endif
|
|
}
|
|
|
|
bool hasDependency(LtsSession* session)
|
|
{
|
|
return (m_dependency.data() == session);
|
|
}
|
|
|
|
LtsSession* dependency() const
|
|
{
|
|
return m_dependency;
|
|
}
|
|
|
|
// bogus.
|
|
void setNeedsToBeSuccessfullyPlaced(bool needed = true)
|
|
{
|
|
m_needsToBeSuccessfullyPlaced = needed;
|
|
} // works even after session creation as 'slotStartPluginInit', which finalizes the session (creates blw, etc.) is
|
|
// called async!
|
|
|
|
int id() const
|
|
{
|
|
return m_id;
|
|
}
|
|
|
|
public slots:
|
|
#ifdef BUILD_RTI
|
|
void slotExecuteNextPayload(); // NEVER call this directly, queue a signal to this slot !
|
|
void slotPluginInitDone(); // NEVER call this directly, queue a signal to this slot !
|
|
#endif
|
|
void slotShowOnlineHelp(const QString& fileName);
|
|
// void takeOverBdv();
|
|
|
|
private slots:
|
|
#ifdef BUILD_RTI
|
|
void slotShowOperatorSettings();
|
|
#endif
|
|
void slotSwap();
|
|
void slotStapleTopicLockHandler(LtsWidgets::LtsDialog* widget);
|
|
void slotStopWaitDialog();
|
|
#ifdef BUILD_RTI
|
|
void slotStartPluginInit();
|
|
void slotMonitorSelected();
|
|
void delayScriptEditorStart();
|
|
#endif
|
|
|
|
signals:
|
|
void signalInitializationAborted();
|
|
void _signalDoneInitializingSession(); // internal
|
|
void signalDoneInitializingSession(); // is called AFTER all payloads have been executed (on no payloads, called
|
|
// after session was created) FOR LTSLOGIN !
|
|
void signalClose(); // tells the session manager to close this session
|
|
void signalLogout();
|
|
void signalQuit(); // for payloads, so that they can quit an app
|
|
void signalStillAlive();
|
|
void signalExerciseDataChanged();
|
|
void signalScreenIdChanged(int screenId, int screenContainerId, int screenTypeId);
|
|
void sessionAboutToBeDestroyed(LtsSession* session);
|
|
void workspaceIdChanged(const QString& newWorkspaceId);
|
|
void signalTakeOverBdv();
|
|
void hideAllOtherBLWs(QObject* caller);
|
|
void taskSwitch(QObject* caller);
|
|
|
|
private:
|
|
friend class DeveloperTools::DevDialog;
|
|
friend class DeveloperTools::AppWidget;
|
|
#ifdef BUILD_RTI
|
|
friend class LtsSessionManager;
|
|
#endif
|
|
|
|
#ifdef BUILD_RTI
|
|
bool event(QEvent* e) override;
|
|
#endif
|
|
void createBaseLayout();
|
|
#ifdef BUILD_RTI
|
|
void initializePlugins(const QVector<LtsPluginManager::AppPluginInstance>& dataPluginList,
|
|
const QVector<LtsPluginManager::AppPluginInstance>& guiPluginList);
|
|
void initializeDataPlugins(const QVector<LtsPluginManager::AppPluginInstance>& dataPluginList);
|
|
void initializeGuiPlugins(const QVector<LtsPluginManager::AppPluginInstance>& guiPluginList);
|
|
bool tryInitGuiPlugin(const QString& guiPluginKey, std::shared_ptr<GuiPluginBase::Interface>& guiPlugin);
|
|
void clearDataPluginInterfaces();
|
|
void clearGuiPluginInterfaces();
|
|
void executePayloads();
|
|
#endif
|
|
void connectOnlineHelpButton(LtsWidgets::LtsDialog* widget);
|
|
// TODO: AFTER FAT !! void stapleWidget(LtsWidgets::LtsDialog *dialog); // FIXME: HACK: because an LtsDialog can
|
|
// directly add widgets to the base layout and misses the staples...
|
|
void aboutToCloseTab(LtsWidgets::LayoutArea area);
|
|
|
|
#ifdef BUILD_RTI
|
|
QPointer<LtsSessionManager> m_sessionManager;
|
|
#endif
|
|
#ifdef BUILD_RTI
|
|
QMap<int /*priority*/, std::shared_ptr<GuiPluginBase::Interface>>
|
|
m_payloadPriorityMap; // QMap automatically sorts by key on iteration and overwrites multiple occurences with
|
|
// the latest)
|
|
QList<std::shared_ptr<GuiPluginBase::Interface>>
|
|
m_payloadList; // for payloads that don't care when they are executed (prio '9999' plugins)
|
|
#endif
|
|
LtsWidgets::LtsBackgroundWidget* m_mainBackground;
|
|
bool m_hasBaseLayout;
|
|
#ifdef BUILD_RTI
|
|
LtsWidgets::LtsBaseLayoutWidget* m_baseLayout;
|
|
#else
|
|
void* m_baseLayout{nullptr}; // stub for non-RTI build
|
|
#endif
|
|
bool m_markedForDeletion;
|
|
bool m_payloads;
|
|
QVector<LtsNotification::LtsNotificationController*> m_notiCtlList;
|
|
bool m_initDone; // set by doneInitializingSession / signalDoneInitializingSession
|
|
#ifdef BUILD_RTI
|
|
bool m_payloadsDone{false}; // for debug
|
|
#endif
|
|
bool m_menuVisible;
|
|
// bool m_ignoreSignalInLoop = false;
|
|
bool m_firstActionsFetch;
|
|
#ifdef BUILD_RTI
|
|
LtsWidgets::ExerciseData* m_exerciseData;
|
|
#else
|
|
void* m_exerciseData{nullptr}; // stub for non-RTI build
|
|
#endif
|
|
QVector<LtsWidgets::PluginData> m_missingRightActions;
|
|
std::shared_ptr<Core::Interface::Ftc> m_coreFtc;
|
|
#ifdef BUILD_RTI
|
|
GuiPluginBase::Interface* m_currentInitIfc; // not owning
|
|
bool m_slotPluginInitDoneMutex;
|
|
bool m_pluginInitDone; // set by slotPluginInitDone
|
|
#endif
|
|
QJsonObject m_savegame;
|
|
bool m_hidden; // if true, does not create BLW
|
|
int m_screenId{-1};
|
|
int m_screenContainerId{-1};
|
|
int m_screenIdPreset{-1};
|
|
int m_screenContainerIdPreset{-1};
|
|
bool m_loadedFromSavegame;
|
|
std::shared_ptr<OnlineHelp::ForeignOnlineHelpViewerGuiInterface> m_ohvIfc;
|
|
bool m_foreverInvisible; // if true, creates BLW but hides it and does not use MMM
|
|
#ifdef BUILD_RTI
|
|
QStringList m_failedFetches;
|
|
#endif
|
|
QVector<LtsWidgets::LtsBackgroundWidget*> m_bgWidgets;
|
|
QString m_workspaceId;
|
|
bool m_needsToBeSuccessfullyPlaced{
|
|
true /* ALWAYS! */ /*false*/}; // if set to true, 'signalDoneInitializingSession' will only be called after the
|
|
// blw was successfully placed by MMM (even works if MMM inavtive (off))
|
|
QString m_name;
|
|
QTimer* m_blub{nullptr};
|
|
QTimer* m_scriptEditorTimer{nullptr};
|
|
int m_blub2;
|
|
QPointer<LtsSession> m_dependency; // when MMM iprovides the screen selection for this app, it isn't allowed to
|
|
// replace apps that are dependencies of this app (e.g. logout bug)
|
|
bool m_presetBaseLayoutAsSecondaryWidget{false};
|
|
int m_id;
|
|
};
|
|
|
|
} // namespace LtsSession
|