/** * @RDE_HEADER@ * GUI Plugin for ExerciseManangement * $Id$ * $HeadURL$ * $Author$ * Created by Christian Ehrlicher, SLSE, 2016-02-29 */ #include "exm_edit_gui_plugin.h" #include "exm_dialog.h" #include "exm_edit_dialog.h" #include "exm_exercise_purpose.h" #include "exm_phase_edit.h" #include "exm_state_edit.h" #include "exm_operator_edit.h" #include "ExerciseChooser/exm_chooser.h" #include // for abort #include #include #include #include #include #include #include // SitRepMgr #include #include #include #include #include #include #include namespace ExerciseManagement { std::shared_ptr GuiPlugin::createGuiInterface(LtsSession::LtsSession *session) { return std::make_shared(session); } InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session) : GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Exm.Edit")) , m_dtc(nullptr) , m_asmDtc(nullptr) , m_mainBackground(nullptr) {} QVector InterfaceImpl::getActions() { QVector ret; if(m_session->partitionType() == IDL::PartitionType::Global) { LtsWidgets::PluginData plData; plData.menuGroup = menuGroup(); plData.menuText = tr("Exercises"); plData.menuIcon = QIcon(QLatin1String("icon:set_exercise_process.svg")); plData.identifier = QLatin1String("exmExerciseEdit"); plData.operatorRight = OperatorRights::ExercisesEdit; plData.exercisePart = LtsWidgets::ExercisePart::ePlanning; plData.createWidgetFunc = [this](QWidget *parent) { return onShowExerciseManagementDialog(parent); }; ret.append(plData); } if(m_session->partitionType() == IDL::PartitionType::Exercise) { #if !GUEZ_MODE || LTS_DEBUG // in GUEZ ein Übungstatus soll nur in Übergeordnete Übung geändert werden. LtsWidgets::PluginData plStateEdit; plStateEdit.menuGroup = menuGroup(); plStateEdit.menuText = tr("Exercise State"); plStateEdit.menuIcon = QIcon(QLatin1String("icon:set_exercise_process.svg")); plStateEdit.identifier = QLatin1String("exmStateEdit"); plStateEdit.operatorRight = OperatorRights::ExerciseStateEdit; plStateEdit.exercisePart = LtsWidgets::ExercisePart::eExecution; plStateEdit.createWidgetFunc = [this](QWidget *parent) { return onShowExerciseManagementStateEdit(parent); }; ret.append(plStateEdit); #endif LtsWidgets::PluginData plExercisePurpose; plExercisePurpose.menuGroup = menuGroup(); plExercisePurpose.menuText = tr("Exercise Purpose"); plExercisePurpose.menuIcon = QIcon(QLatin1String("icon:exercise_purpose.svg")); plExercisePurpose.identifier = QLatin1String("exmExercisePurpose"); plExercisePurpose.operatorRight = OperatorRights::ExercisePurposeEdit; plExercisePurpose.exercisePart = LtsWidgets::ExercisePart::ePlanning; plExercisePurpose.createWidgetFunc = [this](QWidget *parent) { return onShowExerciseManagementExercisePurpose(parent); }; ret.append(plExercisePurpose); LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance(); const bool enableEditPhases = ps->value(QStringLiteral("exm"), QStringLiteral("enableEditPhases")).toBool(); if (enableEditPhases) { LtsWidgets::PluginData plPhaseEdit; plPhaseEdit.menuGroup = menuGroup(); plPhaseEdit.menuText = tr("Exercise Phases"); plPhaseEdit.menuIcon = QIcon(QLatin1String("icon:phase_def.svg")); plPhaseEdit.identifier = QLatin1String("exmPhaseEdit"); plPhaseEdit.operatorRight = OperatorRights::ExercisePhaseEdit; plPhaseEdit.exercisePart = LtsWidgets::ExercisePart::ePlanning; plPhaseEdit.createWidgetFunc = [this](QWidget *parent) { return onShowExerciseManagementPhaseEdit(parent); }; ret.append(plPhaseEdit); } LtsWidgets::PluginData plOperatorEdit; plOperatorEdit.menuGroup = menuGroup(); plOperatorEdit.menuText = tr("Exercise Operators"); plOperatorEdit.menuIcon = QIcon(QLatin1String("icon:operator_rights.svg")); plOperatorEdit.identifier = QLatin1String("exmOperatorEdit"); plOperatorEdit.operatorRight = OperatorRights::ExerciseOperatorEdit; plOperatorEdit.createWidgetFunc = [this](QWidget *parent) { return onShowExerciseManagementOperatorEdit(parent); }; ret.append(plOperatorEdit); } return ret; } bool InterfaceImpl::fetchInterfaces() { if (!m_session->getDtc(m_dtc)) return false; std::shared_ptr pdmDtc; if (!m_session->getDtc(pdmDtc)) // TODO: not obli return false; if (!m_session->getDtc(m_asmDtc)) // TODO: not obli return false; for (const QString &option : getOptions()) DEBUG_LOG(m_logger) << "option: " << option; return true; } void InterfaceImpl::clearInterfaces() { m_asmDtc = nullptr; m_dtc = nullptr; } LtsWidgets::LtsDialog *InterfaceImpl::onShowExerciseManagementDialog(QWidget *parent) { ExerciseManagementDialog *dialog = new ExerciseManagementDialog(menuGroup(), parent); dialog->init(m_session); return dialog; } LtsWidgets::LtsDialog *InterfaceImpl::onShowExerciseManagementExercisePurpose(QWidget *parent) { ExerciseManagementExercisePurpose *dialog = new ExerciseManagementExercisePurpose(menuGroup(), parent); dialog->init(m_session); return dialog; } LtsWidgets::LtsDialog *InterfaceImpl::onShowExerciseManagementStateEdit(QWidget *parent) { ExerciseManagementStateEdit *dialog = new ExerciseManagementStateEdit(menuGroup(), parent); dialog->init(m_session); return dialog; } LtsWidgets::LtsDialog *InterfaceImpl::onShowExerciseManagementPhaseEdit(QWidget *parent) { ExerciseManagementPhaseEdit *dialog = new ExerciseManagementPhaseEdit(menuGroup(), parent); dialog->init(m_session); return dialog; } LtsWidgets::LtsDialog *InterfaceImpl::onShowExerciseManagementOperatorEdit(QWidget *parent) { ExerciseManagementOperatorEdit *dialog = new ExerciseManagementOperatorEdit(menuGroup(), parent); dialog->init(m_session); return dialog; } void InterfaceImpl::executePayload(LtsWidgets::LtsBackgroundWidget *mainBackground) { connect(this, &InterfaceImpl::signalSuccess, m_session, &LtsSession::LtsSession::slotExecuteNextPayload, Qt::QueuedConnection); if (m_session->partitionType() != IDL::PartitionType::Global) // skip payload if already in exercise (or replay) { checkNeedRecalcMgrsSquares(m_session->exerciseId()); emit signalSuccess(); // exm payload not needed here return; } m_mainBackground = mainBackground; m_dtc->enableExercise(); connect(new LtsUtils::ConnectingDialogNT([this](int timeWait) { return m_dtc->waitForHistoricalDataExercise(timeWait); }, tr("Exercise Management"), tr("Global"), mainBackground), &QObject::destroyed, this, &InterfaceImpl::executePayloadStep2, Qt::QueuedConnection); // ingores errors } void InterfaceImpl::executePayloadStep2() { int idPreset = LtsSessionData::LtsSessionData::getInstance()->getPartitionIdPreset(); if (m_session->isLoadedFromSavegame() /* otherwise exercise chooser is shown whenever it was an admin session (as it would be partition type Global ;) */) idPreset = 0; // so this is a global session BUT was saved with a savegame, so set idPreset to 0 to not show the exc chooser on a savegame, trust me if (idPreset > -1) // preset is set! skip exc chooser (as the session manager logged it in already) { // no direct call to make sure LtsSessionManager::m_sessionMap is properly filled // to get the same behavior as below (exerciseChooser->show() does not block) QTimer::singleShot(0, this, [this]() { slotSelectExercise(LtsSessionData::LtsSessionData::getInstance()->getPartitionIdPreset()); LtsSessionData::LtsSessionData::getInstance()->removePresets(); }); } else { ExerciseChooser *exerciseChooser = new ExerciseChooser(m_mainBackground); exerciseChooser->init(m_session); exerciseChooser->setAttribute(Qt::WA_DeleteOnClose); connect(exerciseChooser, &ExerciseChooser::signalSelectExercise, this, [this](int partitionId) { slotSelectExercise(partitionId); }, Qt::QueuedConnection); connect(exerciseChooser, &ExerciseChooser::signalQuit, m_session, &LtsSession::LtsSession::signalQuit); // TODO: connect to deleteLater? if (!LtsSessionData::LtsSessionData::getInstance()->isTablet()) exerciseChooser->setModal(true); exerciseChooser->show(); } } void InterfaceImpl::slotSelectExercise(int partitionId) { LtsSession::LtsSessionManager *sessionManager = m_session->getSessionManager(); if (partitionId > 0) // non-admin session { //m_session->setBaseLayoutVisiblity(false); // don't show admin session if an exercise/replay is required LtsSession::DdsConnectionParams connParams(m_session->connParams()); connParams.partitionId = partitionId; connParams.partitionType = IDL::PartitionType::Exercise; connParams.exerciseId = partitionId; sessionManager->createSession(connParams, true, /* show base layout */ true /* payloads were already triggered - but since the script editor payload has to be in an exercise, payloads must be started */); ExerciseManagement::Exercise exc = m_dtc->exercise(partitionId); int excId = exc.id(); if (excId == 0) { qWarning() << "Preset Exercise does not exist or db/svc is down!"; Q_ASSERT(false); return; } if (excId != partitionId) { qWarning() << "exc => preset mismatch"; Q_ASSERT(false); return; } m_asmDtc->enableTrainingArea(); connect(new LtsUtils::ConnectingDialogNT([this](int timeWait) { return m_asmDtc->waitForHistoricalDataTrainingArea(timeWait); }, tr("Asset Management"), tr("Global"), m_mainBackground), &QObject::destroyed, this, [this, exc]() { selectExerciseStep2(exc); }, Qt::QueuedConnection); } else { // user selected Admin Session as his Exercise => as it was already created, make it visible //LtsSession::LtsSession *session = sessionManager->getSession(IDL::PartitionType::Global, 0); if (!m_session) { qWarning() << "No Admin Session available - abort."; // TODO: ERROR_LOG(m_logger) << abort(); } m_session->setBaseLayoutVisible(); // show the Admin Session's BaseLayout emit signalSuccess(); // we are done (exc chosen), tell the session that it can continue executing payloads } } void InterfaceImpl::selectExerciseStep2(const ExerciseManagement::Exercise &exc) { checkNeedRecalcMgrsSquares(exc); m_session->setMarkForDeletion(); // admin session not needed anymore! emit signalSuccess(); // we are done (exc chosen), tell the session that it can continue executing payloads } void InterfaceImpl::checkNeedRecalcMgrsSquares(int exerciseId) { if (!LtsCoordTrans::defaultMgrsSquares().isEmpty()) return; checkNeedRecalcMgrsSquares(m_dtc->exercise(exerciseId)); } void InterfaceImpl::checkNeedRecalcMgrsSquares(const ExerciseManagement::Exercise &exc) { if (!LtsCoordTrans::defaultMgrsSquares().isEmpty()) return; AssetManagement::TrainingArea ta = m_asmDtc->trainingArea(exc.trainingAreaId()); if (ta.id() != exc.trainingAreaId()) { qWarning() << "Could not fetch Training Area with id " << exc.trainingAreaId(); abort(); } LtsCoordTrans::UtmCoordinate bottomLeft = LtsCoordTrans::UtmCoordinate::fromGeographic(ta.bottomLeft().lon(), ta.bottomLeft().lat()); LtsCoordTrans::getMgrsSquares(QRectF(bottomLeft.geographic(0, ta.height()), bottomLeft.geographic(ta.width(), 0)), true, true); } } // namespace ExerciseManagement