Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Common/LtsAppManager/lts_app_manager.cpp
T
torstenandCopilot 7a6be7474e Qt6 migration: Fix BUILD_RTI=OFF build errors in TrainingAreaBase
- 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>
2026-08-23 20:49:23 +02:00

964 lines
31 KiB
C++

#include "lts_app_manager.h"
#include "AppChooser/app_chooser.h"
#include <LtsLogin/lts_login.h>
#include <LtsMultiMonitor/lts_multi_monitor.h>
#include <LtsPluginManager/lts_plugin_manager.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <LtsSession/lts_session_manager.h>
#include <LtsUtilsSettings/settings.h>
#include <LtsWidgets/lts_events.h>
#include <LtsWidgets/lts_global_wait_dialog.h>
#include <OperatorManagement/opm_settings_gui_plugin_interface.h>
#include <PluginInterfaces/gui_plugin_interface.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonValue>
#include <QtWidgets/QMessageBox>
#include <QtNetwork/QTcpServer>
#include <QtNetwork/QTcpSocket>
#include <QtCore/QTimer>
#include <QtCore/QUuid>
#include <utility>
#ifndef LTS_VERSION_MAJOR
#define LTS_VERSION_MAJOR "undefined"
#endif
#ifndef LTS_VERSION_MINOR
#define LTS_VERSION_MINOR "undefined"
#endif
#ifndef LTS_VERSION_PATCH
#define LTS_VERSION_PATCH "undefined"
#endif
#ifndef JENKINS_BUILD_NUMBER
#define JENKINS_BUILD_NUMBER "unknown"
#endif
static const char ver_major[] = LTS_VERSION_MAJOR;
static const char ver_minor[] = LTS_VERSION_MINOR;
static const char ver_patch[] = LTS_VERSION_PATCH;
static const char ver_jenkins[] = JENKINS_BUILD_NUMBER;
namespace LtsAppManager
{
struct LtsAppManagerHandler
{
LtsAppManager ltsAppManager;
};
Q_GLOBAL_STATIC(LtsAppManagerHandler, s_ltsAppManager)
LtsAppManager* LtsAppManager::getInstance()
{
return &s_ltsAppManager->ltsAppManager;
}
LtsAppManager::LtsAppManager() : m_login(nullptr)
{
qRegisterMetaType<LtsAppDescriptor::App>("LtsAppDescriptor::App");
slotStartDebugServer();
connect(qApp, &QCoreApplication::aboutToQuit, this, [this] {
delete m_login;
m_login = nullptr;
});
}
LtsAppManager::~LtsAppManager()
{
delete m_login;
m_login = nullptr;
}
void LtsAppManager::setAvailableApps(const LtsAppDescriptor::AppDescriptionVector& availableApps)
{
m_availableApps = availableApps;
#ifndef LTS_DEBUG
if (LtsSessionData::LtsSessionData::getInstance()->debugFlagValue(
QStringLiteral("PluginManager.CheckAppRequirements")) == QVariant(true))
{
QMessageBox::information(nullptr, QStringLiteral("LtsAppManager"),
QStringLiteral("Checking App Requirements now"));
#else
{
#endif
QStringList errors;
LtsPluginManager::LtsPluginLoader::getInstance()->checkPlugins(availableApps, errors);
if (!errors.isEmpty())
QMessageBox::critical(
nullptr, QStringLiteral("LtsAppManager"),
QStringLiteral("App Requirements check failed!<br> - %1").arg(errors.join(QStringLiteral("<br> - "))));
}
if (m_availableApps.isEmpty())
{
QMessageBox::critical(nullptr, tr("App Manager"),
tr("There are no apps available for this project.\nPlease contact Support."));
abort();
}
}
void LtsAppManager::slotStartDebugServer()
{
QTcpServer* debugServer = new QTcpServer(this);
if (!debugServer->listen(QHostAddress::Any, 20000))
{
debugServer->deleteLater();
const int waitTryAgain = 5;
#ifdef LTS_DEBUG
#endif
QTimer::singleShot(waitTryAgain * 1000, this, &LtsAppManager::slotStartDebugServer);
return;
}
connect(debugServer, &QTcpServer::newConnection, this, [this]() {
QTcpServer* server = qobject_cast<QTcpServer*>(sender());
if (server == nullptr)
return;
QTcpSocket* client = server->nextPendingConnection();
if (client == nullptr)
return;
connect(client, &QTcpSocket::readyRead, this, [this]() {
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
if (client == nullptr)
return;
QString commandStr(
QString::fromUtf8(client->readLine(100)).remove(QStringLiteral("\r")).remove(QStringLiteral("\n")));
QStringList argList = commandStr.split(QLatin1Char(' '), QString::SplitBehavior::SkipEmptyParts);
if (argList.count() < 1)
return;
const QString& command = argList.at(0);
LtsSessionData::LtsSessionData* sessionData = LtsSessionData::LtsSessionData::getInstance();
static QStringList commands;
commands << QStringLiteral("showSessions") << QStringLiteral("operator") << QStringLiteral("help")
<< QStringLiteral("logout") << QStringLiteral("flag") << QStringLiteral("setFlag")
<< QStringLiteral("start") << QStringLiteral("voiceCommand") << QStringLiteral("ftcmock");
switch (commands.indexOf(command))
{
case 0: {
sessionData->setDebugFlagValue(QStringLiteral("DeveloperTools.ShowSessionsOnce"), true);
client->write("K");
break;
}
case 1: {
QString operatorName(sessionData->getOperatorName());
if (operatorName.isEmpty())
operatorName = QStringLiteral("(none)");
QString result(QStringLiteral("%1").arg(operatorName));
client->write(result.toUtf8());
break;
}
case 2: {
QString result(QStringLiteral("Available Commands: %1").arg(commands.join(QStringLiteral(", "))));
client->write(result.toUtf8());
break;
}
case 3: {
client->write("...");
slotLogout();
client->write("\r\nK");
break;
}
case 4: {
if (argList.count() != 2)
{
client->write("Usage: flag <flag name>");
break;
}
const QString& debugFlagName = argList.at(1);
if (!sessionData->hasDebugFlag(debugFlagName))
{
client->write("(unknown)");
break;
}
client->write(sessionData->debugFlagValue(argList.at(1)).toString().toUtf8());
break;
}
case 5: {
if (argList.count() < 3)
{
client->write("Usage: setFlag <flag name> <flag type> <value>\r\nFlag types: int, string (no "
"spaces allowed yet), boolean, double");
break;
}
static QStringList flagTypes;
flagTypes << QStringLiteral("int") << QStringLiteral("string") << QStringLiteral("boolean")
<< QStringLiteral("double");
const QString& flagType = argList.at(2);
bool k = false;
const QString& flagName = argList.at(1);
switch (flagTypes.indexOf(flagType))
{
case 0: {
int value = argList.at(3).toInt(&k);
if (k)
sessionData->setDebugFlagValue(flagName, value);
else
client->write("cannot convert value to integer");
break;
}
case 1: {
sessionData->setDebugFlagValue(flagName, argList.at(3));
break;
}
case 2: {
QString value(argList.at(3).toLower().simplified());
if (value == QStringLiteral("true"))
sessionData->setDebugFlagValue(flagName, true);
else if (value == QStringLiteral("false"))
sessionData->setDebugFlagValue(flagName, false);
else
client->write("cannot convert value to boolean");
break;
}
case 3: {
double value = argList.at(3).toDouble(&k);
if (k)
sessionData->setDebugFlagValue(flagName, value);
else
client->write("cannot convert value to double");
break;
}
default: {
client->write("unknown flag type");
break;
}
}
break;
}
case 6: {
if (argList.count() < 3)
{
client->write("Usage: start <app id> <domain id> ");
break;
}
client->write("not implemented yet");
break;
}
case 7: {
if (argList.count() < 2)
{
client->write("Usage: voiceCommand <keyword> <optional description>");
break;
}
static QStringList keywords;
keywords << QStringLiteral("AddMarker") << QStringLiteral("SetMarker")
<< QStringLiteral("AddSnapshot") << QStringLiteral("SaveSnapshot");
const QString& keyword = argList.at(1);
switch (keywords.indexOf(keyword))
{
case 0: {
auto ev = new LtsWidgets::AddMarkerEvent;
ev->setAccepted(false);
sessionData->setDebugFlagValue(command, keyword);
QCoreApplication::postEvent(qApp, ev);
break;
}
case 1: {
auto ev = new LtsWidgets::SetMarkerEvent(QString());
if (argList.size() > 2)
ev->setDescription(argList.at(2));
ev->setAccepted(false);
sessionData->setDebugFlagValue(command, keyword);
QCoreApplication::postEvent(qApp, ev);
break;
}
case 2: {
auto ev = new LtsWidgets::AddSnapshotEvent;
ev->setAccepted(false);
sessionData->setDebugFlagValue(command, keyword);
QCoreApplication::postEvent(qApp, ev);
break;
}
case 3: {
auto ev = new LtsWidgets::SaveSnapshotEvent(QString());
if (argList.size() > 2)
ev->setDescription(argList.at(2));
ev->setAccepted(false);
sessionData->setDebugFlagValue(command, keyword);
QCoreApplication::postEvent(qApp, ev);
break;
}
default:
break;
}
if (!sessionData->hasDebugFlag(command))
{
client->write("(unknown)");
break;
}
client->write(sessionData->debugFlagValue(argList.at(1)).toString().toUtf8());
break;
}
case 8: {
auto usage = [client]() {
client->write("Usage: ftcmock start <sessionId> <min ms> <max ms> <timer count> - See 'Session "
"id' in DevDialog "
"\nftcmock stop <sessionId>");
};
if (argList.count() < 3)
{
usage();
break;
}
bool k = false;
switch (QStringList({QStringLiteral("start"), QStringLiteral("stop")}).indexOf(argList.at(1)))
{
case 0: {
if (argList.count() < 6)
{
usage();
return;
}
const int min = argList.at(3).toInt(&k);
if (!k || min < 0)
{
client->write("min must be a positive integer!");
return;
}
const int max = argList.at(4).toInt(&k);
if (!k || max < 0)
{
client->write("max must be a positive integer!");
return;
}
const int timers = argList.at(5).toInt(&k);
if (!k || timers < 1)
{
client->write("'timer count' must be a positive integer and greater than 0!");
return;
}
break;
}
case 1: {
break;
}
default: {
usage();
return;
}
}
const int sessionId = argList.at(2).toInt(&k);
if (!k || sessionId < 0)
{
client->write("sessionId must be a positive integer!");
return;
}
emit signalCommand(client, argList);
break;
}
default: {
QString result(QStringLiteral("Unknown command '%1'").arg(command));
client->write(result.toUtf8());
break;
}
}
client->write("\r\n> ");
});
QString versionString = QStringLiteral("%1.%2-%3 (rev: %4)")
.arg(QString::fromLatin1(ver_major), QString::fromLatin1(ver_minor),
QString::fromLatin1(ver_jenkins), QString::fromLatin1(ver_patch));
QString motd(QStringLiteral("\r\nOperatorApplication - Version %1").arg(versionString));
client->write(motd.toUtf8());
client->write("\r\n> ");
});
}
void LtsAppManager::showLogin()
{
QTimer::singleShot(0, this, &LtsAppManager::slotShowLogin);
}
void LtsAppManager::slotShowLogin()
{
if (m_login == nullptr)
{
m_login = new LtsLogin::LtsLogin;
connect(m_login, &LtsLogin::LtsLogin::signalLoginDone, this, [&] {
#ifdef LTS_DEBUG
#endif
if (m_appList.isEmpty())
if (!startAppOrLetUserChoose(m_app, {}))
QTimer::singleShot(100, this, &LtsAppManager::slotLogout);
});
connect(m_login, &LtsLogin::LtsLogin::signalLogoffDone, this, &LtsAppManager::signalLogoffDone);
connect(m_login, &LtsLogin::LtsLogin::signalLogoffDone, this, &LtsAppManager::slotShowLogin,
Qt::QueuedConnection);
connect(m_login, &LtsLogin::LtsLogin::signalLogout, this, &LtsAppManager::slotLogout);
m_login->setLoginPlugin(m_loginPluginIid);
}
m_login->login();
}
bool LtsAppManager::hasRightForApp(const LtsAppDescriptor::AppDescription& appDescription) const
{
const QSet<int>& acls = LtsSessionData::LtsSessionData::getInstance()->getOperatorRights();
for (int reqRight : appDescription.requiredAcls)
{
if (!acls.contains(reqRight))
{
QMessageBox::critical(
nullptr, tr("App Manager"),
tr("The minimal required operator rights are not met. Therefore, the app cannot be started."));
return false;
}
}
return true;
}
void LtsAppManager::taskSwitch(QObject* _caller)
{
LtsSession::LtsSession* caller = qobject_cast<LtsSession::LtsSession*>(_caller);
if (caller == nullptr)
{
Q_ASSERT(false);
return;
}
QVector<LtsSession::LtsSession*> sessions;
for (const LtsPluginManager::LtsPluginManager* app : m_appList)
sessions += app->sessions();
if (sessions.isEmpty())
return;
int sessionCount = sessions.count();
if (sessionCount < 2)
return;
auto sessionIt = std::find_if(sessions.begin(), sessions.end(),
[caller](const LtsSession::LtsSession* session) { return (session == caller); });
if (sessionIt == sessions.end())
{
return;
}
auto it = ++sessionIt;
int x = 0;
do
{
if (x > 100)
{
return;
}
x++;
if (it == sessions.end())
{
if (sessions.begin() == sessionIt)
{
return;
}
it = sessions.begin();
}
LtsSession::LtsSession* session = *it;
QWidget* blw = session->baseLayoutWidget();
if (blw == nullptr || session->isForeverInvisible() || session == caller)
{
continue;
}
caller->baseLayoutWidget()->hide();
blw->showFullScreen();
return;
}
while (++it != sessionIt);
}
void LtsAppManager::hideAllOtherBLWs(QObject* _caller)
{
if (!LtsSessionData::LtsSessionData::getInstance()->isTablet())
return;
LtsSession::LtsSession* caller = qobject_cast<LtsSession::LtsSession*>(_caller);
QVector<LtsSession::LtsSession*> sessions;
for (const LtsPluginManager::LtsPluginManager* app : m_appList)
sessions += app->sessions();
for (LtsSession::LtsSession* session : sessions)
{
QWidget* blw = session->baseLayoutWidget();
if (blw != nullptr && !session->isForeverInvisible() && session != caller)
{
blw->hide();
}
}
if (caller != nullptr)
return;
for (LtsSession::LtsSession* session : sessions)
{
QWidget* blw = session->baseLayoutWidget();
if (blw == nullptr || session->isForeverInvisible())
{
continue;
}
blw->showFullScreen();
return;
}
}
bool LtsAppManager::startAppOrLetUserChoose(LtsAppDescriptor::App appId,
const LtsSession::DdsConnectionParams& connParams, bool force)
{
return startAppOrLetUserChoose(getApp(appId), connParams, force);
}
bool LtsAppManager::startAppOrLetUserChoose(const LtsAppDescriptor::AppDescription& appDescription,
const LtsSession::DdsConnectionParams& connParams, bool force)
{
if (!appDescription.active && !force)
{
AppChooser* appChooser = new AppChooser();
appChooser->setAttribute(Qt::WA_DeleteOnClose);
connect(appChooser, &AppChooser::signalLogout, this, &LtsAppManager::slotLogout);
connect(
appChooser, &AppChooser::signalAppSelected, this,
[this, connParams](LtsAppDescriptor::App appId) {
if (createApp(appId, connParams) == nullptr)
QTimer::singleShot(100, this, &LtsAppManager::slotLogout);
},
Qt::QueuedConnection);
appChooser->show();
return true;
}
if (createApp(appDescription, connParams, {}, false, force) == nullptr)
{
QMessageBox::critical(nullptr, tr("App Manager"), tr("Could not create app.\nPlease contact support."));
return false;
}
return true;
}
LtsPluginManager::LtsPluginManager* LtsAppManager::createApp(LtsAppDescriptor::App appId,
const LtsSession::DdsConnectionParams& connParams,
const QString& workspaceId, bool hidden, bool force)
{
return createApp(getApp(appId), connParams, workspaceId, hidden, force);
}
LtsPluginManager::LtsPluginManager* LtsAppManager::createApp(const LtsAppDescriptor::AppDescription& appDescription,
const LtsSession::DdsConnectionParams& connParams,
const QString& workspaceId, bool hidden, bool force)
{
if (!appDescription.isValid())
{
return nullptr;
}
if (!hasRightForApp(appDescription) && !force)
return nullptr;
const bool bDesiredAppHasSituationMapInstance =
LtsPluginManager::LtsPluginManager::hasSituationMapInstance(appDescription, true);
if (bDesiredAppHasSituationMapInstance)
{
const int curInstances = getNumberOfSituationMapInstances();
if (curInstances >= 3 && !force)
{
if (QMessageBox::Yes !=
QMessageBox::question(nullptr, tr("App Manager"),
tr("Are you sure you want to launch another resource-intensive app? <br />"
"Please note that you are currently running three apps containing the "
"resource-intensive map componment. <br />"
"It may lead to potential performance issues.")))
{
return nullptr;
}
}
}
auto* pluginManager = new LtsPluginManager::LtsPluginManager();
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalQuit, this, &LtsAppManager::slotQuit);
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalSoftQuit, this, &LtsAppManager::slotSoftQuit);
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalLogout, this, &LtsAppManager::slotLogout);
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalInitializationFinished, this,
&LtsAppManager::signalInitializationFinished);
connect(pluginManager, &LtsPluginManager::LtsPluginManager::destroyed, this, &LtsAppManager::slotAppDestroyed);
connect(pluginManager, &LtsPluginManager::LtsPluginManager::hideAllOtherBLWs, this,
&LtsAppManager::hideAllOtherBLWs);
connect(pluginManager, &LtsPluginManager::LtsPluginManager::taskSwitch, this, &LtsAppManager::taskSwitch);
#ifdef LTS_DEBUG
connect(pluginManager, &LtsPluginManager::LtsPluginManager::signalStillAlive, this, [this]() {
auto* app = qobject_cast<LtsPluginManager::LtsPluginManager*>(sender());
if (!app)
return;
for (auto i = m_appList.constBegin(); i != m_appList.constEnd(); ++i)
{
if (*i == app)
return;
}
});
#endif
if (!pluginManager->startApp(appDescription, false, connParams, workspaceId, hidden))
{
QMessageBox::critical(
nullptr, tr("App Manager"),
tr("The Plugin Manager failed to start the app due to plugin errors.\nPlease contact support."));
pluginManager->deleteLater();
return nullptr;
}
m_appList.append(pluginManager);
return pluginManager;
}
bool LtsAppManager::hasApp(LtsAppDescriptor::App appId) const
{
return (std::find_if(m_availableApps.constBegin(), m_availableApps.constEnd(),
[appId](const LtsAppDescriptor::AppDescription& app) {
bool ret = (app.id == appId);
return ret;
}) != m_availableApps.constEnd());
}
int LtsAppManager::getNumberOfSituationMapInstances() const
{
int numberOfSituationMapInstances = 0;
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(m_appList))
{
if (!app)
continue;
if (app->hasSituationMapInstance())
++numberOfSituationMapInstances;
}
return numberOfSituationMapInstances;
}
LtsAppDescriptor::AppDescription LtsAppManager::getApp(LtsAppDescriptor::App appId) const
{
for (const LtsAppDescriptor::AppDescription& app : m_availableApps)
{
if (app.id == appId)
return app;
}
return LtsAppDescriptor::AppDescription();
}
void LtsAppManager::setMainApp(LtsAppDescriptor::App appId)
{
m_app = getApp(appId);
}
void LtsAppManager::saveState()
{
if (LtsSessionData::LtsSessionData::getInstance()->getOperatorId() == 0)
return;
QStringList unsavedWorkspaces =
LtsUtils::OperatorSettings::getInstance()->identifiers(QStringLiteral("UnsavedWorkspace"));
for (auto i = unsavedWorkspaces.constBegin(); i != unsavedWorkspaces.constEnd(); ++i)
LtsUtils::OperatorSettings::getInstance()->removeValue(QStringLiteral("UnsavedWorkspace"), *i);
QStringList unsavedFilterPreset =
LtsUtils::OperatorSettings::getInstance()->identifiers(QStringLiteral("UnsavedFilterPreset"));
for (auto i = unsavedFilterPreset.constBegin(); i != unsavedFilterPreset.constEnd(); ++i)
LtsUtils::OperatorSettings::getInstance()->removeValue(QStringLiteral("UnsavedFilterPreset"), *i);
QJsonArray root;
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(m_appList))
{
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
const auto appId = app->appDescription().id;
if (appId == LtsAppDescriptor::App::Login || sessions.count() < 1)
continue;
QJsonObject appState;
appState[QStringLiteral("id")] = static_cast<int>(appId);
QJsonArray sessionStates;
for (LtsSession::LtsSession* session : sessions)
{
if (session->baseLayout() != nullptr && session->baseLayout()->isSecondaryWidget())
continue;
QJsonObject sessionState;
int screenId = session->screenId();
int screenContainerId = session->screenContainerId();
sessionState[QStringLiteral("screenId")] = screenId;
sessionState[QStringLiteral("screenContainerId")] = screenContainerId;
sessionState[QStringLiteral("exerciseId")] = session->exerciseId();
sessionState[QStringLiteral("partitionId")] = session->partitionId();
sessionState[QStringLiteral("partitionType")] = int(session->partitionType());
sessionState[QStringLiteral("savegame")] = session->getSavegame();
const QString newId(QUuid::createUuid().toString());
sessionState[QStringLiteral("workspaceId")] = newId;
std::shared_ptr<OperatorManagement::ForeignSettingsGuiInterface> ifcOpm;
if (session->getForeignGuiInterface<OperatorManagement::ForeignSettingsGuiInterface>(ifcOpm))
{
ifcOpm->callWorkspaceSaveUnsaved(newId);
}
sessionStates.append(sessionState);
}
if (!sessionStates.isEmpty())
{
appState[QStringLiteral("sessions")] = sessionStates;
root.append(appState);
}
}
QJsonDocument doc(root);
LtsUtils::OperatorSettings::getInstance()->setValue(QStringLiteral("app"), QStringLiteral("LastAppStates"),
doc.toJson(QJsonDocument::Compact));
}
void LtsAppManager::slotLogout()
{
for (LtsPluginManager::LtsPluginManager* app : std::as_const(m_appList))
{
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
for (LtsSession::LtsSession* session : sessions)
{
if (session->notifyUnsavedChanges() == false)
return;
}
}
saveState();
const QVector<LtsPluginManager::LtsPluginManager*> apps = m_appList;
if (apps.isEmpty() && m_login != nullptr)
m_login->logoff();
for (LtsPluginManager::LtsPluginManager* app : apps)
app->deleteLater();
}
void LtsAppManager::slotAppDestroyed()
{
LtsPluginManager::LtsPluginManager* app = static_cast<LtsPluginManager::LtsPluginManager*>(sender());
m_appList.removeOne(app);
if (m_appList.isEmpty() && m_login != nullptr)
{
m_login->logoff();
}
}
void LtsAppManager::slotQuit()
{
QObject* object = sender();
if (!object)
qCritical()
<< "ERROR: LtsAppManager: slot called without object - so it cannot be deleted from the app assignments!";
LtsPluginManager::LtsPluginManager* app = qobject_cast<LtsPluginManager::LtsPluginManager*>(object);
if (app == nullptr)
{
qCritical() << "ERROR: LtsAppManager: quit requested for invalid app";
return;
}
if (m_appList.count() == 1)
{
m_appList.removeAll(app);
saveState();
}
app->deleteLater();
}
void LtsAppManager::slotSoftQuit()
{
QObject* object = sender();
LtsPluginManager::LtsPluginManager* app = qobject_cast<LtsPluginManager::LtsPluginManager*>(object);
if (app == nullptr)
{
qCritical() << "ERROR: LtsAppManager: quit requested for invalid app";
return;
}
app->_softQuit();
if (m_appList.count() == 1)
{
m_appList.removeAll(app);
saveState();
}
}
bool LtsAppManager::otherSessionsResponsibility(LtsSession::LtsSession* thisSession,
const QVector<LtsAppDescriptor::App>& requiredAppTypes,
const QVector<IDL::PartitionType>& requiredPartitionTypes,
const QString& menuGroup, const QString& identifier,
LtsWidgets::LayoutArea area)
{
const QVector<LtsPluginManager::LtsPluginManager*> apps = LtsAppManager::LtsAppManager::getInstance()->getAppList();
QVector<LtsPluginManager::LtsPluginManager*> worthyApps;
for (LtsPluginManager::LtsPluginManager* app : apps)
{
if (!requiredAppTypes.contains(static_cast<LtsAppDescriptor::App>(app->appDescription().id)))
continue;
worthyApps.append(app);
}
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(worthyApps))
{
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
for (const LtsSession::LtsSession* session : sessions)
{
if (session->widgetExists(menuGroup, identifier, area))
return true;
}
}
LtsMultiMonitor::LtsMultiMonitor* mm = LtsMultiMonitor::LtsMultiMonitor::getInstance();
LtsMultiMonitor::LtsScreenBase* mainScreen = mm->mainScreen();
for (const LtsPluginManager::LtsPluginManager* app : std::as_const(worthyApps))
{
const QVector<LtsSession::LtsSession*> sessions = app->sessions();
for (LtsSession::LtsSession* session : sessions)
{
if (session != thisSession && mm->widgetsScreen(session->baseLayoutWidget()) == mainScreen &&
requiredPartitionTypes.contains(session->partitionType()))
return true;
}
}
return false;
}
} // namespace LtsAppManager