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

389 lines
13 KiB
C++
Executable File

/**
*@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 <Buildings/bld_operator_rights.h>
#include <InfrastructureManagement/ism_data_plugin_interface.h>
#include <SituationMapPlugin/situation_map_gui_plugin_interface.h>
// Lts
#include <LtsSession/lts_session.h>
#include <LtsWidgets/lts_base_layout_widget.h>
#include <LtsUtilsSettings/settings.h>
//Qt
#include <QShortcut>
namespace Buildings
{
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
} // end of createGuiInterface()
//-----------------------------------------------------------------------------
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, getLogger("BldInfo"))
{} // end of ctor()
//-----------------------------------------------------------------------------
bool InterfaceImpl::fetchInterfaces()
{
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc))
return false;
if (!m_session->getForeignDataInterface<InfrastructureManagement::DataInterface>(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<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> 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<int> bldIdCont;
bldIdCont.reserve(1000);
QVector<int> 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<InfrastructureManagement::StructureElement>& 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<void(const InfrastructureManagement::MainStructureElement &data)> 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<SituationMap::ForeignGuiInterface> sitMapGuiIfc;
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(sitMapGuiIfc);
if (!sitMapGuiIfc)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " error, no sitMapGuiIfc";
return;
}
QVector<SituationMap::ForeignGuiInterface::MapObjectTypeEntityId> 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<int> &bldEntityIds)
{
for (auto id : bldEntityIds)
this->showInfoWindow(id);
}
//-----------------------------------------------------------------------------
void InterfaceImpl::showInfoWindow(int bldEntityId)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " bldEntityId: " << bldEntityId;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc;
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(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<int> &bldEntityIds)
{
for (auto id : bldEntityIds)
this->showBridgeInfoWindow(id);
}
//-----------------------------------------------------------------------------
void InterfaceImpl::showBridgeInfoWindow(int buildingId)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " bldEntityId: " << buildingId;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc;
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(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<InfrastructureManagement::Interface::Dtc> ismDtc;
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(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<int> &hitLineIds)
{
for (auto id : hitLineIds)
this->showHitLineInfoWindow(id);
}
void InterfaceImpl::showHitLineInfoWindow(int hitLineId)
{
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc;
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(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