/** *@RDE_HEADER@ * Gui Plugin for Building - Info * $Id$ * $HeadURL$ * $Author$ * Created by hjl, SLSE, 2017-04-05 */ #include "bld_info_gui_plugin.h" #include "bld_info_dialog.h" #include "egcu_info_dialog.h" #include "egcu_operational.h" #include "bld_hitline_info_dialog.h" #include "bridge_info_dialog.h" // DDS #include #include #include // Lts #include #include #include //Qt #include namespace Buildings { std::shared_ptr GuiPlugin::createGuiInterface(LtsSession::LtsSession *session) { return std::make_shared(session); } // end of createGuiInterface() //----------------------------------------------------------------------------- InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session) : GuiPluginBase::Interface(session, getLogger("BldInfo")) {} // end of ctor() //----------------------------------------------------------------------------- bool InterfaceImpl::fetchInterfaces() { if (!m_session->getDtc(m_ismDtc)) return false; if (!m_session->getForeignDataInterface(m_ismDataIfc)) return false; return true; } // end of fetchInterfaces() //----------------------------------------------------------------------------- void InterfaceImpl::clearInterfaces() { m_ismDtc = nullptr; m_ismDataIfc = nullptr; } // end of clearInterfaces() //----------------------------------------------------------------------------- QString InterfaceImpl::menuGroup() const { return tr("Building Info"); } QVector InterfaceImpl::getActions() { QVector ret; LtsWidgets::PluginData plData2; plData2.menuGroup = menuGroup(); plData2.createInstant = LtsWidgets::CreateInstantType::CreateInstantAndDiscardAction; plData2.directFunc = [this](const LtsWidgets::PluginData &) { if (m_session->app() == LtsAppDescriptor::App::Situation || m_session->app() == LtsAppDescriptor::App::ResourceManager || m_session->app() == LtsAppDescriptor::App::Snapshot ) { if (!m_scSearchBuilding) { m_scSearchBuilding = new QShortcut(QKeySequence((Qt::ShiftModifier + Qt::Key_F4)), m_session->baseLayout()); m_scSearchBuilding->setContext(Qt::WindowShortcut); connect(m_scSearchBuilding, &QShortcut::activated, this, &InterfaceImpl::showBuildingSearchDialog); } } // if (m_session->app() == LtsAp }; ret.append(plData2); return ret; } void InterfaceImpl::showBuildingSearchDialog() { if (m_buildingShowModalPtr) return; if (appId() != LtsAppDescriptor::App::OC) { m_buildingShowModalPtr = new BuildingSearchModal(m_session->baseLayout()); m_buildingShowModalPtr->setAttribute(Qt::WA_DeleteOnClose); // auto delete on close // #define TEST_LIFETIME #ifdef TEST_LIFETIME // Ein Test fuer wen's interessiert QTimer *t = new QTimer(m_buildingShowModalPtr.data()); connect(t, &QTimer::timeout, this, [this, t]() { ERROR_LOG(m_logger) << "TEST_LIFETIME: " << (qintptr)t << " @ " << (qintptr)m_session->baseLayout() << " still alive"; }); t->start(1000); #endif connect(m_buildingShowModalPtr.data(), &BuildingSearchModal::selectedSearchString, this, &InterfaceImpl::onBuildinSearchStringEntered); m_buildingShowModalPtr->show(); } else { // // LtsAppDescriptor::App::OC: // if (m_buildingShowQWidgetPtr) { m_buildingShowQWidgetPtr->show(); m_buildingShowQWidgetPtr->raise(); m_buildingShowQWidgetPtr->activateWindow(); return; } m_buildingShowQWidgetPtr = new BuildingSearchWidget(m_session->baseLayout()); m_buildingShowQWidgetPtr->setAttribute(Qt::WA_DeleteOnClose); // auto delete on close // #define TEST_LIFETIME #ifdef TEST_LIFETIME // Ein Test fuer wen's interessiert QTimer *t = new QTimer(m_buildingShowQWidgetPtr.data()); connect(t, &QTimer::timeout, this, [this, t]() { ERROR_LOG(m_logger) << "TEST_LIFETIME: " << (qintptr)t << " @ " << (qintptr)m_session->baseLayout() << " still alive"; }); t->start(1000); #endif connect(m_buildingShowQWidgetPtr.data(), &BuildingSearchWidget::selectedSearchString, this, &InterfaceImpl::onBuildinSearchStringEntered); // specific: m_buildingShowQWidgetPtr->setWindowFlags( Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint ); // hints.. QPoint wPos = m_session->baseLayout()->geometry().center(); wPos.setX(wPos.x() - m_buildingShowQWidgetPtr->size().width()); wPos.setY(wPos.y()/2); m_buildingShowQWidgetPtr->move(wPos); m_buildingShowQWidgetPtr->show(); } } void InterfaceImpl::onBuildinSearchStringEntered(const QString &searchString) { TRACE_LOG(m_logger) << " BuildingSearch -> searchString='" << searchString << "'"; QVector bldIdCont; bldIdCont.reserve(1000); QVector bridgeIdCont; bridgeIdCont.reserve(1000); // Following callback takes ~20ms for ~500bldgs // if (displayName.contains(txt, Qt::CaseSensitivity::CaseInsensitive)) // Norbert Thoden ; CTCAP15 // cb to iterate over the items and break loop (return) if one item is found: const auto cb = [this, searchString, &bldIdCont, &bridgeIdCont](const InfrastructureManagement::MainStructureElement & data) -> void { if (data.isDeleted()) return; const std::vector& elements = data.elements(); if (elements.empty()) return; const InfrastructureManagement::StructureElement &firstElement = elements.front(); // per definition, element of type Building is at first position const InfrastructureManagement::StructureElementType_def::type type = firstElement.structureElementTypeId().underlying(); if (type == InfrastructureManagement::StructureElementType_def::Building) { if (!(m_ismDataIfc && m_ismDataIfc->isBuildingsInCurrentExercise(data.id()))) return; } else if (type != InfrastructureManagement::StructureElementType_def::Bridge) // GUEZE-1631: Brücken via Gebäudesuche finden. return; // qCritical() << " searchString='" << searchString << "'" // << ", data.id=" << data.id() // << ", data.type=" << type // << ", mfp.ele.size()=" << m_ismDtc->mainFootprint(data.id()).elements().size(); // Only objects that could be displayed. // So a footprint is required. // Some internal objects (GUEZ: 300 -> 'Outdoor Cameras / Announcement Units') do not have a footprint -> skip if (m_ismDtc->mainFootprint(data.id()).elements().size() < 3) return; const QString &displayName = firstElement.displayName().empty() ? QString::fromStdString(firstElement.name()) : QString::fromStdString(firstElement.displayName()); // qCritical() << " searchString='" << searchString << "'" // << ", data.id=" << data.id() // << ", data.type=" << type // << ", displayName='" << displayName << "'"; if (displayName.contains(searchString, Qt::CaseSensitivity::CaseInsensitive)) { switch (type) { case InfrastructureManagement::StructureElementType_def::Building: bldIdCont.append(data.id()); break; case InfrastructureManagement::StructureElementType_def::Bridge: bridgeIdCont.append(data.id()); break; default: break; } //// return true; // break loop } }; // sonst kann sich der compiler nicht zwischen bool und void entscheiden... !? std::function cb1 = cb; m_ismDtc->mainStructureElements(cb1); DEBUG_LOG(m_logger) << " BuildingSearch (searchString='" << searchString << "') -> " << " bldIdCont=" << bldIdCont.size() << ", bridgeIdCont=" << bridgeIdCont.size(); if (bldIdCont.isEmpty() && bridgeIdCont.isEmpty()) { WARNING_LOG(m_logger) << " BuildingSearch (searchString='" << searchString << "'), " << " no matching buildings/bridges"; return; } // exact one Bldg? if ((bldIdCont.size() == 1) && bridgeIdCont.isEmpty()) { DEBUG_LOG(m_logger) << " BuildingSearch -> bldId='" << bldIdCont.first(); showInfoWindow(bldIdCont.first()); return; } else if ((bridgeIdCont.size() == 1) && bldIdCont.isEmpty()) // // exact one Bridge? { DEBUG_LOG(m_logger) << " BuildingSearch -> bridgeIdCont='" << bridgeIdCont.first(); showBridgeInfoWindow(bridgeIdCont.first()); return; } // mixed results: // mapObjectSelection / Vorauswahlfenster @ SitMap std::shared_ptr sitMapGuiIfc; m_session->getForeignGuiInterface(sitMapGuiIfc); if (!sitMapGuiIfc) { ERROR_LOG(m_logger) << LOGFUNCTION << " error, no sitMapGuiIfc"; return; } QVector mapObjectTypeEntityIdPairs; mapObjectTypeEntityIdPairs += SituationMap::ForeignGuiInterface::MapObjectTypeEntityId(SituationMap::MapObjectType::MOT_Building, bldIdCont); mapObjectTypeEntityIdPairs += SituationMap::ForeignGuiInterface::MapObjectTypeEntityId(SituationMap::MapObjectType::MOT_Bridge, bridgeIdCont); if (!sitMapGuiIfc->openMapObjectSelection(mapObjectTypeEntityIdPairs)) ERROR_LOG(m_logger) << " openMapObjectSelection failed (searchString='" << searchString << "')"; } // wird nur von 'aussen' verwendet void InterfaceImpl::showInfoWindow(const QVector &bldEntityIds) { for (auto id : bldEntityIds) this->showInfoWindow(id); } //----------------------------------------------------------------------------- void InterfaceImpl::showInfoWindow(int bldEntityId) { DEBUG_LOG(m_logger) << LOGFUNCTION << " bldEntityId: " << bldEntityId; std::shared_ptr ismDtc; if (!m_session->getDtc(ismDtc)) { new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), tr("The Infrastructure Management is not available!"), tr("Cannot open Building Info Dialog")); return; } BldInfoDialog *dialog = new BldInfoDialog(bldEntityId, menuGroup()); if (!dialog->init(m_session)) { delete dialog; return; } m_session->addWidget(dialog, menuGroup(), QString::number(bldEntityId), LtsWidgets::LayoutArea::eInfoTab); } // end of showInfoWindow() //----------------------------------------------------------------------------- void InterfaceImpl::showBridgeInfoWindow(const QVector &bldEntityIds) { for (auto id : bldEntityIds) this->showBridgeInfoWindow(id); } //----------------------------------------------------------------------------- void InterfaceImpl::showBridgeInfoWindow(int buildingId) { DEBUG_LOG(m_logger) << LOGFUNCTION << " bldEntityId: " << buildingId; std::shared_ptr ismDtc; if (!m_session->getDtc(ismDtc)) { new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), tr("The Infrastructure Management is not available!"), tr("Cannot open Building Info Dialog")); return; } BridgeInfoDialog *dialog = new BridgeInfoDialog(buildingId, menuGroup()); if (!dialog->init(m_session)) { delete dialog; return; } m_session->addWidget(dialog, menuGroup(), QString::number(buildingId), LtsWidgets::LayoutArea::eInfoTab); } //----------------------------------------------------------------------------- void InterfaceImpl::showEffectGenerationUnitWindow(int mountingPointId) { std::shared_ptr ismDtc; if (!m_session->getDtc(ismDtc)) { new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), tr("The Infrastructure Management is not available!"), tr("Cannot open Effect Generation Unit")); return; } int mpaId; ismDtc->getMountingPointAssetId(mountingPointId, 0, mpaId); if (mpaId == 0) return; auto mpa = ismDtc->mountingPointAsset(mpaId); int assetId = mpa.assetId(); EgcuInfoDialog *dialog = new EgcuInfoDialog(assetId, menuGroup()); DEBUG_LOG(m_logger) << " new EgcuInfoDialog: "; if (!dialog->init(m_session)) { delete dialog; return; } m_session->addWidget(dialog, menuGroup(), dialog->egcuName(), LtsWidgets::LayoutArea::eInfoTab); } void InterfaceImpl::showHitLineInfoWindow(const QVector &hitLineIds) { for (auto id : hitLineIds) this->showHitLineInfoWindow(id); } void InterfaceImpl::showHitLineInfoWindow(int hitLineId) { std::shared_ptr ismDtc; if (!m_session->getDtc(ismDtc)) { new LtsWidgets::LtsMessageDialogNew(m_session->baseLayout(), tr("The Infrastructure Management is not available!"), tr("Cannot open Hit Line Info")); return; } HitLineInfoDialog *hli = new HitLineInfoDialog(hitLineId); if (!hli->init(m_session)) { delete hli; return; } m_session->addWidget(hli, menuGroup(), QStringLiteral("HitLineInfo%1").arg(hitLineId), LtsWidgets::LayoutArea::eInfoTab); } } // namespace Buildings