/** ** ** @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 #include #include #include #include #include #include #include #include #include #include #include #include #include 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 &dtc , const std::shared_ptr &opmDtc , const std::shared_ptr &exmDtc , const std::function &doRead , const std::function &doReload , const std::function &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 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 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 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