Files
qt5-legatus-legacy/Lts/Plugins/PlanOverlays/Gui/plan_overlay_dialog.cpp
T
2026-08-13 18:33:10 +02:00

337 lines
13 KiB
C++
Executable File

/**
**
** @RDE_HEADER@
** plan_overlay_dialog.h
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.7. ArcGIS 100
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 14.07.2017, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "plan_overlay_dialog.h"
#include "plan_overlay_model.h"
#include "plan_overlay_view.h"
#include <LtsSession/lts_session.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <LtsWidgets/lts_drag_icon.h>
#include <LtsWidgets/lts_dialog_button_box.h>
#include <Viewer/LtsFileDialog/lts_file_dialog_widget.h>
#include <QDebug>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QDialog>
#include <QtWidgets/QLabel>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QSplitter>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QHBoxLayout>
namespace PlanOverlaysPlugin
{
//const int PlanFolderID = 30;
struct PlanOverlayDialogWidget::InternalData
{
LtsSession::LtsSession *m_session = nullptr;
LtsWidgets::LtsFileDialogWidget *m_fileDialogWidget = nullptr;
PlanOverlaysPlugin::PlanOverlayModel *m_planOverlayModel = nullptr;
PlanOverlaysPlugin::PlanOverlayView *m_planOverlayView = nullptr;
SituationMap::ForeignGuiInterface *m_situationMapGui = nullptr;
QWidget *m_overlaySection = nullptr;
bool m_isInModalDialog = false;
}; // PlanOverlayDialog::InternalData
PlanOverlayDialogWidget::PlanOverlayDialogWidget(LtsSession::LtsSession *session,
SituationMap::ForeignGuiInterface *situationMapGui,
PlanOverlayModel *planOverlayModel,
QWidget *parent)
: QWidget(parent), m_internal(new InternalData())
{
m_internal->m_session = session;
m_internal->m_situationMapGui = situationMapGui;
m_internal->m_planOverlayModel = planOverlayModel;
const QString &title = tr("Managing Plan Overlays");
setObjectName(QLatin1String("PlanOverlaysPlugin::PlanOverlayDialog"));
QSplitter *splitter = new QSplitter(this);
QWidget *overlays = new QWidget(this);
QWidget *ctrlArea = new QWidget(overlays);
QVBoxLayout *layout = new QVBoxLayout(this);
QLabel *titleWidget = new QLabel(title, this);
m_internal->m_fileDialogWidget = new LtsWidgets::LtsFileDialogWidget(this);
m_internal->m_planOverlayView = new PlanOverlayView(m_internal->m_planOverlayModel, overlays);
m_internal->m_planOverlayModel->setFileDialogMimeType(m_internal->m_fileDialogWidget->dragMimeType());
connect(m_internal->m_planOverlayView, &PlanOverlayView::requestMinScale, this, &PlanOverlayDialogWidget::onRequestMinScaleFromUser);
connect(m_internal->m_planOverlayView, &PlanOverlayView::requestMaxScale, this, &PlanOverlayDialogWidget::onRequestMaxScaleFromUser);
titleWidget->setAlignment(Qt::AlignCenter);
// titleWidget->setStyleSheet(QStringLiteral("font-size: 18pt;"));
QFont boldFont;
boldFont.setBold(true);
boldFont.setPointSize(18);
titleWidget->setFont(boldFont);
layout->addWidget(titleWidget);
#ifdef LTS_DEBUG
if ((session) && (session->exerciseId() > 0))
{
const QString &subtitle = tr("Exercise: %1 / Phase: %2").arg(session->exerciseId()).arg(session->exerciseData()->phId);
QLabel *subtitleWidget = new QLabel(subtitle, this);
subtitleWidget->setAlignment(Qt::AlignCenter);
layout->addWidget(subtitleWidget);
}
#endif
layout->addWidget(splitter, 2);
layout->setMargin(0);
splitter->setOrientation(Qt::Orientation::Vertical); // or is Horizontal better here
splitter->addWidget(m_internal->m_fileDialogWidget);
splitter->addWidget(overlays);
splitter->setStretchFactor(0, 2);
splitter->setStretchFactor(1, 4);
QPixmap icon(QLatin1String("icon:overlay_load_plan.svg")); // better use left and right buttons
LtsWidgets::LtsDragIcon *pbAddOverlay = new LtsWidgets::LtsDragIcon(ctrlArea);
pbAddOverlay->setIcon(QIcon(icon));
pbAddOverlay->setText(QString());
pbAddOverlay->setIconSize(LtsWidgets::ButtonSize::eDefault);
pbAddOverlay->setButtonStyle(LtsWidgets::ButtonStyle::eIconOnly);
pbAddOverlay->setToolTip(tr("Load selected plan file and create new plan overlayer at end of display order"));
connect(pbAddOverlay, &LtsWidgets::LtsDragIcon::clicked, this, &PlanOverlayDialogWidget::onLoadPlan);
#ifdef DISABLE_ADD_OVERLAY
pbAddOverlay->setDisabled(true);
connect(m_internal->m_fileDialogWidget, &LtsWidgets::LtsFileDialogWidget::readyToAccept, pbAddOverlay, [pbAddOverlay]()
{
pbAddOverlay->setDisabled(false);
});
#endif
QVBoxLayout *layoutOverlays = new QVBoxLayout(overlays); // or is QHBoxLayout better here
QHBoxLayout *layoutCtrl = new QHBoxLayout();
layoutOverlays->addSpacing(5);
layoutOverlays->addLayout(layoutCtrl, 0);
layoutOverlays->addSpacing(5);
layoutOverlays->addWidget(m_internal->m_planOverlayView, 2);
layoutCtrl->addStretch(2);
layoutCtrl->addSpacing(20);
layoutCtrl->addWidget(pbAddOverlay);
layoutCtrl->addSpacing(20);
layoutCtrl->addStretch(2);
m_internal->m_overlaySection = overlays;
if (m_internal->m_situationMapGui)
{
auto mapIsReady = [this]() { onEnableOverlaySection(true); };
if (!m_internal->m_situationMapGui->setMapReadyCallback(this, mapIsReady))
qCritical() << " setMapReadyCallback failed";
}
onEnableOverlaySection(true);
// setMinimumHeight(int(QApplication::desktop()->availableGeometry().height()*0.9));
} // PlanOverlayDialogWidget::PlanOverlayDialogWidget( QWidget * parent )
PlanOverlayDialogWidget::~PlanOverlayDialogWidget()
{
delete m_internal;
} // PlanOverlayDialogWidget::~PlanOverlayDialogWidget()
bool PlanOverlayDialogWidget::isInModalDialog() const { return m_internal->m_isInModalDialog; }
void PlanOverlayDialogWidget::setIsInModalDialog(bool on) { m_internal->m_isInModalDialog = on; }
bool PlanOverlayDialogWidget::initFileManagement(const std::shared_ptr<FileManagement::Interface::Dtc> &dtc
, const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc
, const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc
, const std::function<void(int selectedFileId)> &doRead
, const std::function<void(int planId)> &doReload
, const std::function<void(int planId)> &doUnload
, bool isOc)
{
int parentFolderId = 0;
if (isOc)
{
//search for exercise folder instead of global plans
parentFolderId = dtc->getExerciseFolderId(m_internal->m_session->exerciseId());
}
int planFolderId = dtc->findFolder(parentFolderId, QStringLiteral("Tactical Plans"));
connect(m_internal->m_fileDialogWidget, &LtsWidgets::LtsFileDialogWidget::readSelectedFile, m_internal->m_fileDialogWidget, [doRead](int fileId)
{
doRead(fileId);
});
connect(m_internal->m_planOverlayView, &PlanOverlayView::requestUnloadPlan, this, [doUnload](int planId)
{
doUnload(planId);
});
connect(m_internal->m_planOverlayView, &PlanOverlayView::requestReloadPlanById, this, [doReload](int planId)
{
doReload(planId);
});
// TODO: init parameter with desired MainFolders
QVector<FileManagement::MainFolder> mainFolders;
// remove next comment to hide Globald File Structure on OC
if (!isOc)
mainFolders.append(FileManagement::MainFolder::GlobalDocuments);
mainFolders.append(FileManagement::MainFolder::ExerciseDocuments);
mainFolders.append(FileManagement::MainFolder::UserDocuments);
if (!m_internal->m_fileDialogWidget->init(m_internal->m_session, dtc, opmDtc, exmDtc, LtsWidgets::FileDialogMode::modeOpenFile,
mainFolders,{FileManagement::FileType::TacticalPlan}, planFolderId))
return false;
return true;
} // bool PlanOverlayDialogWidget::initFileManagement(...)
void PlanOverlayDialogWidget::onEnableOverlaySection(bool on)
{
m_internal->m_overlaySection->setEnabled(((m_internal->m_situationMapGui) ? m_internal->m_situationMapGui->isMapReady() : true) && on);
} // void PlanOverlayDialogWidget::onEnableOverlaySection(bool on)
void PlanOverlayDialogWidget::onLoadPlan()
{
m_internal->m_fileDialogWidget->requestReadingSelectedFile();
}
void PlanOverlayDialogWidget::onRequestMinScaleFromUser(int planId, const QString &planName)
{
if (isInModalDialog()) return;
QHash<LtsWidgets::Button, QString> btnTxt;
btnTxt[LtsWidgets::Button::Yes] = tr("Set to current");
btnTxt[LtsWidgets::Button::No] = tr("Clear");
btnTxt[LtsWidgets::Button::Cancel] = tr("Cancel");
const LtsWidgets::Button resultBNtn = LtsWidgets::LtsMessageDialog::showMessage(this
, tr("Set current scale of map as minimum scale of plan overlay %1?").arg(planName)
, tr("Redefine maximum scale of plan overlay")
, LtsWidgets::Behaviour::Modal
, LtsWidgets::Button::Yes | LtsWidgets::Button::No | LtsWidgets::Button::Cancel
, btnTxt);
if (resultBNtn == LtsWidgets::Button::Yes)
{
double minScale = m_internal->m_situationMapGui->getCurrentMapScale();
if (minScale > 0.0)
{
const auto maxScale = m_internal->m_situationMapGui->planOverlayMaxScale(planId);
if (minScale < maxScale || qFuzzyIsNull(maxScale))
{
int row = m_internal->m_planOverlayModel->getRowOfId(planId);
m_internal->m_planOverlayModel->setMinScale(row, minScale);
}
else
{
QString msg = tr("The value of %1 is not allowed as minimum scale").arg(minScale);
LtsWidgets::LtsMessageDialog::showMessage(this, msg, tr("Illegal value of minimum scale"));
}
}
}
else if (resultBNtn == LtsWidgets::Button::No)
{
// clear / undefined
int row = m_internal->m_planOverlayModel->getRowOfId(planId);
m_internal->m_planOverlayModel->setMinScale(row, 0); // 0 == undefined
}
emit requestDialogShow();
} // void PlanOverlayDialogWidget::onSetMinScale( int planId )
void PlanOverlayDialogWidget::onRequestMaxScaleFromUser(int planId, const QString &planName)
{
if (isInModalDialog()) return;
QHash<LtsWidgets::Button, QString> btnTxt;
btnTxt[LtsWidgets::Button::Yes] = tr("Set to current");
btnTxt[LtsWidgets::Button::No] = tr("Clear");
btnTxt[LtsWidgets::Button::Cancel] = tr("Cancel");
const LtsWidgets::Button resultBNtn = LtsWidgets::LtsMessageDialog::showMessage(this
, tr("Set current scale of map as maximum scale of plan overlay %1?").arg(planName)
, tr("Redefine maximum scale of plan overlay")
, LtsWidgets::Behaviour::Modal
, LtsWidgets::Button::Yes | LtsWidgets::Button::No | LtsWidgets::Button::Cancel
, btnTxt);
if (resultBNtn == LtsWidgets::Button::Yes)
{
double maxScale = m_internal->m_situationMapGui->getCurrentMapScale();
if (maxScale > 0)
{
if (maxScale > m_internal->m_situationMapGui->planOverlayMinScale(planId))
{
int row = m_internal->m_planOverlayModel->getRowOfId(planId);
m_internal->m_planOverlayModel->setMaxScale(row, maxScale);
}
else
{
QString msg = tr("The value of %1 is not allowed as maximum scale").arg(maxScale);
LtsWidgets::LtsMessageDialog::showMessage(this, msg, tr("Illegal Value of Maximum Scale"));
}
}
}
else if (resultBNtn == LtsWidgets::Button::No)
{
// clear / undefined
int row = m_internal->m_planOverlayModel->getRowOfId(planId);
m_internal->m_planOverlayModel->setMaxScale(row, 0); // 0 == undefined
}
emit requestDialogShow();
}// void PlanOverlayDialogWidget::onSetMaxScale( int planId )
PlanOverlayModel *PlanOverlayDialogWidget::planOverlayModel() const { return m_internal->m_planOverlayModel; }
} // namespace PlanOverlaysPlugin