Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+63
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2016-08-24
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(Data)
|
||||
ADD_SUBDIRECTORY(Gui)
|
||||
ADD_SUBDIRECTORY(Shared)
|
||||
|
||||
#
|
||||
# Resource Management Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(
|
||||
IsmResGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ism_resource_management_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
GuiPluginInterface
|
||||
Qt5::Core
|
||||
)
|
||||
|
||||
#
|
||||
# Audio Video Config Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(
|
||||
IsmAvcGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ism_audio_video_config_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
GuiPluginInterface
|
||||
Qt5::Core
|
||||
)
|
||||
|
||||
#
|
||||
# Data Plugin Interface
|
||||
#
|
||||
# need top be shared due to signals/slots
|
||||
NGL_ADD_LIBRARY(WS IsmDataPluginInterface SHARED ism_data_plugin_interface.h)
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmDataPluginInterface
|
||||
Qt5::Core
|
||||
svcIsmCommon
|
||||
DataPluginInterface
|
||||
)
|
||||
NGL_INSTALL_TARGET(IsmDataPluginInterface)
|
||||
|
||||
#
|
||||
# Combobox Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(IsmGuiComboboxPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ism_combobox_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
GuiPluginInterface
|
||||
)
|
||||
|
||||
#
|
||||
# Exercise Assignment Classic Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(IsmExerciseAssignmentClassicGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ism_exercise_assignment_classic_gui_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
GuiPluginInterface
|
||||
)
|
||||
@@ -0,0 +1,45 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2016-09-06
|
||||
#
|
||||
|
||||
#
|
||||
# Data Plugin
|
||||
#
|
||||
NGL_ADD_LIBRARY(WS IsmDataPlugin MODULE
|
||||
ism_data_plugin.cpp
|
||||
ism_data_plugin.h
|
||||
ism_foreign_data_plugin.cpp
|
||||
ism_foreign_data_plugin.h
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmDataPlugin
|
||||
IsmDataPluginInterface
|
||||
IsmShared
|
||||
LtsSessionDataDds
|
||||
LtsUtilsCore
|
||||
NGLLogger
|
||||
Qt5::Core
|
||||
Qt5::Concurrent
|
||||
svcIsmClient
|
||||
)
|
||||
NGL_INSTALL_TARGET(IsmDataPlugin)
|
||||
|
||||
NGL_ADD_LIBRARY(WS IsmDataPluginThp STATIC
|
||||
ism_foreign_data_plugin.cpp
|
||||
ism_foreign_data_plugin.h
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmDataPluginThp
|
||||
IsmDataPluginInterface
|
||||
IsmShared
|
||||
LtsUtilsCore
|
||||
NGLLogger
|
||||
Qt5::Core
|
||||
Qt5::Concurrent
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(IsmDataPluginThp
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../..
|
||||
)
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for InfrastructureManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-08-24
|
||||
*/
|
||||
|
||||
#include "ism_data_plugin.h"
|
||||
#include "ism_foreign_data_plugin.h"
|
||||
|
||||
#include <LtsSession/lts_session_data_dds.h>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<DataPluginBase::Interface> DataPlugin::createDataInterface(LtsSession::LtsSessionDataDds *session)
|
||||
{
|
||||
std::shared_ptr<Interface::Dtc> dtc;
|
||||
std::shared_ptr<Interface::Ftc> ftc;
|
||||
// if (!session->createTopicClient(dtc, ftc, true))
|
||||
// return std::shared_ptr<DataPluginBase::Interface>();
|
||||
|
||||
return std::make_shared<DataInterfaceImpl>(session, dtc, ftc);
|
||||
}
|
||||
|
||||
DataInterfaceImpl::DataInterfaceImpl(LtsSession::LtsSessionDataDds *session,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Ftc> &ftc)
|
||||
: DataInterface()
|
||||
, m_dtc(dtc)
|
||||
, m_ftc(ftc)
|
||||
, m_session(session)
|
||||
//, m_foreignInterface(std::make_shared<ForeignInterfaceImpl>(dtc))
|
||||
{}
|
||||
|
||||
std::shared_ptr<ForeignDataInterface> DataInterfaceImpl::getForeignDataInterface()
|
||||
{
|
||||
if (m_foreignInterface)
|
||||
return m_foreignInterface;
|
||||
|
||||
if (!getDtc())
|
||||
return {};
|
||||
|
||||
int exerciseId = -1;
|
||||
if (m_session)
|
||||
exerciseId = m_session->exerciseId();
|
||||
|
||||
m_foreignInterface = std::make_shared<ForeignInterfaceImpl>(m_dtc, exerciseId);
|
||||
return m_foreignInterface;
|
||||
}
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> DataInterfaceImpl::getDtc()
|
||||
{
|
||||
if (m_dtcEnabled)
|
||||
return m_dtc;
|
||||
|
||||
if (!m_session->createTopicClient(m_dtc, false, true))
|
||||
return {};
|
||||
|
||||
m_dtcEnabled = true;
|
||||
return m_dtc;
|
||||
}
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Ftc> DataInterfaceImpl::getFtc()
|
||||
{
|
||||
if (m_ftcEnabled)
|
||||
return m_ftc;
|
||||
|
||||
if (!m_session->createTopicClient(m_ftc, true, true))
|
||||
return {};
|
||||
|
||||
m_ftcEnabled = true;
|
||||
return m_ftc;
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for InfrastructureManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-08-24
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
class DataPlugin final : public QObject, public DataPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "data:3:ism")
|
||||
Q_INTERFACES(DataPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPlugin() = default;
|
||||
~DataPlugin() = default;
|
||||
|
||||
QString pluginName() const override { return QStringLiteral("InfrastructureManagement.Data"); }
|
||||
std::shared_ptr<DataPluginBase::Interface> createDataInterface(LtsSession::LtsSessionDataDds *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Exercise ||
|
||||
partition == IDL::PartitionType::Global ||
|
||||
partition == IDL::PartitionType::Replay;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class DataInterfaceImpl final : public DataInterface
|
||||
{
|
||||
public:
|
||||
DataInterfaceImpl(LtsSession::LtsSessionDataDds *session,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Ftc> &ftc);
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> getDtc() override;// { return m_dtc; }
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Ftc> getFtc() override;// { return m_ftc; }
|
||||
std::shared_ptr<ForeignDataInterface> getForeignDataInterface() override;// { return m_foreignInterface; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ftc;
|
||||
bool m_dtcEnabled { false };
|
||||
bool m_ftcEnabled { false };
|
||||
LtsSession::LtsSessionDataDds *m_session { nullptr };
|
||||
std::shared_ptr<ForeignDataInterface> m_foreignInterface;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
@@ -0,0 +1,446 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for InfrastructureManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-08-24
|
||||
*/
|
||||
|
||||
#include "ism_foreign_data_plugin.h"
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <LtsUtilsCore/json_object.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QSet>
|
||||
|
||||
#include <QtConcurrent>
|
||||
#include <QMutexLocker>
|
||||
|
||||
|
||||
// #ifdef LTS_DEBUG
|
||||
# define BENCHMARK
|
||||
// #endif // LTS_DEBUG
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# define BENCHMARK_SETUP_AND_START() QElapsedTimer elapsedTimer; elapsedTimer.start();
|
||||
# define BENCHMARK_RUN
|
||||
#else
|
||||
# define BENCHMARK_SETUP_AND_START()
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
ForeignInterfaceImpl::ForeignInterfaceImpl(const std::shared_ptr<Interface::Dtc> &dtc, int exerciseId)
|
||||
: m_dtc(dtc)
|
||||
, m_scheduleId(-1)
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_logger(getLogger("ForeignDataInterface"))
|
||||
{
|
||||
// init() ; lazy-initialisation : moved to enableIsmForeignInterface.
|
||||
}
|
||||
|
||||
ForeignInterfaceImpl::~ForeignInterfaceImpl()
|
||||
{
|
||||
}
|
||||
|
||||
void ForeignInterfaceImpl::enableIsmForeignInterface() const
|
||||
{
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
if (!m_mountingPoints.isEmpty())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, ismDataDtc, m_exerciseId = " << m_exerciseId
|
||||
<< " already initialized -> return";
|
||||
return;
|
||||
}
|
||||
|
||||
// cast const away:
|
||||
ForeignInterfaceImpl *NON_CONST_THIS = const_cast<ForeignInterfaceImpl*>(this);
|
||||
NON_CONST_THIS->init();
|
||||
|
||||
#ifdef BENCHMARK_RUN
|
||||
NOTICE_LOG(m_logger) << LOGFUNCTION << " ISM::StructureElementCache / ForeignInterfaceImpl::init took " << elapsedTimer.elapsed() << " [ms]"
|
||||
<< " - m_exerciseId = " << m_exerciseId
|
||||
<< " - m_mountingPoints.size()=" << m_mountingPoints.size()
|
||||
<< ", (m_mountingPointAssetMap.size()=" << m_mountingPointAssetMap.size() << ")";
|
||||
#endif // BENCHMARK_RUN
|
||||
}
|
||||
|
||||
bool ForeignInterfaceImpl::mountingPoints(const std::function<void (const MountingPoint &)> &cb)
|
||||
{
|
||||
BENCHMARK_SETUP_AND_START();
|
||||
|
||||
enableIsmForeignInterface();
|
||||
for (auto it = m_mountingPoints.constBegin(); it != m_mountingPoints.constEnd(); ++it)
|
||||
cb(it.value());
|
||||
|
||||
#ifdef BENCHMARK_RUN
|
||||
NOTICE_LOG(m_logger) << LOGFUNCTION
|
||||
<< " - m_exerciseId = " << m_exerciseId
|
||||
<< " - m_mountingPoints.size()=" << m_mountingPoints.size()
|
||||
<< " took " << elapsedTimer.elapsed() << " [ms]";
|
||||
#else
|
||||
NOTICE_LOG(m_logger) << LOGFUNCTION
|
||||
<< " - m_exerciseId = " << m_exerciseId
|
||||
<< " - m_mountingPoints.size()=" << m_mountingPoints.size();
|
||||
#endif // BENCHMARK_RUN
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ForeignInterfaceImpl::mountingPoints(const std::function<bool (const MountingPoint &)> &cb)
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
for (auto it = m_mountingPoints.constBegin(); it != m_mountingPoints.constEnd(); ++it)
|
||||
if (cb(it.value()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QHash<int32_t, MountingPoint> ForeignInterfaceImpl::mountingPoints() const
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
return m_mountingPoints;
|
||||
}
|
||||
|
||||
MountingPoint ForeignInterfaceImpl::mountingPoint(int32_t mountingPointId) const
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
return m_mountingPoints.value(mountingPointId);
|
||||
}
|
||||
|
||||
MainSchedule ForeignInterfaceImpl::mainSchedule(int32_t scheduleId)
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
return m_dtc->mainSchedule(scheduleId);
|
||||
}
|
||||
|
||||
void ForeignInterfaceImpl::setScheduleId(int32_t scheduleId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "setScheduleId to: " << scheduleId
|
||||
<< " (was " << m_scheduleId << ")";
|
||||
|
||||
enableIsmForeignInterface();
|
||||
|
||||
m_scheduleId = scheduleId;
|
||||
onMainScheduleChanged(m_dtc->mainSchedule(scheduleId), DataModification::eModified);
|
||||
emit scheduleIdChanged(m_scheduleId);
|
||||
}
|
||||
|
||||
int32_t ForeignInterfaceImpl::scheduleId() const
|
||||
{
|
||||
return m_scheduleId;
|
||||
}
|
||||
|
||||
QSet<int> ForeignInterfaceImpl::buildingsInCurrentExercise()
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
return m_bldgsInExcersise;
|
||||
}
|
||||
|
||||
const QSet<int>& ForeignInterfaceImpl::buildingsInCurrentExercise() const
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
return m_bldgsInExcersise;
|
||||
|
||||
}
|
||||
|
||||
bool ForeignInterfaceImpl::isBuildingsInCurrentExercise(int buildingId) const
|
||||
{
|
||||
enableIsmForeignInterface();
|
||||
return m_bldgsInExcersise.contains(buildingId);
|
||||
}
|
||||
|
||||
void ForeignInterfaceImpl::onMainStructureElementChanged(const MainStructureElement &data, DataModification modType)
|
||||
{
|
||||
const int mseId = data.id();
|
||||
|
||||
switch (modType)
|
||||
{
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
const auto &structureElements = data.elements();
|
||||
for (const StructureElement ¤tStructEle : structureElements)
|
||||
{
|
||||
if (currentStructEle.structureElementTypeId() != StructureElementType::MountingPoint)
|
||||
continue;
|
||||
m_mountingPoints.remove(currentStructEle.id());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
QVector<int> exeIds;
|
||||
|
||||
// read only once properties - available_in_exercise from MSE, only if exerciseId is relevant
|
||||
if (m_exerciseId > 0)
|
||||
{
|
||||
QJsonParseError parserError;
|
||||
const QByteArray &content = QByteArray::fromStdString(data.properties());
|
||||
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
|
||||
if (parserError.error != QJsonParseError::NoError)
|
||||
WARNING_LOG(m_logger) << "Invalid properties for MSE " << data.id() << ", " << data.name();
|
||||
else
|
||||
{
|
||||
const QJsonArray exercises(QJsonObject(doc.object()).value(QStringLiteral("available_in_exercise")).toArray());
|
||||
exeIds.reserve(exercises.size());
|
||||
for (const auto &exercise : exercises)
|
||||
exeIds += exercise.toInt();
|
||||
}
|
||||
}
|
||||
|
||||
// update m_bldgsInExcersise
|
||||
{
|
||||
bool realChange = false;
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (exeIds.contains(m_exerciseId) ||
|
||||
(m_exerciseId == 0) // global -> processAll
|
||||
)
|
||||
{
|
||||
if (!m_bldgsInExcersise.contains(mseId))
|
||||
{
|
||||
m_bldgsInExcersise.insert(mseId);
|
||||
realChange = true;
|
||||
}
|
||||
} else {
|
||||
if (m_bldgsInExcersise.contains(mseId))
|
||||
{
|
||||
m_bldgsInExcersise.remove(mseId);
|
||||
realChange = true;
|
||||
}
|
||||
}
|
||||
} // scope for mutex
|
||||
|
||||
// Maybe an MSE/building is added/removed?
|
||||
if (realChange)
|
||||
{
|
||||
// ensure map object will be created
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " m_bldgsInExcersise updated."
|
||||
<< " (mseId=" << mseId << " name=" << data.name();
|
||||
emit buildingsInCurrentExerciseChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// N. Thoden, 11.01.2022:
|
||||
// reduce amount of data by filtering m_exerciseId / available_in_exercise
|
||||
// (may otherwise took up to ~10 seconds!!)
|
||||
// m_exerciseId <= 0 -> process all
|
||||
if (m_exerciseId == 0 || (m_exerciseId > 0 && exeIds.contains(m_exerciseId)))
|
||||
{
|
||||
const auto &structureElements = data.elements();
|
||||
for (const StructureElement ¤tStructEle : structureElements)
|
||||
{
|
||||
if (currentStructEle.structureElementTypeId() != StructureElementType::MountingPoint)
|
||||
continue;
|
||||
|
||||
StructureElement seFloor;
|
||||
const std::vector<int32_t> &curPath = currentStructEle.path();
|
||||
if (curPath.size() == 4)
|
||||
{
|
||||
// GUEZE-3258: Performance-Untersuchung der OpApp : getStructureElementById is expensive
|
||||
// 500 bldgs, ~25000 structure element -> init() can took 2500ms (CTCAP28)
|
||||
if (!m_dtc->getStructureElementById(curPath[1], seFloor)) // getStructureElementById is expensive if many buildings/structure elements
|
||||
WARNING_LOG(m_logger) << " getStructureElementById failed for " << curPath[1];
|
||||
|
||||
}
|
||||
|
||||
const int floorId = QString::fromStdString(seFloor.name()).split(QStringLiteral("_")).value(1, QStringLiteral("-10")).toInt();
|
||||
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
// GUEZE-3258: Performance-Untersuchung der OpApp
|
||||
const auto it = m_mountingPoints.find(currentStructEle.id());
|
||||
if (it != m_mountingPoints.end())
|
||||
{
|
||||
MountingPoint &mountingPointRef = *it;
|
||||
|
||||
if (mountingPointRef.data() == currentStructEle)
|
||||
continue;
|
||||
|
||||
mountingPointRef.updateData(currentStructEle, floorId);
|
||||
emit mountingPointChanged(mountingPointRef, DataModification::eModified);
|
||||
} else {
|
||||
DEBUG_LOG(m_logger) << "New Mounting point with id " << currentStructEle.id()
|
||||
<< " and type " << currentStructEle.mountingPointTypeId()
|
||||
<< " (type " << currentStructEle.mountingPointTypeId().underlying() << ")"
|
||||
<< " subid: " << currentStructEle.mountingPointId() << this;
|
||||
|
||||
MountingPoint newMountingPoint(currentStructEle, floorId);
|
||||
const int assetId = m_mountingPointAssetMap.value(newMountingPoint.id(), -1);
|
||||
newMountingPoint.setAssociatedAssetId(assetId);
|
||||
// newMountingPoint->setHasAssociatedAssetDefect(); // TODO
|
||||
|
||||
m_mountingPoints.insert(newMountingPoint.id(), newMountingPoint);
|
||||
emit mountingPointChanged(newMountingPoint, DataModification::eAdded);
|
||||
} // if (it != m_mountingPoints.end())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
|
||||
void ForeignInterfaceImpl::onMountingPointAssetChanged(const MountingPointAsset &data, DataModification modType)
|
||||
{
|
||||
const int32_t structureElementId = data.structureElementId();
|
||||
|
||||
DEBUG_LOG(m_logger) << "onMountingPointAssetChanged se id: " << structureElementId << ", assetId: " << data.assetId();
|
||||
|
||||
// [GUEZE-3494] Ressourcenverwaltung ist fehlerhaft laut Kunden
|
||||
|
||||
// QHash:
|
||||
// value() -> return const T
|
||||
// operator[] -> return T &
|
||||
// // MountingPoint mp = m_mountingPoints.value(structureElementId);
|
||||
|
||||
MountingPoint &mpRef = m_mountingPoints[structureElementId]; // default constructed value may okay
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
m_mountingPointAssetMap.remove(structureElementId);
|
||||
if (mpRef.id() > 0)
|
||||
{
|
||||
mpRef.setAssociatedAssetId(-1);
|
||||
mpRef.setHasAssociatedAssetDefect(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mountingPointAssetMap.insert(structureElementId, data.assetId());
|
||||
if (mpRef.id() > 0)
|
||||
{
|
||||
mpRef.setAssociatedAssetId(data.assetId());
|
||||
mpRef.setHasAssociatedAssetDefect(m_dtc->instrumentationAsset(data.assetId()).assetStateId() == InstrumentationAssetState::Defect);
|
||||
}
|
||||
}
|
||||
|
||||
if (mpRef.id() > 0)
|
||||
emit mountingPointChanged(mpRef, DataModification::eModified);
|
||||
}
|
||||
|
||||
void ForeignInterfaceImpl::onMainScheduleChanged(const MainSchedule &data, DataModification modType)
|
||||
{
|
||||
if (m_scheduleId != data.id())
|
||||
return;
|
||||
|
||||
Q_UNUSED(modType);
|
||||
|
||||
QHash<int, MountingPointPlan> mppMap;
|
||||
for (const auto &elem : data.elements())
|
||||
mppMap[elem.structureElementId()] = elem;
|
||||
|
||||
|
||||
for (MountingPoint &mp : m_mountingPoints)
|
||||
{
|
||||
const MountingPointPlan &mpp = mppMap[mp.id()];
|
||||
const MountingPointState &mps = mpp.mountingPointState();
|
||||
|
||||
// If there is no MPP for this Schedule
|
||||
if(mpp.structureElementId() != mp.id())
|
||||
{
|
||||
// Do nothing if idle
|
||||
if (mp.aimState() == MountingPointState_def::Idle)
|
||||
continue;
|
||||
mp.setAimState(MountingPointState::Idle);
|
||||
emit mountingPointChanged(mp, DataModification::eModified);
|
||||
continue;
|
||||
}
|
||||
// If AimState did not change, continue
|
||||
if (mp.aimState() == mps)
|
||||
continue;
|
||||
|
||||
mp.setAimState(mps);
|
||||
emit mountingPointChanged(mp, DataModification::eModified);
|
||||
}
|
||||
}
|
||||
|
||||
void ForeignInterfaceImpl::init()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, ismDataDtc, m_exerciseId = " << m_exerciseId
|
||||
<< " - m_mountingPoints.size()=" << m_mountingPoints.size()
|
||||
<< ", (m_mountingPointAssetMap.size()=" << m_mountingPointAssetMap.size() << ")";
|
||||
|
||||
m_dtc->waitForHistoricalDataMainStructureElement(1000); // enable is implicit
|
||||
m_dtc->waitForHistoricalDataMainSchedule(1000); // enable is implicit
|
||||
m_dtc->waitForHistoricalDataMountingPointAsset(1000); // enable is implicit
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainStructureElementChanged,
|
||||
this, &ForeignInterfaceImpl::onMainStructureElementChanged, Qt::UniqueConnection);
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainScheduleChanged,
|
||||
this, &ForeignInterfaceImpl::onMainScheduleChanged, Qt::UniqueConnection);
|
||||
connect(m_dtc.get(), &Interface::Dtc::mountingPointAssetChanged,
|
||||
this, &ForeignInterfaceImpl::onMountingPointAssetChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
|
||||
// // #define PROCESS_MSE_SEQUENTIELL
|
||||
#ifdef PROCESS_MSE_SEQUENTIELL
|
||||
m_dtc->mainStructureElements([this](const MainStructureElement &data)
|
||||
{
|
||||
onMainStructureElementChanged(data, DataModification::eAdded);
|
||||
});
|
||||
#else
|
||||
|
||||
// 25.10.2022, Norbert Thoden:
|
||||
// ForeignInterfaceImpl::init() benoetigt ca. 5sec at CTCAP15
|
||||
// Durch Parallelisierung reduziert es sich auf knapp 2sec. :-)
|
||||
// via std::bind:
|
||||
// using namespace std::placeholders;
|
||||
// std::function<void(const MainStructureElement &data)> functor =
|
||||
// std::bind(&ForeignInterfaceImpl::onMseChangedForInitializing, this, _1);
|
||||
// QtConcurrent::blockingMap(mseMap, functor);
|
||||
|
||||
// Es geht aber auch einfacher per lambda :-)
|
||||
const QMap<qint32, InfrastructureManagement::MainStructureElement> &mseMap =
|
||||
m_dtc->mainStructureElements();
|
||||
|
||||
m_mountingPoints.reserve(mseMap.size());
|
||||
|
||||
// blockingMap -> functor will be applied to every item:
|
||||
QtConcurrent::blockingMap(mseMap, [this](const MainStructureElement &data) {
|
||||
onMainStructureElementChanged(data, DataModification::eAdded);
|
||||
});
|
||||
#endif // PROCESS_MSE_SEQUENTIELL
|
||||
|
||||
m_dtc->mountingPointAssets([this](const MountingPointAsset &data)
|
||||
{
|
||||
onMountingPointAssetChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
m_dtc->mainSchedules([this](const MainSchedule &data)
|
||||
{
|
||||
onMainScheduleChanged(data, DataModification::eAdded);
|
||||
});
|
||||
|
||||
int firstBldg = -1;
|
||||
if (!m_bldgsInExcersise.isEmpty())
|
||||
firstBldg = *m_bldgsInExcersise.begin();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", exerciseId = " << m_exerciseId << ", bldgs in excersise = " << m_bldgsInExcersise.size()
|
||||
<< ", firstBldg: " << firstBldg;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << "XXXXX" << m_bldgsInExcersise.size();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, ismDataDtc, m_exerciseId = " << m_exerciseId
|
||||
<< " - m_mountingPoints.size()=" << m_mountingPoints.size()
|
||||
<< ", (m_mountingPointAssetMap.size()=" << m_mountingPointAssetMap.size() << ")";
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for InfrastructureManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Mike Wille, SLSE, 2016-08-24
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include <QMutex>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
class ForeignInterfaceImpl final : public ForeignDataInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ForeignInterfaceImpl(const std::shared_ptr<Interface::Dtc> &dtc, int exerciseId = -1);
|
||||
~ForeignInterfaceImpl();
|
||||
|
||||
// lazy-initialisation: // is called at beginning of every access method
|
||||
void enableIsmForeignInterface() const;
|
||||
|
||||
|
||||
// mainStructureElements (buildings)
|
||||
//@{
|
||||
bool mountingPoints(const std::function<void (const MountingPoint &)> &cb) override final;
|
||||
bool mountingPoints(const std::function<bool(const MountingPoint &data)> &cb) override final;
|
||||
QHash<int32_t, MountingPoint> mountingPoints() const override final;
|
||||
MountingPoint mountingPoint(int32_t mountingPointId) const override final;
|
||||
//@}
|
||||
|
||||
// mainSchedule
|
||||
//@{
|
||||
MainSchedule mainSchedule(int32_t scheduleId) override final;
|
||||
void setScheduleId(int32_t scheduleId) override final;
|
||||
int32_t scheduleId() const override final;
|
||||
//@}
|
||||
|
||||
|
||||
// buildings in current exercise
|
||||
//@{
|
||||
QSet<int> buildingsInCurrentExercise() override final;
|
||||
const QSet<int>& buildingsInCurrentExercise() const override final;
|
||||
bool isBuildingsInCurrentExercise(int buildingId) const override final;
|
||||
//@}
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &data, DataModification modType);
|
||||
void onMountingPointAssetChanged(const InfrastructureManagement::MountingPointAsset &data, DataModification modType);
|
||||
void onMainScheduleChanged(const InfrastructureManagement::MainSchedule &data, DataModification modType);
|
||||
|
||||
private: // methods
|
||||
void init();
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
QMutex m_mutex;
|
||||
QHash<int32_t, MountingPoint> m_mountingPoints; // By SeId
|
||||
QHash<int32_t, int32_t> m_mountingPointAssetMap; // key: structureElementId/mountingPointId - value: assetId
|
||||
QSet<int> m_bldgsInExcersise; // All Buildings avaiable in this Exercise
|
||||
|
||||
int32_t m_scheduleId;
|
||||
int32_t m_exerciseId{-1};
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
# Refreshed by Mike Wille, SLTE, 2022-09-26
|
||||
#
|
||||
|
||||
SET(src
|
||||
ism_audio_video_config_gui_plugin.cpp
|
||||
ism_audio_video_config_gui_plugin.h
|
||||
SetRecording/ism_set_recording_dialog.cpp
|
||||
SetRecording/ism_set_recording_dialog_model.cpp
|
||||
SetRecording/ism_set_recording_dialog_requester.cpp
|
||||
SetRecording/ism_set_recording_checkstate_proxy_model.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(src
|
||||
SetRecording/ism_set_recording_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS IsmAvcGuiPlugin MODULE ${src})
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmAvcGuiPlugin
|
||||
NGLLogger
|
||||
nglwidgets
|
||||
LtsPrinting
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsWidgets
|
||||
LtsDataView
|
||||
IsmShared
|
||||
IsmAvcGuiPluginInterface
|
||||
ExmDataPluginInterface # TODO: rm
|
||||
IsmDataPluginInterface
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(IsmAvcGuiPlugin)
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Steve Kemayou, SLTE, 2023-01-25
|
||||
*/
|
||||
|
||||
#include "ism_set_recording_checkstate_proxy_model.h"
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
Qt::ItemFlags SetRecordingCheckStateProxyModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return sourceModel()->flags(index); // delegate to source model for further processing if necessary
|
||||
|
||||
// Sets only the checkbox nodes on user checkable,
|
||||
// checkbox leaves must be handled in source model.
|
||||
QModelIndex sourceIndex = mapToSource(index);
|
||||
Qt::ItemFlags fl = sourceModel()->flags(sourceIndex);
|
||||
if (index.column() == 0)
|
||||
return fl | Qt::ItemIsUserCheckable;
|
||||
return fl;
|
||||
}
|
||||
|
||||
QVariant SetRecordingCheckStateProxyModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
QModelIndex sourceIndex = mapToSource(index);
|
||||
|
||||
// delegate everything except CheckStateRole to source model
|
||||
if (role != Qt::CheckStateRole)
|
||||
return sourceModel()->data(sourceIndex, role);
|
||||
|
||||
// delegate a leaf too with CheckStateRole to source model
|
||||
if (isLeaf(index))
|
||||
{
|
||||
return sourceModel()->data(sourceIndex, role);
|
||||
}
|
||||
|
||||
// delegate to source model for further processing of further columns if necessary
|
||||
if (index.column() != 0)
|
||||
return sourceModel()->data(sourceIndex, role);
|
||||
|
||||
int checkedCount = 0;
|
||||
int childCount = rowCount(index);
|
||||
for (int childRow = 0; childRow < childCount; ++childRow)
|
||||
{
|
||||
const QModelIndex childIndex(this->index(childRow, 0, index));
|
||||
const QVariant value(data(childIndex, Qt::CheckStateRole));
|
||||
if (value.isValid() && value.canConvert<Qt::CheckState>())
|
||||
{
|
||||
Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
|
||||
|
||||
if (state == Qt::PartiallyChecked)
|
||||
return Qt::PartiallyChecked;
|
||||
if (state == Qt::Checked)
|
||||
++checkedCount;
|
||||
}
|
||||
}
|
||||
if (checkedCount == childCount)
|
||||
return Qt::Checked;
|
||||
else if (checkedCount == 0)
|
||||
return Qt::Unchecked;
|
||||
else
|
||||
return Qt::PartiallyChecked;
|
||||
}
|
||||
|
||||
bool SetRecordingCheckStateProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
const QModelIndex sourceIndex(mapToSource(index));
|
||||
// delegate to source model for further processing of further columns if necessary
|
||||
if (index.column() != 0)
|
||||
return sourceModel()->setData(sourceIndex, value, role);
|
||||
|
||||
// delegate everything except CheckStateRole to source mode
|
||||
if (role != Qt::CheckStateRole)
|
||||
return sourceModel()->setData(sourceIndex, value, role);
|
||||
|
||||
if (isLeaf(index))
|
||||
{
|
||||
// delegate a leaf to source model
|
||||
sourceModel()->setData(sourceIndex, value, role);
|
||||
}
|
||||
else
|
||||
{
|
||||
// update underlying children recursively (Additional nodes with leaves may also exist)
|
||||
const int childCount = rowCount(index);
|
||||
for (int childRow = 0; childRow < childCount; ++childRow)
|
||||
{
|
||||
const QModelIndex childIndex(this->index(childRow, 0, index));
|
||||
setData(childIndex, value, (Qt::CheckStateRole));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetRecordingCheckStateProxyModel::isLeaf(const QModelIndex &index) const
|
||||
{
|
||||
QModelIndex sourceIndex = mapToSource(index);
|
||||
return sourceModel()->flags(sourceIndex).testFlag(Qt::ItemIsUserCheckable);
|
||||
}
|
||||
|
||||
}// namespace InfrastructureManagement
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
#ifndef SETRECORDINGCHECKSTATEPROXYMODEL_H
|
||||
#define SETRECORDINGCHECKSTATEPROXYMODEL_H
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class SetRecordingCheckStateProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
public:
|
||||
using QIdentityProxyModel::QIdentityProxyModel;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
private:
|
||||
bool isLeaf(const QModelIndex &index) const;
|
||||
|
||||
};
|
||||
|
||||
}// namespace InfrastructureManagement
|
||||
|
||||
|
||||
#endif // SETRECORDINGCHECKSTATEPROXYMODEL_H
|
||||
Executable
+230
@@ -0,0 +1,230 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The SetReportingDialog lists all known videostreams and offers the option wether to set them to be recorded or not
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-07-03
|
||||
*/
|
||||
|
||||
#include "ism_set_recording_dialog.h"
|
||||
#include "ui_ism_set_recording_dialog.h"
|
||||
#include "ism_set_recording_dialog_model.h"
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
#include <LtsWidgets/lts_overlay_loading.h>
|
||||
#include "ism_set_recording_dialog_requester.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QTreeView>
|
||||
#include <QTimer>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
/**
|
||||
* Helper function to find a given MountingPoint within a MainStructureElement (by id).
|
||||
*/
|
||||
static inline InfrastructureManagement::StructureElement findMountingPoint(const InfrastructureManagement::MainStructureElement &building,
|
||||
const InfrastructureManagement::SimpleRecordingData &guiMountingPoint)
|
||||
{
|
||||
Q_ASSERT(guiMountingPoint.mainStructureElementId == building.id());
|
||||
for (const auto ¤tStructureElement : building.elements())
|
||||
{
|
||||
if (currentStructureElement.id() == guiMountingPoint.id)
|
||||
return currentStructureElement;
|
||||
}
|
||||
|
||||
Q_ASSERT(false);
|
||||
return InfrastructureManagement::StructureElement();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
SetRecordingDialog::SetRecordingDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ui(new Ui::SetRecordingDialog)
|
||||
, m_ismDtc(nullptr)
|
||||
, m_ismFtc(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_model(nullptr)
|
||||
, m_checkStateProxyModel(nullptr)
|
||||
, m_timerUpdate(nullptr)
|
||||
, m_logger(getLogger("SetRecordingDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Exercise_Assignment"));
|
||||
|
||||
}
|
||||
|
||||
SetRecordingDialog::~SetRecordingDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void SetRecordingDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Set Recording"));
|
||||
}
|
||||
|
||||
|
||||
bool SetRecordingDialog::init(const std::shared_ptr<Interface::Dtc> &ismDtc, const std::shared_ptr<Interface::Ftc> &ismFtc, const std::shared_ptr<ForeignDataInterface> &dataInterface)
|
||||
{
|
||||
m_ismDtc = ismDtc;
|
||||
m_ismFtc = ismFtc;
|
||||
|
||||
if (!(m_ismDtc->enableMainStructureElement() &&
|
||||
m_ismFtc->enableMainStructureElementModify()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable ISM topics";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_timerUpdate = new QTimer(this);
|
||||
m_timerUpdate->setSingleShot(true);
|
||||
|
||||
|
||||
delete m_model;
|
||||
m_model = new SetRecordingDialogModel(this);
|
||||
|
||||
if (!m_model->initModel(m_ismDtc, dataInterface))
|
||||
{
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
return false;
|
||||
}
|
||||
|
||||
delete m_checkStateProxyModel;
|
||||
m_checkStateProxyModel = new SetRecordingCheckStateProxyModel(this);
|
||||
m_checkStateProxyModel->setSourceModel(m_model);
|
||||
m_ui->treeView->setModel(m_checkStateProxyModel);
|
||||
|
||||
|
||||
connect(m_timerUpdate, &QTimer::timeout, this, [&]()
|
||||
{
|
||||
if (m_ui->treeView->proxyModel() != nullptr)
|
||||
{
|
||||
m_ui->treeView->proxyModel()->invalidate(); // update treeview
|
||||
}
|
||||
});
|
||||
|
||||
m_ui->treeView->treeView()->expandToDepth(0);
|
||||
|
||||
connect(m_model, &SetRecordingDialogModel::dataChanged, this, &SetRecordingDialog::onDataChanged);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetRecordingDialog::onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void SetRecordingDialog::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
{
|
||||
Q_UNUSED(topLeft);
|
||||
Q_UNUSED(bottomRight);
|
||||
Q_UNUSED(roles);
|
||||
m_timerUpdate->start(100);
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
bool SetRecordingDialog::apply()
|
||||
{
|
||||
|
||||
// XXX: HACK we don't know if user pressed ok or apply - apply() has to emidiately return, but the operation is async... so mimic ok/apply later, based on what was clicked
|
||||
bool wasOkay = (sender() == static_cast<QObject *>(m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)));
|
||||
QVector<SimpleRecordingData> vec;
|
||||
QMap<int32_t, std::vector<StructureElement> > modifiedElements; // By Building ID (Elements in Building)
|
||||
QMap<int32_t, MainStructureElement> affectedMainStructureElements; // By Building ID (Building itself)
|
||||
|
||||
m_model->getChangedCams(vec);
|
||||
LtsWidgets::LtsOverlayLoading *lol = new LtsWidgets::LtsOverlayLoading;
|
||||
setOverlay(lol);
|
||||
|
||||
SEModifyRequestCollector *collector = new SEModifyRequestCollector(m_ismFtc, this);
|
||||
|
||||
{
|
||||
QPushButton *pbCancel = new QPushButton;
|
||||
pbCancel->setText(tr("Cancel"));
|
||||
connect(pbCancel, &QPushButton::clicked,
|
||||
this, [pbCancel, collector, lol]()
|
||||
{
|
||||
collector->cancel();
|
||||
lol->setText(tr("Canceling ..."));
|
||||
pbCancel->setEnabled(false);
|
||||
});
|
||||
|
||||
qobject_cast<QVBoxLayout *>(lol->layout())->addWidget(pbCancel, 0, Qt::AlignmentFlag::AlignCenter);
|
||||
}
|
||||
for (const SimpleRecordingData &affectedMountingPoint : qAsConst(vec))
|
||||
{
|
||||
const int buildingId = affectedMountingPoint.mainStructureElementId;
|
||||
MainStructureElement mse = m_ismDtc->mainStructureElement(buildingId);
|
||||
|
||||
const MainStructureElement &building = mse;
|
||||
StructureElement modifiedMountingPoint = findMountingPoint(building, affectedMountingPoint);
|
||||
|
||||
QJsonDocument propsDoc = QJsonDocument::fromJson(QByteArray::fromStdString(modifiedMountingPoint.properties()));
|
||||
QJsonObject propsObj;
|
||||
if (propsDoc.isObject()) // if the given properties are no valid JSON object, the properties will be made from scratch
|
||||
propsObj = propsDoc.object();
|
||||
|
||||
propsObj.insert(QLatin1String("record"), affectedMountingPoint.shallHaveRecordingOn);
|
||||
// add to list of elements to modify
|
||||
modifiedMountingPoint.properties(QJsonDocument(propsObj).toJson(QJsonDocument::Compact).toStdString());
|
||||
modifiedElements[buildingId].push_back(modifiedMountingPoint); // clazy:exclude=reserve-candidates
|
||||
}
|
||||
|
||||
for(auto it = modifiedElements.cbegin(); it != modifiedElements.cend(); ++it)
|
||||
{
|
||||
StructureElementModifyRequest request(it.key(), it.value());
|
||||
collector->addRequest(it.key(), request);
|
||||
}
|
||||
|
||||
int initialCount = collector->count();
|
||||
const QString leText(QStringLiteral("%1<br />%3 / %2").arg(tr("set Camera(s) recording...")).arg(initialCount));
|
||||
lol->setText(leText.arg(0));
|
||||
|
||||
connect(collector, &SEModifyRequestCollector::requestComplete,
|
||||
this, [collector, lol, leText, initialCount]()
|
||||
{
|
||||
lol->setText(leText.arg(initialCount - collector->count()));
|
||||
});
|
||||
|
||||
connect(collector, &SEModifyRequestCollector::finished,
|
||||
this, [this, collector, wasOkay, lol](bool canceled)
|
||||
{
|
||||
unsetOverlay();
|
||||
lol->deleteLater();
|
||||
collector->deleteLater();
|
||||
|
||||
int failedCount = collector->failedCount();
|
||||
if (failedCount > 0)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Error: Couldn't set %1 camera(s) recording!").arg(failedCount));
|
||||
return;
|
||||
}
|
||||
|
||||
if (canceled)
|
||||
return;
|
||||
|
||||
__unchange__(); // 'apply' behaviour
|
||||
|
||||
if (!wasOkay) // 'ok' behaviour
|
||||
return;
|
||||
|
||||
closeRequest(); // we 'unchanged', so it will close directly
|
||||
});
|
||||
|
||||
collector->go();
|
||||
return false; // our request is async, say false, show a blocking dialog and do ok-/apply-button stuff later
|
||||
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The SetReportingDialog lists all known videostreams and offers the option wether to set them to be recorded or not
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-07-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include "ism_set_recording_checkstate_proxy_model.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SetRecordingDialog;
|
||||
}
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class SetRecordingDialogModel;
|
||||
class SetRecordingCheckStateProxyModel;
|
||||
class SetRecordingDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::StructureElementModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SetRecordingDialog(QWidget *parent = nullptr);
|
||||
~SetRecordingDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &ismDtc, const std::shared_ptr<Interface::Ftc> &ismFtc, const std::shared_ptr<ForeignDataInterface> &dataInterface);
|
||||
|
||||
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
bool apply() override final;
|
||||
|
||||
private: // attributes
|
||||
Ui::SetRecordingDialog *m_ui;
|
||||
std::shared_ptr<Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ismFtc;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
SetRecordingDialogModel *m_model;
|
||||
SetRecordingCheckStateProxyModel *m_checkStateProxyModel;
|
||||
QTimer *m_timerUpdate;
|
||||
bool update = false;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class SetRecordingDialog
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SetRecordingDialog</class>
|
||||
<widget class="QWidget" name="SetRecordingDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>751</width>
|
||||
<height>457</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="LtsDataView::LtsDataView" name="treeView" native="true">
|
||||
<property name="rootIsDecorated" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+338
@@ -0,0 +1,338 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The SetRecordingDialogModel provices data for SetRecordingDialog
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-07-04
|
||||
*/
|
||||
|
||||
#include "ism_set_recording_dialog_model.h"
|
||||
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QCheckBox>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
SetRecordingDialogModel::SetRecordingDialogModel(QObject *parent)
|
||||
: NGLTreeModel(parent, new NGLTreeItem(QVariant()), { tr("Name") })
|
||||
, m_dtc(nullptr)
|
||||
, m_logger(getLogger("InfrastructureManagement"))
|
||||
{
|
||||
}
|
||||
|
||||
QVariant SetRecordingDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!(index.isValid() && (role == Qt::DisplayRole || role == Qt::UserRole || role == (Qt::UserRole + 1) || role == Qt::CheckStateRole)))
|
||||
return QVariant();
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
//no switch() necessary because we have only one column here
|
||||
if (item->data().canConvert<SimpleRecordingData>())
|
||||
return item->data().value<SimpleRecordingData>().name;
|
||||
if (item->data().canConvert<QString>())
|
||||
return item->data().toString();
|
||||
return QVariant();
|
||||
}
|
||||
else if (role == Qt::CheckStateRole)
|
||||
{
|
||||
if (item->data().canConvert<SimpleRecordingData>())
|
||||
return item->data().value<SimpleRecordingData>().shallHaveRecordingOn ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
else if (role == Qt::UserRole && item->data().canConvert<SimpleRecordingData>())
|
||||
return item->data().value<SimpleRecordingData>().id;
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool SetRecordingDialogModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<ForeignDataInterface> &dataInterface)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
|
||||
if (!(m_dtc->enableMainStructureElement() &&
|
||||
m_dtc->enableMountingPointAsset()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Datatopics";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dataInterface = dataInterface;
|
||||
|
||||
connect(m_dataInterface.get(), &ForeignDataInterface::mountingPointChanged,
|
||||
this, &SetRecordingDialogModel::onMountingPointChanged);
|
||||
|
||||
INFO_LOG(m_logger) << "initModel successfull";
|
||||
|
||||
initData();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetRecordingDialogModel::initData()
|
||||
{
|
||||
NGLTreeModel::resetModel();
|
||||
|
||||
QMap<int32_t, StructureElement> allStructureElements;
|
||||
QMap<qint32, InfrastructureManagement::MainStructureElement> mainStructEles = m_dtc->mainStructureElements();
|
||||
QMap<qint32, qint32> mapMse2groupId;
|
||||
for (auto it = mainStructEles.constBegin(); it != mainStructEles.constEnd(); ++it)
|
||||
{
|
||||
mapMse2groupId.insert(it.value().id(), it.value().groupId());
|
||||
for (const StructureElement ¤tElement : it.value().elements())
|
||||
{
|
||||
allStructureElements.insert(currentElement.id(), currentElement);
|
||||
}
|
||||
}
|
||||
|
||||
QMap<int32_t, NGLTreeItem *> structEleIdToItem;
|
||||
|
||||
// create all ngl treeitems
|
||||
for (auto it = allStructureElements.constBegin(); it != allStructureElements.constEnd(); ++it)
|
||||
{
|
||||
NGLTreeItem *item = nullptr;
|
||||
|
||||
if (it.value().structureElementTypeId() == StructureElementType::MountingPoint)
|
||||
{
|
||||
if (it.value().mountingPointTypeId() != MountingPointType::IndoorCamera &&
|
||||
it.value().mountingPointTypeId() != MountingPointType::OutdoorCamera)
|
||||
continue;
|
||||
|
||||
item = new NGLTreeItem(QVariant::fromValue(toSimpleRecordingData(it.value())));
|
||||
}
|
||||
else
|
||||
item = new NGLTreeItem(QString::fromStdString(it.value().displayName()));
|
||||
|
||||
|
||||
structEleIdToItem.insert(it.key(), item);
|
||||
}
|
||||
|
||||
const QList<int> sections = m_dtc->getSections();
|
||||
QMap<int, NGLTreeItem*> mapGroup;
|
||||
//adding default group
|
||||
const int defaultSectionId = static_cast<int>(InfrastructureManagement::BuildingGroup_def::UnknownGroup);
|
||||
NGLTreeItem *defaultSectionRoot = new NGLTreeItem(InfrastructureManagement::toString(static_cast<InfrastructureManagement::BuildingGroup_def::type>(defaultSectionId)));
|
||||
mapGroup.insert(defaultSectionId, defaultSectionRoot);
|
||||
m_rootItem->appendChild(mapGroup.value(defaultSectionId));
|
||||
|
||||
// append to root availables sections by groupId
|
||||
for(auto const &groupId : sections)
|
||||
{
|
||||
if(mapGroup.contains(groupId))
|
||||
continue;
|
||||
const QString sectionText = InfrastructureManagement::toString(static_cast<InfrastructureManagement::BuildingGroup_def::type>(groupId));
|
||||
DEBUG_LOG(m_logger)<<" >> Adding section >> "<<sectionText;
|
||||
NGLTreeItem *sectionRoot = new NGLTreeItem(sectionText);
|
||||
mapGroup.insert(groupId, sectionRoot);
|
||||
m_rootItem->appendChild(mapGroup.value(groupId));
|
||||
}
|
||||
|
||||
for (auto it = structEleIdToItem.begin(); it != structEleIdToItem.end(); ++it)
|
||||
{
|
||||
StructureElement structureElement = allStructureElements.value(it.key());
|
||||
int32_t pathSize = structureElement.path().size();
|
||||
|
||||
NGLTreeItem *parent = mapGroup.value(defaultSectionId); // default section parent index
|
||||
if (pathSize > 1)
|
||||
{
|
||||
parent = structEleIdToItem.value(structureElement.path().at(pathSize - 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
const int sectionId = mapMse2groupId.value(structureElement.mainStructureElementId(), -1);
|
||||
if(sectionId != -1)
|
||||
{
|
||||
parent = mapGroup.value(sectionId);
|
||||
}
|
||||
}
|
||||
parent->appendChild(it.value());
|
||||
}
|
||||
|
||||
for(auto sectionRoot : mapGroup.values())
|
||||
{
|
||||
clearFromEmptyStructures(sectionRoot);
|
||||
}
|
||||
// remove empty sections
|
||||
for (int i = m_rootItem->childCount() - 1; i >= 0; --i)
|
||||
{
|
||||
NGLTreeItem *currentChild = m_rootItem->child(i);
|
||||
if (currentChild->childCount() == 0)
|
||||
{
|
||||
const QModelIndex parentIdx = indexFromItem(m_rootItem);
|
||||
beginRemoveRows(parentIdx, i, i);
|
||||
m_rootItem->removeChild(currentChild);
|
||||
endRemoveRows();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags SetRecordingDialogModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags fl = NGLTreeModel::flags(index);
|
||||
if (!index.isValid())
|
||||
return fl;
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
bool isLeaf = item->data().canConvert<SimpleRecordingData>();
|
||||
if (isLeaf && index.column() == 0)
|
||||
return fl | Qt::ItemIsUserCheckable;
|
||||
return fl;
|
||||
}
|
||||
|
||||
bool SetRecordingDialogModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (role != Qt::CheckStateRole || index.column() != NAME || !index.isValid())
|
||||
return NGLTreeModel::setData(index, value, role);
|
||||
|
||||
if (!value.canConvert<bool>())
|
||||
return false;
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
if (item->data().canConvert<SimpleRecordingData>())
|
||||
{
|
||||
// Blatt
|
||||
SimpleRecordingData srd = item->data().value<SimpleRecordingData>();
|
||||
if (srd.shallHaveRecordingOn == value.toBool())
|
||||
return true;
|
||||
srd.shallHaveRecordingOn = value.toBool();
|
||||
item->setData(QVariant::fromValue(srd));
|
||||
|
||||
emit dataChanged(index, index, {role});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SetRecordingDialogModel::onMountingPointChanged(const MountingPoint &mountingPoint, DataModification modType)
|
||||
{
|
||||
if (modType != DataModification::eModified || !hasCorrectType(mountingPoint))
|
||||
return;
|
||||
|
||||
QModelIndexList indices = match(index(0, 0), Qt::UserRole, QVariant::fromValue(mountingPoint.id()), 1, Qt::MatchRecursive);
|
||||
|
||||
if (indices.isEmpty())
|
||||
return;
|
||||
|
||||
QModelIndex index = indices.first();
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
if (!(item && item->data().canConvert<SimpleRecordingData>()))
|
||||
return;
|
||||
|
||||
item->setData(QVariant::fromValue(toSimpleRecordingData(mountingPoint)));
|
||||
|
||||
emit dataChanged(index, index, QVector<int>() << Qt::DisplayRole);
|
||||
}
|
||||
|
||||
SimpleRecordingData SetRecordingDialogModel::toSimpleRecordingData(const MountingPoint &mountingPoint)
|
||||
{
|
||||
SimpleRecordingData result;
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(mountingPoint.properties(), &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
result.hasRecordingOn = false;
|
||||
else
|
||||
result.hasRecordingOn = doc.object().value(QLatin1String("record")).toBool();
|
||||
|
||||
result.mainStructureElementId = mountingPoint.buildingId();
|
||||
result.name = mountingPoint.name();
|
||||
result.id = mountingPoint.id();
|
||||
result.shallHaveRecordingOn = result.hasRecordingOn;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SimpleRecordingData SetRecordingDialogModel::toSimpleRecordingData(const StructureElement &mountingPoint)
|
||||
{
|
||||
SimpleRecordingData result;
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(mountingPoint.properties()), &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
result.hasRecordingOn = false;
|
||||
else
|
||||
result.hasRecordingOn = doc.object().value(QLatin1String("record")).toBool();
|
||||
|
||||
result.mainStructureElementId = mountingPoint.mainStructureElementId();
|
||||
|
||||
if (mountingPoint.displayName().size())
|
||||
result.name = QString::fromStdString(mountingPoint.displayName());
|
||||
else if (mountingPoint.name().size())
|
||||
result.name = QString::fromStdString(mountingPoint.name());
|
||||
else
|
||||
result.name = QStringLiteral("MP_%1").arg(mountingPoint.id());
|
||||
|
||||
result.id = mountingPoint.id();
|
||||
result.shallHaveRecordingOn = result.hasRecordingOn;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SetRecordingDialogModel::hasCorrectType(const MountingPoint &mountingPoint)
|
||||
{
|
||||
return mountingPoint.type() == MountingPointType::IndoorCamera ||
|
||||
mountingPoint.type() == MountingPointType::OutdoorCamera;
|
||||
}
|
||||
|
||||
void SetRecordingDialogModel::clearFromEmptyStructures(NGLTreeItem *treeItem)
|
||||
{
|
||||
if (!treeItem)
|
||||
return;
|
||||
for (int i = treeItem->childCount() - 1; i >= 0; --i)
|
||||
{
|
||||
NGLTreeItem *currentChild = treeItem->child(i);
|
||||
if (!hasCam(currentChild))
|
||||
{
|
||||
const QModelIndex parentIdx = indexFromItem(treeItem);
|
||||
beginRemoveRows(parentIdx, i, i);
|
||||
treeItem->removeChild(currentChild);
|
||||
endRemoveRows();
|
||||
}
|
||||
else
|
||||
clearFromEmptyStructures(currentChild);
|
||||
}
|
||||
}
|
||||
|
||||
bool SetRecordingDialogModel::hasCam(const NGLTreeItem *treeItem)
|
||||
{
|
||||
if (treeItem->data().canConvert<SimpleRecordingData>())
|
||||
return true;
|
||||
|
||||
const auto children = treeItem->children();
|
||||
for (NGLTreeItem *currentChild : children)
|
||||
if (hasCam(currentChild))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetRecordingDialogModel::getChangedCams(QVector<SimpleRecordingData> &set, NGLTreeItem *treeItem) const
|
||||
{
|
||||
if (treeItem == nullptr)
|
||||
treeItem = m_rootItem;
|
||||
|
||||
const auto children = treeItem->children();
|
||||
for (NGLTreeItem *child : children)
|
||||
{
|
||||
if (!child->data().canConvert<SimpleRecordingData>())
|
||||
{
|
||||
getChangedCams(set, child);
|
||||
continue;
|
||||
}
|
||||
SimpleRecordingData srd = child->data().value<SimpleRecordingData>();
|
||||
if (srd.hasRecordingOn == srd.shallHaveRecordingOn)
|
||||
continue;
|
||||
set << srd;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The SetRecordingDialogModel provices data for SetRecordingDialog
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-07-04
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <QModelIndex>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
struct SimpleRecordingData
|
||||
{
|
||||
QString name;
|
||||
int32_t id = 0;
|
||||
int32_t mainStructureElementId = 0;
|
||||
bool hasRecordingOn = false;
|
||||
bool shallHaveRecordingOn = false;
|
||||
};
|
||||
|
||||
class SetRecordingDialogModel
|
||||
: public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
NAME
|
||||
};
|
||||
explicit SetRecordingDialogModel(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Handles the representation of data.
|
||||
* In case of CheckStateRole only leafs will be handled.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
* @param[in] role role to which the data relates
|
||||
*
|
||||
*/
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override final;
|
||||
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<ForeignDataInterface> &dataInterface);
|
||||
void initData();
|
||||
|
||||
/**
|
||||
* Sets only the leafs of the tree view to Qt::ItemIsUserCheckable.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
*
|
||||
*/
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override final;
|
||||
|
||||
/**
|
||||
* Sets the check state data according to their check box in the internal model.
|
||||
* CheckState data can be set for leafs only.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
* @param[in] value value to be set
|
||||
* @param[in] role role to which the data relates (here especially Qt::CheckStateRole)
|
||||
*
|
||||
*/
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
|
||||
void getChangedCams(QVector<SimpleRecordingData> &set, NGLTreeItem *treeItem = nullptr) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void onMountingPointChanged(const MountingPoint &mountingPoint, DataModification modType);
|
||||
|
||||
private: // methods
|
||||
static SimpleRecordingData toSimpleRecordingData(const MountingPoint &mountingPoint);
|
||||
static SimpleRecordingData toSimpleRecordingData(const StructureElement &mountingPoint);
|
||||
static bool hasCorrectType(const MountingPoint &mountingPoint);
|
||||
void clearFromEmptyStructures(NGLTreeItem *treeItem);
|
||||
static bool hasCam(const NGLTreeItem *treeItem);
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_dataInterface;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class SetRecordingDialogModel
|
||||
} // namespace InfrastructureManagement
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::SimpleRecordingData)
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author: kemayou_s$
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#include "ism_set_recording_dialog_requester.h"
|
||||
#include <QGuiApplication>
|
||||
#include <QMimeData>
|
||||
#include <QTimer>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
/// SEModifyRequestCollector
|
||||
SEModifyRequestCollector::SEModifyRequestCollector(std::shared_ptr<Interface::Ftc> &ftc, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_ftc(ftc)
|
||||
{}
|
||||
|
||||
void SEModifyRequestCollector::addRequest(const int &buildingId, const StructureElementModifyRequest &request)
|
||||
{
|
||||
m_requests += QPair<int, InfrastructureManagement::StructureElementModifyRequest>(buildingId, request);
|
||||
}
|
||||
|
||||
void SEModifyRequestCollector::cancel()
|
||||
{
|
||||
m_canceled = true;
|
||||
}
|
||||
|
||||
void SEModifyRequestCollector::go()
|
||||
{
|
||||
next();
|
||||
}
|
||||
|
||||
int SEModifyRequestCollector::count() const
|
||||
{
|
||||
return m_requests.count();
|
||||
}
|
||||
|
||||
int SEModifyRequestCollector::failedCount() const
|
||||
{
|
||||
return m_failedCount;
|
||||
}
|
||||
|
||||
void SEModifyRequestCollector::next()
|
||||
{
|
||||
if (m_requests.isEmpty())
|
||||
{
|
||||
emit finished(m_canceled);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
SEModifyRequester *requester = new SEModifyRequester;
|
||||
|
||||
const QPair<int, StructureElementModifyRequest> request(m_requests.takeFirst());
|
||||
const int ri = request.first;
|
||||
|
||||
|
||||
connect(requester, &SEModifyRequester::finished,
|
||||
this, [this, ri](const QString &msg)
|
||||
{
|
||||
bool failed = (!msg.isEmpty());
|
||||
|
||||
if (failed)
|
||||
{
|
||||
m_failedCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ri.model->unchange(ri.rowId);
|
||||
}
|
||||
|
||||
emit requestComplete(failed);
|
||||
|
||||
if (m_canceled)
|
||||
m_requests.clear();
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
auto go = [this, request, requester]()
|
||||
{
|
||||
m_ftc->structureElementModifyRequest(request.second, requester);
|
||||
};
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
if (QGuiApplication::keyboardModifiers().testFlag(Qt::KeyboardModifier::ControlModifier))
|
||||
{
|
||||
QTimer::singleShot(3000, this, go);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
go();
|
||||
}
|
||||
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
#ifndef SEMODIFYREQUESTER_H
|
||||
#define SEMODIFYREQUESTER_H
|
||||
|
||||
#include "ism_set_recording_dialog_model.h"
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QPair>
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
/// SEModifyRequester
|
||||
class SEModifyRequester : public QObject,
|
||||
public Interface::Ftc::StructureElementModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SEModifyRequester(): QObject() {} // do NOT parent!
|
||||
|
||||
void onStructureElementModifyReply(const Core::FunctionReplyObject &reply) override
|
||||
{
|
||||
if (reply.error())
|
||||
emit finished(reply.translated());
|
||||
else
|
||||
emit finished({});
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished(const QString &msg);
|
||||
|
||||
};
|
||||
|
||||
/// SEModifyRequestCollector
|
||||
class SEModifyRequestCollector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SEModifyRequestCollector(std::shared_ptr<Interface::Ftc> &ftc, QObject *parent);
|
||||
|
||||
void addRequest(const int &buildingId, const InfrastructureManagement::StructureElementModifyRequest &request);
|
||||
void cancel();
|
||||
void go();
|
||||
int count() const;
|
||||
int failedCount() const;
|
||||
|
||||
private slots:
|
||||
void next();
|
||||
|
||||
signals:
|
||||
void finished(bool canceled);
|
||||
void requestComplete(bool failed);
|
||||
|
||||
private:
|
||||
QVector<QPair<int, InfrastructureManagement::StructureElementModifyRequest> > m_requests;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
bool m_canceled = false;
|
||||
int m_failedCount = 0;
|
||||
};
|
||||
}// namespace InfrastructureManagement
|
||||
|
||||
#endif // SEMODIFYREQUESTER_H
|
||||
Executable
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for AudioVideoConfig
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#include "ism_audio_video_config_gui_plugin.h"
|
||||
#include "SetRecording/ism_set_recording_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsWidgets/lts_background_widget.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("AudioVideoConfigPlugin"))
|
||||
{}
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
LtsWidgets::PluginData plugin;
|
||||
plugin.menuGroup = tr("Exercise Assignment");
|
||||
plugin.layoutArea = LtsWidgets::LayoutArea::eDialogTab;
|
||||
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableSetRecordingDialog = ps->value(QStringLiteral("ism"),
|
||||
QStringLiteral("enableSetRecordingDialog")).toBool();
|
||||
|
||||
if (enableSetRecordingDialog)
|
||||
{
|
||||
// Set Recording Dialog
|
||||
plugin.menuText = tr("Set Recording");
|
||||
plugin.identifier = QLatin1String("IsmAvcSetRecordingDialog");
|
||||
plugin.menuIcon = QIcon(QLatin1String("icon:media-record.svg"));
|
||||
plugin.createWidgetFunc = [this](QWidget * parent) -> LtsWidgets::LtsDialog *
|
||||
{
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Ftc> ismFtc;
|
||||
std::shared_ptr<ForeignDataInterface> ismDataIfc;
|
||||
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(ismDtc)
|
||||
|| !m_session->getFtc<InfrastructureManagement::DataInterface>(ismFtc)
|
||||
|| !m_session->getForeignDataInterface<DataInterface>(ismDataIfc))
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(m_session->baseLayoutWidget(), tr("The Infrastructure Management is not available!"), tr("Cannot open Set Recording"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return LtsWidgets::initDialog(new SetRecordingDialog(parent),
|
||||
ismDtc, ismFtc, ismDataIfc);
|
||||
};
|
||||
ret.append(plugin);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for AudioVideoConfig
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_audio_video_config_gui_plugin_interface.h>
|
||||
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:ism.avc")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return ForeignAudioVideoConfigGuiInterface::pluginName(); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final
|
||||
: public QObject
|
||||
, public ForeignAudioVideoConfigGuiInterface
|
||||
, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QString menuGroup() const override { return tr("Training Voice Communication"); }
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
signals:
|
||||
void signalSuccess();
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2016-10-28
|
||||
#
|
||||
|
||||
add_subdirectory(ResourceManagement)
|
||||
add_subdirectory(AudioVideoConfig)
|
||||
add_subdirectory(IsmComboBox)
|
||||
add_subdirectory(ExerciseAssignmentClassic)
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# $Id: CMakeLists.txt 49595 2020-01-24 13:28:42Z hjl $
|
||||
# $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/CMakeLists.txt $
|
||||
# $Author: hjl $
|
||||
#
|
||||
# Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
#
|
||||
|
||||
SET(src
|
||||
ism_exercise_assignment_classic_gui_plugin.cpp
|
||||
|
||||
#ism_exercise_assignment_dialog.h
|
||||
ism_exercise_assignment_dialog.cpp
|
||||
#ism_exercise_assignment_dialog_model.h
|
||||
ism_exercise_assignment_dialog_model.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(src
|
||||
ism_exercise_assignment_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS IsmExerciseAssignmentClassicGuiPlugin MODULE ${src})
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmExerciseAssignmentClassicGuiPlugin
|
||||
NGLLogger
|
||||
nglwidgets
|
||||
LtsPrinting
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsWidgets
|
||||
LtsDataView
|
||||
IsmDataPluginInterface
|
||||
IsmShared
|
||||
IsmExerciseAssignmentClassicGuiPluginInterface
|
||||
ExmDataPluginInterface
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(IsmExerciseAssignmentClassicGuiPlugin)
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for AudioVideoConfig
|
||||
* $Id: ism_audio_video_config_gui_plugin.cpp 52254 2020-10-06 11:50:47Z wille_m $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ism_audio_video_config_gui_plugin.cpp $
|
||||
* $Author: wille_m $
|
||||
*
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_classic_gui_plugin.h"
|
||||
#include "ism_exercise_assignment_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsWidgets/lts_background_widget.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("AudioVideoConfigPlugin"))
|
||||
// , m_ismDtc(nullptr)
|
||||
// , m_ismFtc(nullptr)
|
||||
, m_exmDtc(nullptr)
|
||||
// , m_ismDataInterface(nullptr)
|
||||
{}
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
LtsWidgets::PluginData plugin;
|
||||
|
||||
plugin.menuGroup = tr("Exercise Assignment");
|
||||
plugin.layoutArea = LtsWidgets::LayoutArea::eDialogTab;
|
||||
plugin.menuText = tr("Exercise Assignment");
|
||||
plugin.identifier = QLatin1String("IsmAvcExerciseAssignmentDialog_CLASSIC");
|
||||
plugin.menuIcon = QIcon(QLatin1String("icon:set_exercise_process.svg"));
|
||||
plugin.createWidgetFunc = [this](QWidget * parent) -> LtsWidgets::LtsDialog *
|
||||
{
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Ftc> ismFtc;
|
||||
if (!m_session->getDtc<InfrastructureManagement::DataInterface>(ismDtc)
|
||||
|| !m_session->getFtc<InfrastructureManagement::DataInterface>(ismFtc))
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(m_session->baseLayoutWidget(), tr("The Infrastructure Management is not available!"), tr("Cannot open Exercise Assignment"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return LtsWidgets::initDialog(new ExerciseAssignmentDialog(m_session, parent),
|
||||
ismDtc, ismFtc, m_exmDtc);
|
||||
};
|
||||
|
||||
return {plugin};
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
return /*m_session->getDtc<DataInterface>(m_ismDtc) &&
|
||||
m_session->getFtc<DataInterface>(m_ismFtc) &&*/
|
||||
m_session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc)/* &&
|
||||
m_session->getForeignDataInterface<DataInterface>(m_ismDataInterface)*/;
|
||||
}
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
//m_ismDataInterface = nullptr;
|
||||
m_exmDtc = nullptr;
|
||||
}
|
||||
|
||||
//void InterfaceImpl::executePayload(LtsWidgets::LtsBackgroundWidget *)
|
||||
//{
|
||||
// DEBUG_LOG(m_logger) << "executePayload";
|
||||
|
||||
// connect(this, &InterfaceImpl::signalSuccess,
|
||||
// m_session, &LtsSession::LtsSession::slotExecuteNextPayload, Qt::QueuedConnection);
|
||||
|
||||
// emit signalSuccess();
|
||||
//}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for AudioVideoConfig
|
||||
* $Id: ism_audio_video_config_gui_plugin.h 58505 2022-11-28 15:41:44Z wille_m $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ism_audio_video_config_gui_plugin.h $
|
||||
* $Author: wille_m $
|
||||
*
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_exercise_assignment_classic_gui_plugin_interface.h>
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:ism.eac")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return ForeignExerciseAssignmentClassicGuiInterface::pluginName(); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final
|
||||
: public QObject
|
||||
, public ForeignExerciseAssignmentClassicGuiInterface
|
||||
, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
QString menuGroup() const override { return tr("Training Voice Communication"); }
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
// // be able to show exercise chooser
|
||||
// int executionPriority() const override { return 9999; }
|
||||
// void executePayload(LtsWidgets::LtsBackgroundWidget *mainBackground) override;
|
||||
|
||||
private: // attributes
|
||||
// std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
// std::shared_ptr<InfrastructureManagement::Interface::Ftc> m_ismFtc;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
//std::shared_ptr<ForeignDataInterface> m_ismDataInterface;
|
||||
signals:
|
||||
void signalSuccess();
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ExerciseAssignmentDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id: ism_exercise_assignment_dialog.cpp 57779 2022-08-03 08:07:45Z ojog_i $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ExerciseAssignment/ism_exercise_assignment_dialog.cpp $
|
||||
* $Author: ojog_i $
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_dialog.h"
|
||||
#include "ui_ism_exercise_assignment_dialog.h"
|
||||
|
||||
#include "ism_exercise_assignment_dialog_model.h"
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QTreeView>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
ExerciseAssignmentDialog::ExerciseAssignmentDialog(LtsSession::LtsSession *session, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_session(session)
|
||||
, m_ui(new Ui::ExerciseAssignmentDialog)
|
||||
, m_ismDtc(nullptr)
|
||||
, m_ismFtc(nullptr)
|
||||
, m_exmDtc(nullptr)
|
||||
, m_model(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("ExerciseAssignmentDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->assetListView->setSelectionMode(QAbstractItemView::MultiSelection);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &ExerciseAssignmentDialog::onPrint);
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Exercise_Assignment"));
|
||||
}
|
||||
|
||||
ExerciseAssignmentDialog::~ExerciseAssignmentDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Exercise Assignment"));
|
||||
}
|
||||
|
||||
bool ExerciseAssignmentDialog::init(const std::shared_ptr<Interface::Dtc> &ismDtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ismFtc,
|
||||
const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc)
|
||||
{
|
||||
m_ismDtc = ismDtc;
|
||||
m_ismFtc = ismFtc;
|
||||
m_exmDtc = exmDtc;
|
||||
delete m_model;
|
||||
|
||||
if (!m_ismFtc->enableInstrumentationAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT InstrumentationAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ismFtc->enableMainStructureElementModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MainStructureElementModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_exmDtc->enableExercise())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable DT Exercise of EXM";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add all available exercises to comboBox
|
||||
const QMap<qint32, ExerciseManagement::Exercise> exercises = m_exmDtc->exercises();
|
||||
m_ui->cbExercises->addItem(QStringLiteral("-"), 0);
|
||||
for (const auto &exercise : exercises)
|
||||
m_ui->cbExercises->addItem(QString::fromStdString(exercise.name()), exercise.id());
|
||||
|
||||
m_ui->pbAssigned->setEnabled(false);
|
||||
|
||||
m_model = new ExerciseAssignmentDialogModel(this);
|
||||
if (!m_model->initModel(m_ismDtc, m_exmDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ui->assetListView->setModel(m_model);
|
||||
|
||||
connect(m_ui->assetListView, &LtsDataView::LtsDataView::selectionChanged,
|
||||
this, &ExerciseAssignmentDialog::onSelectionChanged);
|
||||
connect(m_ui->pbAssigned, &QPushButton::clicked,
|
||||
this, &ExerciseAssignmentDialog::onAssignedClicked);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::onAssignedClicked()
|
||||
{
|
||||
const QModelIndexList selectedIndexs = m_ui->assetListView->selectedRows();
|
||||
if (selectedIndexs.size() < 1)
|
||||
return;
|
||||
|
||||
for (const auto &index : selectedIndexs)
|
||||
{
|
||||
m_requestHelper->addRequest([this, index]()
|
||||
{
|
||||
MainStructureElementModifyRequest request;
|
||||
MainStructureElement &req = request;
|
||||
req = m_model->getRowData(index.row());
|
||||
|
||||
QJsonObject obj = QJsonDocument::fromJson(QByteArray::fromStdString(request.properties())).object();
|
||||
|
||||
// Exercise choose?
|
||||
QJsonArray array;
|
||||
if (m_ui->cbExercises->currentIndex() != 0)
|
||||
array.push_back(m_ui->cbExercises->currentData().toInt());
|
||||
obj.insert(QStringLiteral("available_in_exercise"), array);
|
||||
request.properties(QJsonDocument(obj).toJson(QJsonDocument::Compact).toStdString());
|
||||
|
||||
return m_ismFtc->mainStructureElementModifyRequest(request, this);
|
||||
|
||||
});
|
||||
}
|
||||
m_requestHelper->startRequests();
|
||||
//m_requestHelper->startSingleRequest([this, request]() {return m_ismFtc->mainStructureElementModifyRequest(request, this);});
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::onSelectionChanged()
|
||||
{
|
||||
const auto selectedIndexes = m_ui->assetListView->selectedRows();
|
||||
m_ui->pbAssigned->setEnabled(!selectedIndexes.isEmpty());
|
||||
m_ui->cbExercises->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->assetListView->treeView());
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetListDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id: ism_exercise_assignment_dialog.h 45935 2019-03-08 08:36:11Z ehrlicher $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ExerciseAssignment/ism_exercise_assignment_dialog.h $
|
||||
* $Author: ehrlicher $
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExerciseAssignmentDialog;
|
||||
}
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ExerciseAssignmentDialogModel;
|
||||
|
||||
class ExerciseAssignmentDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected InfrastructureManagement::Interface::Ftc::MainStructureElementModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExerciseAssignmentDialog(LtsSession::LtsSession *session, QWidget *parent = nullptr);
|
||||
~ExerciseAssignmentDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &ismDtc, const std::shared_ptr<Interface::Ftc> &ismFtc, const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc);
|
||||
void onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAssignedClicked();
|
||||
void onSelectionChanged();
|
||||
void onPrint();
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
|
||||
private: // attributes
|
||||
LtsSession::LtsSession *m_session;
|
||||
Ui::ExerciseAssignmentDialog *m_ui;
|
||||
std::shared_ptr<Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ismFtc;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
ExerciseAssignmentDialogModel *m_model;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class AssetListDialogModel
|
||||
} // namespace InfrastructureManagement
|
||||
Lts/Plugins/InfrastructureManagement/Gui/ExerciseAssignmentClassic/ism_exercise_assignment_dialog.ui
Executable
+70
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExerciseAssignmentDialog</class>
|
||||
<widget class="QWidget" name="ExerciseAssignmentDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="assetListView"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbExercises">
|
||||
<property name="text">
|
||||
<string>Exercises:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbExercises">
|
||||
<property name="currentText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbAssigned">
|
||||
<property name="text">
|
||||
<string>Assign to selection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ExerciseAssignmentDialogModel provices data for AssetListDialog
|
||||
* $Id: ism_exercise_assignment_dialog_model.cpp 49203 2019-12-17 09:50:35Z rudolphus_g $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ExerciseAssignment/ism_exercise_assignment_dialog_model.cpp $
|
||||
* $Author: rudolphus_g $
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_dialog_model.h"
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
using namespace InfrastructureManagement;
|
||||
|
||||
ExerciseAssignmentDialogModel::ExerciseAssignmentDialogModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<MainStructureElement>(
|
||||
{
|
||||
tr("Name"),
|
||||
tr("Assigned Exercise")
|
||||
},
|
||||
parent)
|
||||
, m_dtc(nullptr)
|
||||
, m_exmDtc(nullptr)
|
||||
, m_logger(getLogger("ExerciseAssignmentDialogModel"))
|
||||
{
|
||||
}
|
||||
|
||||
ExerciseAssignmentDialogModel::~ExerciseAssignmentDialogModel()
|
||||
{
|
||||
}
|
||||
|
||||
QVariant ExerciseAssignmentDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole || !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const MainStructureElement ¤tMainStructureElement = m_vecData.at(index.row());
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
return m_dtc->getBuildingDisplayName(currentMainStructureElement.id());
|
||||
case ASSIGNED_EXERCISES:
|
||||
{
|
||||
if (!currentMainStructureElement.properties().size())
|
||||
return QChar(QLatin1Char('-'));
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(currentMainStructureElement.properties()), &parseError);
|
||||
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Could not parse JSON props of building with ID "
|
||||
<< currentMainStructureElement.id()
|
||||
<< ". Reason: "
|
||||
<< parseError.errorString()
|
||||
<< "; JSON: "
|
||||
<< doc.toJson(QJsonDocument::Compact);
|
||||
return QChar(QLatin1Char('-'));
|
||||
}
|
||||
|
||||
QJsonArray arr = doc.object().value(QLatin1String("available_in_exercise")).toArray();
|
||||
|
||||
if (arr.isEmpty())
|
||||
return QChar(QLatin1Char('-'));
|
||||
|
||||
QString exercise = QString::fromUtf8(QJsonDocument(arr).toJson(QJsonDocument::Compact));
|
||||
|
||||
exercise.remove(QLatin1Char('['));
|
||||
exercise.remove(QLatin1Char(']'));
|
||||
|
||||
if (exercise.size())
|
||||
{
|
||||
int exId = exercise.toInt();
|
||||
return QString::fromStdString(m_exmDtc->exercise(exId).name());
|
||||
}
|
||||
return QChar(QLatin1Char('-'));
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool ExerciseAssignmentDialogModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_exmDtc = exmDtc;
|
||||
|
||||
if (!m_dtc->enableInstrumentationAsset())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Datatopic InstrumentationAsset of the Data Topic Client";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_exmDtc->enableExercise())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Topic Exercise from Exercise Management DTC";
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainStructureElementChanged,
|
||||
this, &ExerciseAssignmentDialogModel::onDataChanged);
|
||||
|
||||
auto cb = [this](const InfrastructureManagement::MainStructureElement &mse)
|
||||
{
|
||||
onDataChanged(mse, DataModification::eAdded);
|
||||
};
|
||||
m_dtc->mainStructureElements(cb);
|
||||
|
||||
INFO_LOG(m_logger) << "initModel successful";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExerciseAssignmentDialogModel::isFiltered(const InfrastructureManagement::MainStructureElement &data, DataModification modType) const
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
return (data.structureElementTypeId() != InfrastructureManagement::StructureElementType::Building &&
|
||||
data.structureElementTypeId() != InfrastructureManagement::StructureElementType::Announcement);
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ExerciseAssignmentDialogModel provices data for AssetListDialog
|
||||
* $Id: ism_exercise_assignment_dialog_model.h 41411 2018-04-24 14:51:44Z ojog_i $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/iterations/22_01_homer/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ExerciseAssignment/ism_exercise_assignment_dialog_model.h $
|
||||
* $Author: ojog_i $
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ExerciseAssignmentDialogModel final : public LtsWidgets::LtsAbstractTableModel<MainStructureElement>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExerciseAssignmentDialogModel(QObject *parent = nullptr);
|
||||
~ExerciseAssignmentDialogModel();
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<ExerciseManagement::Interface::Dtc> &exmDtc);
|
||||
|
||||
protected:
|
||||
bool isFiltered(const InfrastructureManagement::MainStructureElement &data, DataModification modType) const override;
|
||||
|
||||
private: // other
|
||||
enum Columns
|
||||
{
|
||||
NAME,
|
||||
ASSIGNED_EXERCISES
|
||||
};
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> m_exmDtc;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class ExerciseAssignmentDialogModel
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::MainStructureElement)
|
||||
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Mike Wille, SLSE, 2016-05-05
|
||||
#
|
||||
|
||||
SET(ism_combobox_gui_SRCS
|
||||
ism_combobox_gui_plugin.cpp
|
||||
ism_combobox_gui_plugin.h
|
||||
ism_combobox.cpp
|
||||
ism_combobox.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(ism_combobox_gui_SRCS
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS IsmComboBoxGuiPlugin MODULE ${ism_combobox_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmComboBoxGuiPlugin
|
||||
NGLLogger
|
||||
IsmGuiComboboxPluginInterface
|
||||
IsmDataPluginInterface
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsSession
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(IsmComboBoxGuiPlugin)
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* InfrastructureManagement - IsmComboBox Gui Plugin
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-16
|
||||
*/
|
||||
|
||||
#include "ism_combobox.h"
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <LtsUtilsCore/json_object.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
bool IsmComboBox::fill(LtsWidgets::LtsComboBox *cbx, IsmComboBoxType type, LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc, int filter)
|
||||
{
|
||||
Q_UNUSED(session);
|
||||
cbx->clear();
|
||||
switch (type)
|
||||
{
|
||||
case IsmComboBoxType::CbRadioStations:
|
||||
{
|
||||
auto cb = [cbx,filter](const InfrastructureManagement::MainStructureElement &mse)
|
||||
{
|
||||
if (mse.structureElementTypeId() == InfrastructureManagement::StructureElementType::RadioStation && !mse.isDeleted() && mse.id() > 0 )
|
||||
{
|
||||
const RadioStation &rs = RadioStation::fromMSE(mse);
|
||||
if (((filter >= 0) && rs.radios.contains(static_cast<FrequencyBand>(filter))) ||
|
||||
(filter < 0))
|
||||
{
|
||||
cbx->addItem(QString::fromStdString(mse.name()), mse.id());
|
||||
cbx->setItemData(cbx->findData(mse.id()), rs.radioStationId, Qt::UserRole + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
dtc->mainStructureElements(cb);
|
||||
break;
|
||||
}
|
||||
case IsmComboBoxType::CbApproachingPoints:
|
||||
{
|
||||
auto cb = [cbx](const InfrastructureManagement::MainStructureElement &mse)
|
||||
{
|
||||
if ((mse.structureElementTypeId() == InfrastructureManagement::StructureElementType::ApproachingPoint) && !mse.isDeleted() && (mse.id() > 0))
|
||||
{
|
||||
cbx->addItem(QString::fromStdString(mse.name()), mse.id());
|
||||
cbx->setItemData(cbx->findData(mse.id()), mse.angle(), Qt::UserRole + 1);
|
||||
}
|
||||
};
|
||||
dtc->mainStructureElements(cb);
|
||||
break;
|
||||
}
|
||||
case IsmComboBoxType::CbScheduleStatus:
|
||||
{
|
||||
cbx->addItem(toString(ScheduleStatus::Active), ScheduleStatus::Active);
|
||||
cbx->addItem(toString(ScheduleStatus::Inactive), ScheduleStatus::Inactive);
|
||||
break;
|
||||
}
|
||||
case IsmComboBoxType::CbBridgeStatus:
|
||||
{
|
||||
cbx->addItem(toString(BridgeStatus::Intact), BridgeStatus::Intact);
|
||||
cbx->addItem(toString(BridgeStatus::Broken), BridgeStatus::Broken);
|
||||
}
|
||||
case IsmComboBoxType::CbUnknown:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return cbx->count() > 0;
|
||||
}
|
||||
|
||||
RadioStation RadioStation::fromMSE(const MainStructureElement &mse)
|
||||
{
|
||||
RadioStation rs;
|
||||
rs.mse_id = mse.id();
|
||||
rs.name = QString::fromStdString(mse.name());
|
||||
|
||||
LtsUtils::JsonObject jo = LtsUtils::JsonObject::fromJson(mse.properties());
|
||||
LtsUtils::JsonArray radios = jo.valueOr<LtsUtils::JsonArray>("radios", {});
|
||||
|
||||
// The best and easiest solution is to iterate over the JsonArray right!?
|
||||
// for (const QJsonValue &radioValues : qAsConst(radios))
|
||||
// for (const JsonObject &radioObject : qAsConst(radios))
|
||||
|
||||
const QVector<LtsUtils::JsonObject> &radiosAsVector = radios.toVector<LtsUtils::JsonObject>();
|
||||
for (const LtsUtils::JsonObject &radio : qAsConst(radiosAsVector))
|
||||
{
|
||||
FrequencyBand fb = static_cast<FrequencyBand>(radio.valueOr<int>("frequencyBand", -1));
|
||||
int count = radio.valueOr<int>("count", 0);
|
||||
if (fb != FrequencyBand::INVALID)
|
||||
rs.radios.insert(fb,count);
|
||||
}
|
||||
|
||||
rs.radioStationId = jo.valueOr<int>("stationId", 0);
|
||||
return rs;
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* InfrastructureManagement - IsmComboBox Gui Plugin
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-16
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsWidgets/lts_combo_box.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
enum IsmComboBoxType
|
||||
{
|
||||
CbUnknown = 0,
|
||||
CbRadioStations,
|
||||
CbApproachingPoints,
|
||||
CbScheduleStatus,
|
||||
CbBridgeStatus
|
||||
};
|
||||
|
||||
// Keep in sync with avm_enums.h!
|
||||
enum FrequencyBand
|
||||
{
|
||||
INVALID = -1,
|
||||
VHF = 0,
|
||||
UHF = 1,
|
||||
HF = 2,
|
||||
REL = 3
|
||||
};
|
||||
|
||||
struct RadioStation
|
||||
{
|
||||
int mse_id;
|
||||
int radioStationId;
|
||||
QString name;
|
||||
QMap<FrequencyBand, int> radios; // How many radios are there per type?
|
||||
static RadioStation fromMSE(const MainStructureElement &mse);
|
||||
};
|
||||
|
||||
// --------------------------------------------------------
|
||||
// ComboBox
|
||||
// --------------------------------------------------------
|
||||
class IsmComboBox
|
||||
{
|
||||
public:
|
||||
Q_REQUIRED_RESULT static bool fill(LtsWidgets::LtsComboBox *cbx,
|
||||
IsmComboBoxType type,
|
||||
LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc, int filter = -1);
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* GUI Plugin for InfrastructureManagement - IsmComboBox
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-16
|
||||
*/
|
||||
|
||||
#include "ism_combobox_gui_plugin.h"
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.IsmCombobox"))
|
||||
, m_dtc(nullptr)
|
||||
{}
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
// if (!m_session->getDtc<InfrastructureManagement::DataInterface>(m_dtc))
|
||||
// {
|
||||
// DEBUG_LOG(m_logger) << "Failed to fetch Dtc InfrastructureManagement interface!";
|
||||
// return false;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void InterfaceImpl::clearInterfaces()
|
||||
{
|
||||
m_dtc = nullptr;
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fillRadioStationsComboBox(LtsWidgets::LtsComboBox *cbx, int filter)
|
||||
{
|
||||
return fillIsmComboBox(cbx, IsmComboBoxType::CbRadioStations, filter);
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fillApproachingPointsComboBox(LtsWidgets::LtsComboBox *cbx)
|
||||
{
|
||||
return fillIsmComboBox(cbx, IsmComboBoxType::CbApproachingPoints);
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fillScheduleStatusComboBox(LtsWidgets::LtsComboBox *cbx)
|
||||
{
|
||||
return fillIsmComboBox(cbx, IsmComboBoxType::CbScheduleStatus);
|
||||
}
|
||||
|
||||
bool InterfaceImpl::fillBridgeStatusComboBox(LtsWidgets::LtsComboBox *cbx)
|
||||
{
|
||||
return fillIsmComboBox(cbx, IsmComboBoxType::CbBridgeStatus);
|
||||
}
|
||||
|
||||
//private
|
||||
|
||||
bool InterfaceImpl::fillIsmComboBox(LtsWidgets::LtsComboBox *cbx, IsmComboBoxType type, int filter)
|
||||
{
|
||||
if (!m_dtc && !m_session->getDtc<InfrastructureManagement::DataInterface>(m_dtc))
|
||||
return false;
|
||||
|
||||
return IsmComboBox::fill(cbx, type, m_session, m_dtc, filter);
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for InfrastructureManagement - IsmComboBox
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-16
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ism_combobox.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_combobox_gui_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
#include <QComboBox>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:ism.combobox")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QStringLiteral("InfrastructureManagement.GuiPlugin.ComboBox"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Global ||
|
||||
partition == IDL::PartitionType::Exercise ||
|
||||
partition == IDL::PartitionType::Replay);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public ForeignGuiComboboxInterface, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
void clearInterfaces() override;
|
||||
QString menuGroup() const override { return QString(); }
|
||||
bool availableInPartition(IDL::PartitionType partition) const override { return partition == IDL::PartitionType::Global || partition == IDL::PartitionType::Exercise; }
|
||||
|
||||
// ForeignDataInterface
|
||||
bool fillRadioStationsComboBox(LtsWidgets::LtsComboBox *cbx, int filter) override;
|
||||
bool fillApproachingPointsComboBox(LtsWidgets::LtsComboBox *cbx) override;
|
||||
bool fillScheduleStatusComboBox(LtsWidgets::LtsComboBox *cbx) override;
|
||||
bool fillBridgeStatusComboBox(LtsWidgets::LtsComboBox *cbx) override;
|
||||
|
||||
private:
|
||||
bool fillIsmComboBox(LtsWidgets::LtsComboBox *cbx, IsmComboBoxType type, int filter = -1);
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ApproachingPointsDialog shows a list of approaching points
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-17
|
||||
*/
|
||||
|
||||
#include "ism_approaching_point_list_dialog.h"
|
||||
#include "ui_ism_approaching_point_list_dialog.h"
|
||||
#include "ism_approaching_point_list_dialog_model.h"
|
||||
#include "ism_edit_approaching_point_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QTreeView>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
ApproachingPointsDialog::ApproachingPointsDialog(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_session(session)
|
||||
, m_ui(new Ui::ApproachingPointsDialog)
|
||||
, m_model(nullptr)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_logger(getLogger("ApproachingPointsDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &ApproachingPointsDialog::onPrint);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Approach_Points"));
|
||||
}
|
||||
|
||||
ApproachingPointsDialog::~ApproachingPointsDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void ApproachingPointsDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Approaching Points"));
|
||||
}
|
||||
|
||||
void ApproachingPointsDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->approachingPointsView->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
bool ApproachingPointsDialog::init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMap)
|
||||
{
|
||||
m_ftc = ftc;
|
||||
m_sitMapIfc = sitMap;
|
||||
delete m_model;
|
||||
m_model = new ApproachingPointsDialogModel(this);
|
||||
if (!m_model->initModel(dtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ui->approachingPointsView->setModel(m_model);
|
||||
|
||||
connect(m_ui->approachingPointsView, &LtsDataView::LtsDataView::signalDoubleClicked,
|
||||
this, &ApproachingPointsDialog::onItemDoubleClicked);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &ApproachingPointsDialog::onItemDoubleClicked);
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, true);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &ApproachingPointsDialog::onAddApproachingPoint);
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->approachingPointsView->hideColumn(ApproachingPointsDialogModel::Columns::Id);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApproachingPointsDialog::onItemDoubleClicked()
|
||||
{
|
||||
QModelIndex currentIndex = m_ui->approachingPointsView->currentIndex();
|
||||
|
||||
if (!currentIndex.isValid())
|
||||
return;
|
||||
|
||||
EditApproachingPointDialog *dialog = new EditApproachingPointDialog(this);
|
||||
|
||||
MainStructureElement approachingPoint = m_model->getRowData(currentIndex.row());
|
||||
if (!dialog->init(m_ftc, m_sitMapIfc, approachingPoint))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
|
||||
addDialog(dialog, m_menuGroup, QStringLiteral("EditApproachingPoint%1").arg(approachingPoint.id()), LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
void ApproachingPointsDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->approachingPointsView->treeView() );
|
||||
}
|
||||
|
||||
void ApproachingPointsDialog::onAddApproachingPoint()
|
||||
{
|
||||
QModelIndex currentIndex = m_ui->approachingPointsView->currentIndex();
|
||||
|
||||
EditApproachingPointDialog *dialog = new EditApproachingPointDialog(this);
|
||||
|
||||
MainStructureElement approachingPoint = m_model->getRowData(currentIndex.row());
|
||||
approachingPoint.id(0);
|
||||
if (!dialog->init(m_ftc, m_sitMapIfc, approachingPoint))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
|
||||
addDialog(dialog, m_menuGroup, QStringLiteral("AddApproachingPoint"), LtsWidgets::LayoutArea::eDialogTab);
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ApproachingPointsDialog shows a list of approaching points
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-17
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ApproachingPointsDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class ForeignGuiInterface;
|
||||
}
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
class ApproachingPointsDialogModel;
|
||||
|
||||
class ApproachingPointsDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ApproachingPointsDialog(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent = nullptr);
|
||||
~ApproachingPointsDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMap);
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
void onItemDoubleClicked();
|
||||
void onPrint();
|
||||
void onAddApproachingPoint();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
LtsSession::LtsSession *m_session;
|
||||
Ui::ApproachingPointsDialog *m_ui;
|
||||
ApproachingPointsDialogModel *m_model;
|
||||
QString m_menuGroup;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapIfc;
|
||||
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class ApproachingPointsDialogModel
|
||||
} // namespace InfrastructureManagement
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ApproachingPointsDialog</class>
|
||||
<widget class="QWidget" name="ApproachingPointsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Approaching Points</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="LtsDataView::LtsDataView" name="approachingPointsView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ApproachingPointsDialogModel provides data for ApproachingPointsDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-17
|
||||
*/
|
||||
|
||||
#include "ism_approaching_point_list_dialog_model.h"
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <QDateTime>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
ApproachingPointsDialogModel::ApproachingPointsDialogModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<MainStructureElement>({tr("Id"),
|
||||
tr("Name"),
|
||||
tr("Description"),
|
||||
tr("Position"),
|
||||
tr("Departure Direction"),
|
||||
tr("Special Type"),
|
||||
tr("Properties")},
|
||||
parent)
|
||||
, m_logger(getLogger("ApproachingPointsDialogModel"))
|
||||
{
|
||||
}
|
||||
|
||||
QVariant ApproachingPointsDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role != Qt::DisplayRole || !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const MainStructureElement ¤tPoint = m_vecData.at(index.row());
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case Id:
|
||||
return currentPoint.id();
|
||||
case Name:
|
||||
return QString::fromStdString(currentPoint.name());
|
||||
case Description:
|
||||
{
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(currentPoint.description()));
|
||||
const QString jsonKey = QLatin1String("description");
|
||||
if (!doc.isObject())
|
||||
return QVariant();
|
||||
return doc.object().value(jsonKey).toString();
|
||||
}
|
||||
case Position:
|
||||
return LtsCoordTrans::mgrsFromGeographic(currentPoint.geoPosition().lon(), currentPoint.geoPosition().lat());
|
||||
case Orientation:
|
||||
return calculateCardinalDirection(currentPoint.angle());
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool ApproachingPointsDialogModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc)
|
||||
{
|
||||
connect(dtc.get(), &Interface::Dtc::mainStructureElementChanged,
|
||||
this, &ApproachingPointsDialogModel::onDataChanged);
|
||||
|
||||
auto cb = [this](const InfrastructureManagement::MainStructureElement &mse)
|
||||
{
|
||||
onDataChanged(mse, DataModification::eAdded);
|
||||
};
|
||||
dtc->mainStructureElements(cb);
|
||||
|
||||
INFO_LOG(m_logger) << "initModel successful";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString ApproachingPointsDialogModel::calculateCardinalDirection(double degree, bool longVersion) const
|
||||
{
|
||||
int value = (int) ((degree / 45) + 0.5) % 8;
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case 0:
|
||||
return longVersion ? tr("North") : tr("N");
|
||||
case 1:
|
||||
return longVersion ? tr("North-East") : tr("NE");
|
||||
case 2:
|
||||
return longVersion ? tr("East") : tr("E");
|
||||
case 3:
|
||||
return longVersion ? tr("South-East") : tr("SE");
|
||||
case 4:
|
||||
return longVersion ? tr("South") : tr("S");
|
||||
case 5:
|
||||
return longVersion ? tr("South-West") : tr("SW");
|
||||
case 6:
|
||||
return longVersion ? tr("West") : tr("W");
|
||||
case 7:
|
||||
return longVersion ? tr("North-West") : tr("NW");
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool ApproachingPointsDialogModel::isFiltered(const InfrastructureManagement::MainStructureElement &data, DataModification modType) const
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
return (data.structureElementTypeId() != InfrastructureManagement::StructureElementType::ApproachingPoint);
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ApproachingPointsDialogModel provides data for ApproachingPointsDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-17
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ApproachingPointsDialogModel : public LtsWidgets::LtsAbstractTableModel<MainStructureElement>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ApproachingPointsDialogModel(QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc);
|
||||
QString calculateCardinalDirection(double degree, bool longVersion = true) const;
|
||||
|
||||
enum Columns
|
||||
{
|
||||
Id,
|
||||
Name,
|
||||
Description,
|
||||
Position,
|
||||
Orientation
|
||||
};
|
||||
|
||||
protected:
|
||||
bool isFiltered(const InfrastructureManagement::MainStructureElement &data, DataModification modType) const override;
|
||||
|
||||
private: // attributes
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class ApproachingPointsDialogModel
|
||||
} // namespace InfrastructureManagement
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditApproachingPointDialog offers an UI to edit an Approaching Point
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-17
|
||||
*/
|
||||
|
||||
#include "ism_edit_approaching_point_dialog.h"
|
||||
#include "ui_ism_edit_approaching_point_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
EditApproachingPointDialog::EditApproachingPointDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_ui(new Ui::EditApproachingPointDialog)
|
||||
, m_ftc(nullptr)
|
||||
, m_sitMapGuiIfc(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("EditApproachingPointDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
fillCbDepartureDirection();
|
||||
m_uiRequirements->addRequirement({m_ui->lblPosition, [this]() { return !m_ui->positionEdit->coordinate().isNull(); }});
|
||||
m_uiRequirements->addRequirement({m_ui->lblName, [this]() { return !m_ui->leName->text().isEmpty(); }});
|
||||
|
||||
connect(m_ui->pbClear, &QPushButton::clicked,
|
||||
m_ui->positionEdit, &LtsCoordWidget::LtsCoordWidget::clear);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Approach_Points"));
|
||||
}
|
||||
|
||||
EditApproachingPointDialog::~EditApproachingPointDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void EditApproachingPointDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, m_approachingPoint, tr("Approaching Point"));
|
||||
}
|
||||
|
||||
bool EditApproachingPointDialog::init(const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMap,
|
||||
const MainStructureElement &approachingPoint)
|
||||
{
|
||||
m_ftc = ftc;
|
||||
m_sitMapGuiIfc = sitMap;
|
||||
if (m_sitMapGuiIfc)
|
||||
connect(m_ui->pbPosition, &QPushButton::clicked, this, &EditApproachingPointDialog::getPosition);
|
||||
else
|
||||
m_ui->pbPosition->setEnabled(false);
|
||||
|
||||
setData(approachingPoint);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EditApproachingPointDialog::apply()
|
||||
{
|
||||
return m_requestHelper->startSingleRequest([this]()
|
||||
{
|
||||
MainStructureElementModifyRequest request;
|
||||
|
||||
request.id(m_approachingPoint.id());
|
||||
request.name(m_ui->leName->text().toStdString());
|
||||
request.angle(m_ui->cbDepartureDirection->currentData().toDouble());
|
||||
|
||||
request.properties("{}");
|
||||
request.structureElementId(m_approachingPoint.structureElementId());
|
||||
request.structureElementTypeId(InfrastructureManagement::StructureElementType::ApproachingPoint);
|
||||
|
||||
QJsonObject objDescription;
|
||||
objDescription.insert(QLatin1String("description"), m_ui->leDescription->text());
|
||||
request.description(QJsonDocument(objDescription).toJson(QJsonDocument::Compact).toStdString());
|
||||
|
||||
const Core::GeoPosition pos(m_ui->positionEdit->coordinate().x(),m_ui->positionEdit->coordinate().y(), 0);
|
||||
request.geoPosition(pos);
|
||||
|
||||
// fill in structure element (only one, needed for mse/se relationsships)
|
||||
if (m_approachingPoint.id() == 0)
|
||||
{
|
||||
StructureElement seData;
|
||||
seData.name(request.name());
|
||||
seData.displayName(request.name());
|
||||
seData.structureElementTypeId(InfrastructureManagement::StructureElementType::ApproachingPoint);
|
||||
seData.mountingPointTypeId(InfrastructureManagement::MountingPointType::Unknown);
|
||||
seData.properties("{}");
|
||||
|
||||
request.elements().resize(1, seData);
|
||||
request.childParentRelations().resize(1, -1);
|
||||
}
|
||||
|
||||
return m_ftc->mainStructureElementModifyRequest(request, this);
|
||||
});
|
||||
}
|
||||
|
||||
void EditApproachingPointDialog::fillCbDepartureDirection()
|
||||
{
|
||||
m_ui->cbDepartureDirection->insertItem(0,tr("North"),0);
|
||||
m_ui->cbDepartureDirection->insertItem(1,tr("North-East"),45);
|
||||
m_ui->cbDepartureDirection->insertItem(2,tr("East"),90);
|
||||
m_ui->cbDepartureDirection->insertItem(3,tr("South-East"),135);
|
||||
m_ui->cbDepartureDirection->insertItem(4,tr("South"),180);
|
||||
m_ui->cbDepartureDirection->insertItem(5,tr("South-West"),225);
|
||||
m_ui->cbDepartureDirection->insertItem(6,tr("West"),270);
|
||||
m_ui->cbDepartureDirection->insertItem(7,tr("North-West"),315);
|
||||
}
|
||||
|
||||
void EditApproachingPointDialog::setData(const MainStructureElement &approachingPoint)
|
||||
{
|
||||
m_approachingPoint = approachingPoint;
|
||||
|
||||
m_ui->leName->setText(QString::fromStdString(m_approachingPoint.name()));
|
||||
QJsonObject objDescription = QJsonDocument::fromJson(QByteArray::fromStdString(m_approachingPoint.description())).object();
|
||||
QString strDescription = objDescription.value(QLatin1String("description")).toString();
|
||||
m_ui->leDescription->setText(strDescription);
|
||||
QPointF pos(m_approachingPoint.geoPosition().lon(), m_approachingPoint.geoPosition().lat());
|
||||
if (!pos.isNull())
|
||||
m_ui->positionEdit->setCoordinate(pos);
|
||||
|
||||
m_ui->cbDepartureDirection->setCurrentIndex( (int) ((approachingPoint.angle() / 45) + 0.5) % 8);
|
||||
}
|
||||
|
||||
void EditApproachingPointDialog::getPosition()
|
||||
{
|
||||
if (!m_sitMapGuiIfc) //sanity
|
||||
return;
|
||||
m_sitMapGuiIfc->getCoordinate(m_ui->positionEdit, SLOT(setCoordinate(QPointF)), nullptr);
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditApproachingPointDialog offers an UI to edit an Approaching Point
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLSE, 2018-01-17
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsProgressDialogHelper;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EditApproachingPointDialog;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
class ForeignGuiInterface;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class EditApproachingPointDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::MainStructureElementModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EditApproachingPointDialog(QWidget *parent = nullptr);
|
||||
~EditApproachingPointDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &sitMap,
|
||||
const MainStructureElement &approachingPoint = MainStructureElement());
|
||||
void onMainStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
private slots:
|
||||
void getPosition();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void fillCbDepartureDirection();
|
||||
void setData(const MainStructureElement &approachingPoint);
|
||||
bool apply() override final;
|
||||
|
||||
Ui::EditApproachingPointDialog *m_ui;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
|
||||
MainStructureElement m_approachingPoint;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class EditApproachingPointDialog
|
||||
} // namespace InfrastructureManagement
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditApproachingPointDialog</class>
|
||||
<widget class="QWidget" name="EditApproachingPointDialog">
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Edit Approaching Point</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblDescription">
|
||||
<property name="text">
|
||||
<string>Description:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="leDescription"/>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbDepartureDirection"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblPosition">
|
||||
<property name="text">
|
||||
<string>Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="LtsCoordWidget::LtsCoordWidget" name="positionEdit"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbPosition">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/position.svg</normaloff>:/style/position.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbClear">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<normaloff>:/style/remove.svg</normaloff>:/style/remove.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblOrientation">
|
||||
<property name="text">
|
||||
<string>Departure Direction:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QLineEdit" name="leName"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblName">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsCoordWidget::LtsCoordWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsCoordTrans/lts_coord_widget.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>leName</tabstop>
|
||||
<tabstop>leDescription</tabstop>
|
||||
<tabstop>positionEdit</tabstop>
|
||||
<tabstop>pbPosition</tabstop>
|
||||
<tabstop>pbClear</tabstop>
|
||||
<tabstop>cbDepartureDirection</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+866
@@ -0,0 +1,866 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetListDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#include "ism_asset_list_dialog.h"
|
||||
#include "ui_ism_asset_list_dialog.h"
|
||||
#include "ism_asset_list_dialog_model.h"
|
||||
#include <InfrastructureManagement/ism_operator_rights.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <ComponentMonitor/cmo.hpp>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QFileDialog>
|
||||
#include <QTreeView>
|
||||
#include <QTextStream>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QTimer>
|
||||
#include <vector>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
static QHash<int, QString> &INSTRUMENTATION_ASSET_STATES()
|
||||
{
|
||||
static QHash<int, QString> s_ret
|
||||
{
|
||||
{InstrumentationAssetState_def::Unmounted, QLatin1String("Unmounted")},
|
||||
{InstrumentationAssetState_def::Mounted, QLatin1String("Mounted")},
|
||||
{InstrumentationAssetState_def::Defect, QLatin1String("Defect")}
|
||||
};
|
||||
return s_ret;
|
||||
}
|
||||
|
||||
AssetListDialog::AssetListDialog(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_session(session)
|
||||
, m_model(nullptr)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_dtc(nullptr)
|
||||
, m_ftc(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper())
|
||||
, m_ui(new Ui::AssetListDialog)
|
||||
, m_logger(getLogger("AssetListDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &AssetListDialog::onPrint);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Asset_List"));
|
||||
}
|
||||
|
||||
AssetListDialog::~AssetListDialog()
|
||||
{
|
||||
if (m_hostsForUpdateNotifiy)
|
||||
m_hostsForUpdateNotifiy->stop();
|
||||
|
||||
if(m_editAssetDialog!=nullptr)
|
||||
{
|
||||
m_editAssetDialog->deleteLater();
|
||||
}
|
||||
delete m_ui;
|
||||
delete m_model;
|
||||
}
|
||||
|
||||
void AssetListDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Asset List"));
|
||||
}
|
||||
|
||||
bool AssetListDialog::apply()
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Export)->setEnabled(true);
|
||||
bool enabled = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SystemConfiguration);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(enabled);
|
||||
|
||||
|
||||
InstrumentationAsset asset;
|
||||
for (int i = 0; i < m_model->rowCount(); ++i)
|
||||
{
|
||||
if (!rowContainsAlteredData(m_model->alteredRows().at(i)))
|
||||
continue;
|
||||
asset = m_model->getRowData(i);
|
||||
InstrumentationAssetModifyRequest request(asset.id(),
|
||||
asset.name(),
|
||||
asset.mountingPointTypeId(),
|
||||
asset.barcode(),
|
||||
asset.hostname(),
|
||||
asset.properties(),
|
||||
asset.assetStateId(),
|
||||
asset.lastUpdated(),
|
||||
asset.availableInExercise());
|
||||
m_requestHelper->addRequest([request, this]()
|
||||
{
|
||||
return m_ftc->instrumentationAssetModifyRequest(request, this);
|
||||
});
|
||||
}
|
||||
|
||||
m_model->removeBackgroundHighlighting();
|
||||
bool ret = m_requestHelper->startRequests();
|
||||
if(ret)
|
||||
{
|
||||
m_hasImportedAsset = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AssetListDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->assetListView->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::getExportString
|
||||
* @param exp enum class, that informs about the selected filtering option.
|
||||
* @param type gives the selected type in case of filtering by specific type, otherwise it is empty and unused.
|
||||
* @return a vector containing all filtered rows as string
|
||||
*/
|
||||
QVector<QString> AssetListDialog::getExportString(const AssetFilterDialog::Export &exp, const QString &type) const
|
||||
{
|
||||
QVector<QString> vecOut;
|
||||
|
||||
switch (exp)
|
||||
{
|
||||
// ----- CASE ALL -----
|
||||
case AssetFilterDialog::Export::eAll:
|
||||
{
|
||||
vecOut.reserve(m_model->rowCount());
|
||||
for (int i = 0; i < m_model->rowCount(); ++i)
|
||||
vecOut << exportData(m_model->getRowData(i));
|
||||
break;
|
||||
}// all end
|
||||
// ----- CASE SELECTED -----
|
||||
case AssetFilterDialog::Export::eSelected:
|
||||
{
|
||||
const auto idxList = m_ui->assetListView->selectedRows();
|
||||
vecOut.reserve(idxList.size());
|
||||
for (const QModelIndex &idx : idxList)
|
||||
vecOut << exportData(m_model->getRowData(idx.row()));
|
||||
break;
|
||||
} // selected end
|
||||
// ----- CASE SPECIFIC TYPE -----
|
||||
case AssetFilterDialog::Export::eSpecificType:
|
||||
{
|
||||
vecOut.reserve(m_model->rowCount() / 10);
|
||||
for (int i = 0; i < m_model->rowCount(); ++i)
|
||||
{
|
||||
const InstrumentationAsset &ia = m_model->getRowData(i);
|
||||
if (toString(ia.mountingPointTypeId()) == type)
|
||||
vecOut << exportData(ia);
|
||||
}
|
||||
break;
|
||||
} // specific type end
|
||||
} // switch end
|
||||
return vecOut;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::exportData
|
||||
* creates a string from the given InstrumentationAsset.
|
||||
* @param ia InstrumentationAsset contains several propertys.
|
||||
* @param separator the separator that is going to separate several items in the string.
|
||||
* @return contains every property of the given InstrumentationAsset, separated by the given separator.
|
||||
* @see importData()
|
||||
*/
|
||||
QString AssetListDialog::exportData(const InstrumentationAsset &ia, const QString &separator)
|
||||
{
|
||||
const QByteArray &properties = QByteArray::fromRawData(ia.properties().c_str(), ia.properties().size());
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(properties));
|
||||
const QJsonObject obj(doc.object());
|
||||
|
||||
const QString &name = QString::fromStdString(ia.name());
|
||||
const int nameSep = name.lastIndexOf(QLatin1Char('_'));
|
||||
const QString &dmc = QString::fromStdString(ia.barcode());
|
||||
const QString &tkz = name.mid(0, nameSep);
|
||||
const QString &snr = nameSep >= 0 ? name.mid(nameSep + 1) : QString();
|
||||
const QString &mac = obj.value(QStringLiteral("mac")).toString();
|
||||
const QString &status = INSTRUMENTATION_ASSET_STATES().value(ia.assetStateId().underlying());
|
||||
const QString &bz = ia.isUsed() ? QStringLiteral("Mounted") : QStringLiteral("Unmounted");
|
||||
const QString &oc = QString::number(obj.value(QStringLiteral("opticalCode")).toInt());
|
||||
const QString &ls = obj.value(QStringLiteral("hasSpeaker")).toBool() ? QStringLiteral("1") : QStringLiteral("0");
|
||||
const QString &mf = obj.value(QStringLiteral("hasMicrophone")).toBool() ? QStringLiteral("1") : QStringLiteral("0");
|
||||
const QString &vapix = obj.value(QStringLiteral("type")).toString() == QStringLiteral("vapix") ? QStringLiteral("1") : QStringLiteral("0");
|
||||
const QString &user = obj.value(QStringLiteral("username")).toString();
|
||||
const QString &pass = obj.value(QStringLiteral("password")).toString();
|
||||
const QString &props = QString::fromUtf8(properties);
|
||||
const QString &lastMod = QDateTime::fromMSecsSinceEpoch(ia.lastUpdated()).toString();
|
||||
|
||||
return QStringList({dmc, tkz, snr, mac, status, bz, oc, ls, mf, vapix, user, pass, props, lastMod}).join(separator);
|
||||
}
|
||||
|
||||
static std::string unquote(const QStringRef &in)
|
||||
{
|
||||
if (!in.startsWith(QLatin1Char('"')) && !in.endsWith(QLatin1Char('"')))
|
||||
return in.toString().toStdString();
|
||||
QString out = in.mid(1, in.length() - 2).toString();
|
||||
out.replace(QStringLiteral("\"\""), QStringLiteral("\""));
|
||||
return out.toStdString();
|
||||
}
|
||||
/**
|
||||
* @brief AssetListDialog::importData
|
||||
* creates an InstrumentationAsset from the given stringlist.
|
||||
* @param segments list of all segments of an InstrumentationAsset.
|
||||
* @return InstrumentationAsset.
|
||||
* @see exportData()
|
||||
*/
|
||||
static inline void setJson(QJsonObject &obj, const QString &key, bool bVal)
|
||||
{
|
||||
if (!bVal)
|
||||
obj.remove(key);
|
||||
else
|
||||
obj[key] = bVal;
|
||||
}
|
||||
static inline void setJson(QJsonObject &obj, const QString &key, const QStringRef &val)
|
||||
{
|
||||
if (val.isEmpty())
|
||||
obj.remove(key);
|
||||
else
|
||||
obj[key] = val.toString();
|
||||
}
|
||||
static inline void setJson(QJsonObject &obj, const QString &key, const QString &val)
|
||||
{
|
||||
setJson(obj, key, QStringRef(&val));
|
||||
}
|
||||
|
||||
InstrumentationAsset AssetListDialog::importData(const QVector<QStringRef> &segments, bool *bOk) const
|
||||
{
|
||||
if (bOk)
|
||||
*bOk = true;
|
||||
const int len = segments.size();
|
||||
|
||||
const QStringRef &dmc = segments.at(0);
|
||||
const QStringRef &tkz = segments.at(1);
|
||||
const QStringRef &snr = segments.at(2);
|
||||
const QStringRef &mac = segments.at(3);
|
||||
const QStringRef &status = segments.at(4);
|
||||
//const QString &bz = segments.at(5);
|
||||
const QStringRef &oc = segments.at(6);
|
||||
const QStringRef &ls = segments.at(7);
|
||||
const QStringRef &mf = segments.at(8);
|
||||
const QStringRef &vapix = segments.at(9);
|
||||
const QStringRef &user = len > 10 ? segments.at(10) : QStringRef();
|
||||
const QStringRef &pass = len > 11 ? segments.at(11) : QStringRef();
|
||||
const QStringRef &props = len > 12 ? segments.at(12) : QStringRef();
|
||||
//const QString &lastMod = len > 13 ? segments.at(13) : QStringRef();
|
||||
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(props.toUtf8()));
|
||||
QJsonObject obj(doc.object());
|
||||
setJson(obj, QStringLiteral("mac"), mac);
|
||||
setJson(obj, QStringLiteral("opticalCode"), oc);
|
||||
setJson(obj, QStringLiteral("hasSpeaker"), (ls.isEmpty() || ls == QLatin1String("0")) ? false : true);
|
||||
setJson(obj, QStringLiteral("hasMicrophone"), (mf.isEmpty() || mf == QLatin1String("0")) ? false : true);
|
||||
setJson(obj, QStringLiteral("type"), (vapix.isEmpty() || vapix == QLatin1String("0")) ? QString() : QStringLiteral("vapix"));
|
||||
setJson(obj, QStringLiteral("username"), user);
|
||||
setJson(obj, QStringLiteral("password"), pass);
|
||||
|
||||
const std::string snrStd = unquote(snr);
|
||||
const std::string tkzStd = unquote(tkz);
|
||||
InstrumentationAsset asset;
|
||||
asset.barcode() = unquote(dmc);
|
||||
asset.name() = snrStd.empty() ? tkzStd : std::string(tkzStd + '_' + snrStd);
|
||||
asset.assetStateId(static_cast<InstrumentationAssetState_def::type>(INSTRUMENTATION_ASSET_STATES().key(status.toString())));
|
||||
asset.properties() = QJsonDocument(obj).toJson(QJsonDocument::Compact).constData();
|
||||
// mountingPointTypeId is in DataMatrixCode
|
||||
if (dmc.startsWith(QLatin1String("GSM")))
|
||||
asset.mountingPointTypeId(MountingPointType::BuildingSensorModule);
|
||||
else if (dmc.startsWith(QLatin1String("KAA")))
|
||||
asset.mountingPointTypeId(MountingPointType_def::OutdoorCamera);
|
||||
else if (dmc.startsWith(QLatin1String("KAI")))
|
||||
asset.mountingPointTypeId(MountingPointType_def::IndoorCamera);
|
||||
else if (dmc.startsWith(QLatin1String("OPS")))
|
||||
asset.mountingPointTypeId(MountingPointType_def::IndoorIPS);
|
||||
else if (dmc.startsWith(QLatin1String("WD_")))
|
||||
asset.mountingPointTypeId(MountingPointType_def::EffectGenerationControlUnit);
|
||||
else
|
||||
{
|
||||
if (bOk)
|
||||
*bOk = false;
|
||||
WARNING_LOG(m_logger) << "Could not determine mounting point type from barcode: " << dmc.toString();
|
||||
}
|
||||
|
||||
return asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::updateInstrumentationAsset
|
||||
* compares the name and the mountingPointTypeId of given InstrumentationAsset asset with the ones of every InstrumentationAsset that
|
||||
* is already present in the model and if it is found, it is gonna update.
|
||||
* @param asset InstrumentationAsset.
|
||||
* @return true on found and updated, false on unlocated.
|
||||
*/
|
||||
bool AssetListDialog::updateInstrumentationAsset(const InstrumentationAsset &asset) const
|
||||
{
|
||||
InstrumentationAsset ia = asset;
|
||||
int rowCount = m_model->rowCount();
|
||||
for (int i = 0; i < rowCount; ++i)
|
||||
{
|
||||
InstrumentationAsset iaModelSide = m_model->getRowData(i);
|
||||
if ((iaModelSide.name() == ia.name()) &&
|
||||
(iaModelSide.mountingPointTypeId() == ia.mountingPointTypeId()))
|
||||
{
|
||||
ia.id(iaModelSide.id());
|
||||
QHash<int, bool> alteredCells;
|
||||
QHash<int, QString> alteredValues;
|
||||
|
||||
// NAME
|
||||
if (ia.name() != iaModelSide.name())
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::NAME, true);
|
||||
alteredValues.insert(AssetListDialogModel::NAME, m_model->data(m_model->index(i, AssetListDialogModel::NAME), Qt::DisplayRole).toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::NAME, false);
|
||||
alteredValues.insert(AssetListDialogModel::NAME, QString::fromStdString(ia.name()));
|
||||
}
|
||||
|
||||
// TYPE
|
||||
if (ia.mountingPointTypeId() != iaModelSide.mountingPointTypeId())
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::TYPE, true);
|
||||
alteredValues.insert(AssetListDialogModel::TYPE, m_model->data(m_model->index(i, AssetListDialogModel::TYPE), Qt::DisplayRole).toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::TYPE, false);
|
||||
alteredValues.insert(AssetListDialogModel::TYPE, QString::fromStdString(ia.name()));
|
||||
}
|
||||
|
||||
// BARCODE
|
||||
if (ia.barcode() != iaModelSide.barcode())
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::BARCODE, true);
|
||||
alteredValues.insert(AssetListDialogModel::BARCODE, m_model->data(m_model->index(i, AssetListDialogModel::BARCODE), Qt::DisplayRole).toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::BARCODE, false);
|
||||
alteredValues.insert(AssetListDialogModel::BARCODE, QString::fromStdString(ia.name()));
|
||||
}
|
||||
|
||||
// HOSTNAME
|
||||
if (ia.hostname() != iaModelSide.hostname())
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::HOSTNAME, true);
|
||||
alteredValues.insert(AssetListDialogModel::HOSTNAME, m_model->data(m_model->index(i, AssetListDialogModel::HOSTNAME), Qt::DisplayRole).toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::HOSTNAME, false);
|
||||
alteredValues.insert(AssetListDialogModel::HOSTNAME, QString::fromStdString(ia.name()));
|
||||
}
|
||||
|
||||
// PROPERTIES
|
||||
if (ia.properties() != iaModelSide.properties())
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::PROPERTIES, true);
|
||||
alteredValues.insert(AssetListDialogModel::PROPERTIES, m_model->data(m_model->index(i, AssetListDialogModel::PROPERTIES), Qt::DisplayRole).toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
alteredCells.insert(AssetListDialogModel::PROPERTIES, false);
|
||||
alteredValues.insert(AssetListDialogModel::PROPERTIES, QString::fromStdString(ia.name()));
|
||||
}
|
||||
|
||||
m_model->setAlteredCells(i, alteredCells);
|
||||
// for(const int col : m_model->previousValues(i).keys())
|
||||
// alteredValues.insert(col, m_model->data(m_model->index(i, col), Qt::DisplayRole).toString());
|
||||
m_model->setPreviousValues(i, alteredValues);
|
||||
ia.assetStateId(iaModelSide.assetStateId());
|
||||
ia.lastUpdated(iaModelSide == ia ? iaModelSide.lastUpdated() : QDateTime::currentMSecsSinceEpoch());
|
||||
m_model->setRowData(i, ia);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::onSelectionChanged
|
||||
* is called on selection-change of the listview.
|
||||
* @param selected a list of all selected items; unused.
|
||||
* @param deselected a list of all deselected items; unused.
|
||||
*/
|
||||
void AssetListDialog::onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
|
||||
{
|
||||
Q_UNUSED(selected);
|
||||
Q_UNUSED(deselected);
|
||||
|
||||
bool enabled = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SystemConfiguration);
|
||||
if (m_ui->assetListView->selectionModel()->selectedRows().size() < 1)
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_ui->assetListView->selectionModel()->selectedRows().size() == 1)
|
||||
{
|
||||
InstrumentationAsset asset = m_model->assetByIndex(m_ui->assetListView->currentIndex());
|
||||
StructureElement se;
|
||||
if(m_dtc->getStructureElementInMntPointAssetByAssetId(asset.id(), se) && enabled)
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enabled)
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(true);
|
||||
}
|
||||
if (enabled)
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool AssetListDialog::init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ComponentMonitor::Interface::Dtc> cmoDtc,
|
||||
const std::shared_ptr<ComponentMonitor::Interface::Ftc> cmoFtc
|
||||
)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
m_cmoDtc = cmoDtc;
|
||||
m_cmoFtc = cmoFtc;
|
||||
|
||||
if (!m_ftc->enableStructureElementModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT StructureElementModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableMountingPointAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MountingPointAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
if (!m_ftc->enableMountingPointAssetRemove())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MountingPointAssetRemove of ISM";
|
||||
return false;
|
||||
}
|
||||
if (!m_ftc->enableInstrumentationAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT InstrumentationAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
if (!m_ftc->enableInstrumentationAssetUnmount())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT InstrumentationAssetUnmount of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_cmoFtc->enableTriggerUpdate())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT TriggerUpdate of CMO";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_ftc->enableInstrumentationAssetSetState() == false)
|
||||
{
|
||||
ERROR_LOG(m_logger)<<"Couldn't enable InstrumentationAssetSetState";
|
||||
return false;
|
||||
}
|
||||
|
||||
delete m_model;
|
||||
m_model = new AssetListDialogModel(this);
|
||||
|
||||
connect(m_model, &AssetListDialogModel::dataAvailable, this, &AssetListDialog::enaDisaBtnBoxBtns);
|
||||
|
||||
if (!m_model->initModel(m_dtc, m_cmoDtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ui->assetListView->setModel(m_model);
|
||||
m_ui->assetListView->setSelectionMode(QAbstractItemView::SelectionMode::ExtendedSelection);
|
||||
|
||||
// connect(m_ui->assetListView, &LtsDataView::LtsDataView::signalDoubleClicked,
|
||||
// this, &AssetListDialog::onItemDoubleClicked);
|
||||
connect(m_ui->assetListView, &LtsDataView::LtsDataView::selectionChanged,
|
||||
this, &AssetListDialog::onSelectionChanged);
|
||||
connect(m_requestHelper, &LtsUtils::RequestHelper::signalQuitLoop, m_model, [this]()
|
||||
{
|
||||
m_model->initModel(m_dtc, m_cmoDtc);
|
||||
});
|
||||
|
||||
// delay trigger update buttonbox to void multiple calls
|
||||
m_updateBtnBoxBtns = new QTimer(this);
|
||||
m_updateBtnBoxBtns->setSingleShot(true);
|
||||
m_updateBtnBoxBtns->setInterval(1000);
|
||||
connect(m_updateBtnBoxBtns, &QTimer::timeout, this, &AssetListDialog::onInstrumentationAssetChanged);
|
||||
connect(m_dtc.get(), &Interface::Dtc::instrumentationAssetChanged,
|
||||
this, [&]{ m_updateBtnBoxBtns->start(); }, Qt::UniqueConnection);
|
||||
|
||||
//
|
||||
// ContextMen
|
||||
m_actionMenu = new QMenu(this);
|
||||
m_updateAction = new QAction(tr("Trigger Reachability Update"), this);
|
||||
m_actionMenu->addAction(m_updateAction);
|
||||
connect(m_updateAction, &QAction::triggered, this, &AssetListDialog::onReachabilityUpdateAction);
|
||||
|
||||
m_ui->assetListView->setContextMenuPolicyPerView(LtsDataView::LtsDataView::Page::TABLE, Qt::CustomContextMenu);
|
||||
connect(m_ui->assetListView, &LtsDataView::LtsDataView::signalContextMenuRequested,
|
||||
this, &AssetListDialog::onCustomContextMenuRequested);
|
||||
|
||||
if (!m_hostsForUpdateNotifiy)
|
||||
{
|
||||
m_hostsForUpdateNotifiy = new QTimer(this);
|
||||
m_hostsForUpdateNotifiy->setSingleShot(true);
|
||||
m_hostsForUpdateNotifiy->setInterval(1000);
|
||||
connect(m_hostsForUpdateNotifiy, &QTimer::timeout,
|
||||
this, &AssetListDialog::onHostsForUpdateNotifyTimeout);
|
||||
}
|
||||
|
||||
// ButtonBox
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SystemConfiguration))
|
||||
{
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &AssetListDialog::onUnmountButtonClicked);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Unmount"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(false);
|
||||
m_buttonBox->setIcon(LtsWidgets::DialogButton::Load, QIcon(QLatin1String("icon:fixed_video_announcement.svg")));
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &AssetListDialog::onSetStateButtonClicked);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setText(tr("Set State"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Edit)->setEnabled(false);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Import, this, &AssetListDialog::onImportClicked);
|
||||
}
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Export, this, &AssetListDialog::onExportClicked);
|
||||
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->assetListView->hideColumn(AssetListDialogModel::Columns::ID);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssetListDialog::onSetStateButtonClicked()
|
||||
{
|
||||
const QModelIndexList indexList = m_ui->assetListView->selectedRows();
|
||||
if (indexList.isEmpty())
|
||||
return;
|
||||
|
||||
if(m_hasImportedAsset)
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Save imported assets first before changing state."),
|
||||
tr("Set Asset State"), LtsWidgets::Behaviour::Modal, LtsWidgets::Button::Yes);
|
||||
return;
|
||||
}
|
||||
|
||||
// const QString identifier = QStringLiteral("Assets: Set State");
|
||||
|
||||
|
||||
std::vector<InstrumentationAsset> assets;
|
||||
assets.reserve(indexList.size());
|
||||
for(QModelIndex index: qAsConst(indexList))
|
||||
{
|
||||
InstrumentationAsset asset = m_model->assetByIndex(index);
|
||||
assets.push_back(asset);
|
||||
}
|
||||
|
||||
QScopedPointer<EditAssetDialog> editAssetDialog (new EditAssetDialog(this, m_ftc, assets));
|
||||
editAssetDialog->exec();
|
||||
}
|
||||
|
||||
void AssetListDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->assetListView->treeView());
|
||||
}
|
||||
|
||||
void AssetListDialog::enaDisaBtnBoxBtns(const bool b)
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Export)->setEnabled(b);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Apply)->setEnabled(b);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(b);
|
||||
}
|
||||
|
||||
void AssetListDialog::onInstrumentationAssetChanged()
|
||||
{
|
||||
// refresh selection buttons
|
||||
onSelectionChanged(QItemSelection(), QItemSelection());
|
||||
}
|
||||
|
||||
bool AssetListDialog::rowContainsAlteredData(const QHash<int, bool> &data)
|
||||
{
|
||||
for (const bool b : data)
|
||||
{
|
||||
if (b)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::onImportClicked
|
||||
* is called by clicking on Import-button and inserts all InstrumentationAssets of a selected file.
|
||||
* @see onExportClicked()
|
||||
*/
|
||||
void AssetListDialog::onImportClicked()
|
||||
{
|
||||
QString fileName = QFileDialog::getOpenFileName(this, tr("Import"), QString(),
|
||||
tr("CSV-Files (*.csv)"));
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
|
||||
QFile file(fileName);
|
||||
|
||||
if (!file.open(QFile::ReadOnly))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Cannot open file '%1': %2").arg(file.fileName(), file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
in.setLocale(QLocale::c());
|
||||
// first get the header data
|
||||
QString header = in.readLine();
|
||||
Q_UNUSED(header);
|
||||
bool bOk;
|
||||
while (!in.atEnd())
|
||||
{
|
||||
const QString line = in.readLine();
|
||||
QVector<QStringRef> segments = line.splitRef(QLatin1Char(';'));
|
||||
if (segments.size() < 10)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Skipping line '" << line << "' - to few data";
|
||||
continue;
|
||||
}
|
||||
const InstrumentationAsset ia = importData(segments, &bOk);
|
||||
if (!bOk)
|
||||
continue;
|
||||
if (updateInstrumentationAsset(ia))
|
||||
continue;
|
||||
m_model->insertRow(ia, true);
|
||||
m_hasImportedAsset = true;
|
||||
|
||||
QHash<int, bool> alteredCells;
|
||||
for (int i = 0; i < segments.size(); ++i)
|
||||
alteredCells.insert(m_model->rowCount() - 1, true);
|
||||
m_model->setAlteredCells(m_model->rowCount() - 1, alteredCells);
|
||||
|
||||
QHash<int, QString> previousValues;
|
||||
for (int i = 0; i <= AssetListDialogModel::Columns::LAST_UPDATED; ++i)
|
||||
{
|
||||
QModelIndex idx = m_model->index(m_model->rowCount() - 1, i);
|
||||
previousValues[m_model->rowCount() - 1] = m_model->data(idx, Qt::DisplayRole).toString();
|
||||
}
|
||||
m_model->setPreviousValues(m_model->rowCount() - 1, previousValues);
|
||||
}
|
||||
file.close();
|
||||
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Export)->setEnabled(false);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Import)->setEnabled(false);
|
||||
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::onExportClicked
|
||||
* is called by clicking on the Export-button and opens a new window to set several filters
|
||||
* that decide which items are going to get exported.
|
||||
* @see onFilterSelected()
|
||||
* @see onImportClicked()
|
||||
*/
|
||||
void AssetListDialog::onExportClicked()
|
||||
{
|
||||
AssetFilterDialog *filterDialog = new AssetFilterDialog(m_model, this);
|
||||
if (!filterDialog->init(m_ui->assetListView->selectionModel()->selectedRows().size() > 0))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Unexpected error";
|
||||
return;
|
||||
}
|
||||
filterDialog->fillAssetComboBoxes();
|
||||
connect(filterDialog, &AssetFilterDialog::exportFilterSelected, this, &AssetListDialog::onFilterSelected);
|
||||
filterDialog->show();
|
||||
}
|
||||
|
||||
void AssetListDialog::onUnmountButtonClicked()
|
||||
{
|
||||
if (m_ui->assetListView->selectionModel()->selectedRows().size() < 1)
|
||||
return;
|
||||
|
||||
LtsWidgets::Button button = LtsWidgets::LtsMessageDialog::showMessage(
|
||||
this, tr("Do you really want to unmount selected asset(s)?"), tr("Unmount Assets"), LtsWidgets::Behaviour::Modal,
|
||||
{ LtsWidgets::Button::Yes, LtsWidgets::Button::No });
|
||||
|
||||
if (button == LtsWidgets::Button::Yes)
|
||||
{
|
||||
// get asset id of all selected assets;
|
||||
const QModelIndexList indexList = m_ui->assetListView->selectedRows();
|
||||
for(QModelIndex index: indexList)
|
||||
{
|
||||
InstrumentationAsset asset = m_model->assetByIndex(index);
|
||||
if(asset.id() > 0 )
|
||||
{
|
||||
StructureElement se;
|
||||
if(m_dtc->getStructureElementInMntPointAssetByAssetId(asset.id(), se) == false)
|
||||
{
|
||||
WARNING_LOG(m_logger)<<" asset not mounted. name: "<<asset.name()<< " id: "<<asset.id();
|
||||
continue;
|
||||
}
|
||||
InstrumentationAssetUnmountRequest req(asset.id());
|
||||
m_requestHelper->addRequest([req, this]()
|
||||
{
|
||||
return m_ftc->instrumentationAssetUnmountRequest(req, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
if(m_requestHelper->hasRequests() &&
|
||||
m_requestHelper->startRequests() == false)
|
||||
{
|
||||
ERROR_LOG(m_logger)<<" Couldn't unmount selected assets";
|
||||
}
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load,false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetListDialog::onFilterSelected
|
||||
* is called by clicking on the Ok-button in the filter window.
|
||||
* @param exp enum class, that informs about the selected filtering option.
|
||||
* @param type gives the selected type in case of filtering by specific type, otherwise it is empty and unused.
|
||||
* @see onExportClicked()
|
||||
*/
|
||||
void AssetListDialog::onFilterSelected(const AssetFilterDialog::Export &exp, const QString &type)
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(this, tr("Export"),
|
||||
QString(),
|
||||
tr("CSV-Files (*.csv)"));
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QFile::WriteOnly))
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Cannot save file '%1': %2").arg(file.fileName(),
|
||||
file.errorString()));
|
||||
return;
|
||||
}
|
||||
|
||||
QTextStream out(&file);
|
||||
out.setLocale(QLocale::c());
|
||||
|
||||
const QStringList headerNames = { QStringLiteral("Data Matrix Code"),
|
||||
QStringLiteral("TKZ"),
|
||||
QStringLiteral("SNr"),
|
||||
QStringLiteral("MAC"),
|
||||
QStringLiteral("Status"),
|
||||
QStringLiteral("Bauzustand"),
|
||||
QStringLiteral("UCATT Code"),
|
||||
QStringLiteral("Lautsprecher"),
|
||||
QStringLiteral("Mikrofon"),
|
||||
QStringLiteral("Vapix Protokoll"),
|
||||
QStringLiteral("Bentuzername"),
|
||||
QStringLiteral("Passwort"),
|
||||
QStringLiteral("Properties"),
|
||||
QStringLiteral("Last updated") };
|
||||
out << headerNames.join(QLatin1Char(';')) << "\n";
|
||||
|
||||
QVector<QString> vecStr;
|
||||
if (exp == AssetFilterDialog::Export::eSpecificType)
|
||||
vecStr = getExportString(exp, type);
|
||||
else
|
||||
vecStr = getExportString(exp);
|
||||
|
||||
for (int i = 0; i < vecStr.size(); ++i)
|
||||
{
|
||||
if (!vecStr.at(i).isEmpty())
|
||||
out << vecStr.at(i) << "\n";
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
void AssetListDialog::onCustomContextMenuRequested(const QPoint &globalPos, const QModelIndex &indexSrc)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, indexSrc" << indexSrc.row();
|
||||
if (!indexSrc.isValid())
|
||||
return;
|
||||
|
||||
if (!m_model || !m_updateAction)
|
||||
return;
|
||||
|
||||
m_updateAction->setEnabled(m_model->triggerUpdateRequestUseful(indexSrc));
|
||||
m_actionMenu->exec(globalPos);
|
||||
}
|
||||
|
||||
void AssetListDialog::onReachabilityUpdateAction()
|
||||
{
|
||||
const QModelIndexList &mil = m_ui->assetListView->selectedRows();
|
||||
QIcon icon;
|
||||
QString str;
|
||||
for (const QModelIndex &il : qAsConst(mil))
|
||||
{
|
||||
const InstrumentationAsset ia = m_model->getRowData(il.row());
|
||||
|
||||
bool bhasHostnameForTriggerUpdate = m_model->getReachable(ia, icon, str);
|
||||
if (bhasHostnameForTriggerUpdate)
|
||||
{
|
||||
m_hostsForUpdate.insert(QString::fromStdString(ia.hostname()));
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " trigger update for " << ia;
|
||||
}
|
||||
} // for
|
||||
|
||||
m_hostsForUpdateNotifiy->start(); // restart
|
||||
}
|
||||
|
||||
void AssetListDialog::onHostsForUpdateNotifyTimeout()
|
||||
{
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << " START, hostsForUpdate.size() = " << m_hostsForUpdate.size();
|
||||
|
||||
if (!m_cmoFtc)
|
||||
return;
|
||||
if (m_hostsForUpdate.isEmpty())
|
||||
return;
|
||||
|
||||
for (auto item : qAsConst(m_hostsForUpdate))
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " host = " << item;
|
||||
|
||||
// start request now and trigger update:
|
||||
std::vector<std::string> hostnameStd;
|
||||
hostnameStd.reserve(m_hostsForUpdate.size());
|
||||
for (const QString &item : qAsConst(m_hostsForUpdate))
|
||||
if( std::find(hostnameStd.begin(), hostnameStd.end(), item.toStdString()) == hostnameStd.end())
|
||||
hostnameStd.push_back(item.toStdString());
|
||||
|
||||
ComponentMonitor::TriggerUpdate request;
|
||||
request.hostnames(hostnameStd);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " TriggerUpdate - request = " << request;
|
||||
|
||||
m_requestHelper->addRequest([request, this]()
|
||||
{
|
||||
return m_cmoFtc->triggerUpdateRequest(request, this);
|
||||
});
|
||||
m_requestHelper->startRequests();
|
||||
|
||||
// cleanup in any case:
|
||||
m_hostsForUpdate.clear();
|
||||
}
|
||||
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetListDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <AssetList/ism_filter_asset_dialog.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <ComponentMonitor/cmo_data_plugin_interface.h>
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include "ism_edit_asset_dialog.h"
|
||||
#include <QSet>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AssetListDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class AssetListDialogModel;
|
||||
|
||||
class AssetListDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::InstrumentationAssetModifyReplyHandler
|
||||
, protected Interface::Ftc::InstrumentationAssetUnmountReplyHandler
|
||||
, protected Interface::Ftc::StructureElementModifyReplyHandler
|
||||
, protected Interface::Ftc::MountingPointAssetModifyReplyHandler
|
||||
, protected Interface::Ftc::MountingPointAssetRemoveReplyHandler
|
||||
, protected ComponentMonitor::Interface::Ftc::TriggerUpdateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AssetListDialog(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent = nullptr);
|
||||
~AssetListDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ComponentMonitor::Interface::Dtc> cmoDtc,
|
||||
const std::shared_ptr<ComponentMonitor::Interface::Ftc> cmoFtc);
|
||||
|
||||
void onInstrumentationAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onInstrumentationAssetUnmountReply(const Core::FunctionReplyObject &replyObject) override final {m_requestHelper->requestReply(replyObject);}
|
||||
|
||||
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
void onMountingPointAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onMountingPointAssetRemoveReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
// CMO:
|
||||
void onTriggerUpdateReply(const Core::FunctionReplyObject &reply) override final { m_requestHelper->requestReply(reply); }
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
void onSetStateButtonClicked();
|
||||
void onPrint();
|
||||
void onImportClicked();
|
||||
void onExportClicked();
|
||||
void onUnmountButtonClicked();
|
||||
void onSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
void onFilterSelected(const AssetFilterDialog::Export &exp, const QString &type = QString());
|
||||
void onCustomContextMenuRequested(const QPoint &globalPos, const QModelIndex &indexSrc);
|
||||
void onReachabilityUpdateAction();
|
||||
void onHostsForUpdateNotifyTimeout();
|
||||
void onInstrumentationAssetChanged();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
bool apply() override final;
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
QVector<QString> getExportString(const AssetFilterDialog::Export &exp, const QString &type = QString()) const;
|
||||
static QString exportData(const InstrumentationAsset &ia, const QString &separator = QLatin1String(";"));
|
||||
InstrumentationAsset importData(const QVector<QStringRef> &segments, bool *bOk) const;
|
||||
bool updateInstrumentationAsset(const InstrumentationAsset &asset) const;
|
||||
void enaDisaBtnBoxBtns(const bool b);
|
||||
static bool rowContainsAlteredData(const QHash<int, bool> &data);
|
||||
|
||||
EditAssetDialog *m_editAssetDialog{nullptr};
|
||||
LtsSession::LtsSession *m_session;
|
||||
AssetListDialogModel *m_model;
|
||||
QString m_menuGroup;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<ComponentMonitor::Interface::Dtc> m_cmoDtc; // CMO ComponentMonitor
|
||||
std::shared_ptr<ComponentMonitor::Interface::Ftc> m_cmoFtc; // CMO ComponentMonitor
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
Ui::AssetListDialog *m_ui;
|
||||
bool m_hasImportedAsset{false};
|
||||
|
||||
// CustomContextMenu
|
||||
QMenu *m_actionMenu{nullptr};
|
||||
QAction *m_updateAction{nullptr};
|
||||
QSet<QString> m_hostsForUpdate;
|
||||
QTimer *m_hostsForUpdateNotifiy{nullptr};
|
||||
QTimer *m_updateBtnBoxBtns{nullptr};
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class AssetListDialogModel
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AssetListDialog</class>
|
||||
<widget class="QWidget" name="AssetListDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Asset Stocks</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="LtsDataView::LtsDataView" name="assetListView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+499
@@ -0,0 +1,499 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetListDialogModel provices data for AssetListDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#include "ism_asset_list_dialog_model.h"
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <ComponentMonitor/cmo_data_plugin_interface.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
#include <QDateTime>
|
||||
#include <QBrush>
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
#include <QDebug>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
AssetListDialogModel::AssetListDialogModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<InstrumentationAsset>(
|
||||
{
|
||||
tr("Id"),
|
||||
tr("Name"),
|
||||
tr("Type"),
|
||||
tr("State"),
|
||||
tr("Reachability"),
|
||||
tr("Barcode"),
|
||||
tr("Hostname"),
|
||||
tr("Mounting point"),
|
||||
tr("Properties"),
|
||||
tr("Last updated")
|
||||
},
|
||||
parent)
|
||||
, m_dtc(nullptr)
|
||||
, m_reachabilityGreen(QLatin1String("icon:green_light.svg"))
|
||||
, m_reachabilityYellow(QLatin1String("icon:yellow_light.svg"))
|
||||
, m_reachabilityOrange(QLatin1String("icon:orange_light.svg"))
|
||||
, m_reachabilityRed(QLatin1String("icon:red_light.svg"))
|
||||
, m_alteredCells()
|
||||
, m_alteredValues()
|
||||
, m_updateFilterTimer(new QTimer(this))
|
||||
, m_logger(getLogger("AssetListDialogModel"))
|
||||
{
|
||||
m_intactStr = tr("Intact");
|
||||
updateFilterStates();
|
||||
updateFilterTypes();
|
||||
// // updateFilterReachability();
|
||||
m_updateFilterTimer->setInterval(100);
|
||||
m_updateFilterTimer->setSingleShot(true);
|
||||
connect(m_updateFilterTimer, &QTimer::timeout,
|
||||
this, &AssetListDialogModel::onUpdateFilter, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
QVariant AssetListDialogModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
{
|
||||
switch (section)
|
||||
{
|
||||
case TYPE:
|
||||
return m_cbxFilterType;
|
||||
case STATE:
|
||||
return m_cbxFilterState;
|
||||
case REACHABILITY:
|
||||
return m_cbxFilterReachability;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return LtsWidgets::LtsAbstractTableModel<InstrumentationAsset>::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QVariant AssetListDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole &&
|
||||
role != Qt::BackgroundRole &&
|
||||
role != Qt::ToolTipRole &&
|
||||
role != Qt::DecorationRole &&
|
||||
role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
|| !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const InstrumentationAsset ¤tAsset = m_vecData.at(index.row());
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case ID:
|
||||
return currentAsset.id();
|
||||
case NAME:
|
||||
return QString::fromStdString(currentAsset.name());
|
||||
case TYPE:
|
||||
return toString(currentAsset.mountingPointTypeId());
|
||||
case BARCODE:
|
||||
return QString::fromStdString(currentAsset.barcode());
|
||||
case HOSTNAME:
|
||||
return QString::fromStdString(currentAsset.hostname());
|
||||
case MOUNTINGPOINT:
|
||||
{
|
||||
StructureElement se;
|
||||
if (m_dtc->getStructureElementInMntPointAssetByAssetId(currentAsset.id(), se) && se.id() > 0 )
|
||||
{
|
||||
return QString::fromStdString(se.displayName());
|
||||
}
|
||||
else
|
||||
{
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
case PROPERTIES:
|
||||
return QString::fromStdString(currentAsset.properties());
|
||||
case STATE:
|
||||
{
|
||||
const InstrumentationAssetState_def::type &currAssetState = currentAsset.assetStateId().underlying();
|
||||
if(currAssetState == InstrumentationAssetState_def::Unmounted || currAssetState == InstrumentationAssetState_def::Mounted)
|
||||
{
|
||||
return m_intactStr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return toString(currentAsset.assetStateId());
|
||||
}
|
||||
//return toString(currentAsset.assetStateId());
|
||||
}
|
||||
case REACHABILITY:
|
||||
{
|
||||
QIcon icon;
|
||||
QString str;
|
||||
getReachable(currentAsset, icon, str);
|
||||
return str;
|
||||
}
|
||||
case LAST_UPDATED:
|
||||
return QDateTime::fromMSecsSinceEpoch(currentAsset.lastUpdated());
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (index.column() == REACHABILITY)
|
||||
{
|
||||
if (triggerUpdateRequestUseful(currentAsset))
|
||||
{
|
||||
return QDateTime::fromSecsSinceEpoch(m_reachabilityLastCheck[currentAsset.id()]);
|
||||
}
|
||||
}
|
||||
|
||||
const auto cont = m_alteredValues.value(index.row());
|
||||
if (!cont.value(index.column()).isEmpty())
|
||||
return tr("Previous: %1").arg(m_alteredValues.at(index.row()).value(index.column()));
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole)
|
||||
{
|
||||
const auto cont = m_alteredCells.value(index.row());
|
||||
if (cont.value(index.column()))
|
||||
return QBrush(QColor(Qt::red));
|
||||
}
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
if (index.column() == REACHABILITY)
|
||||
{
|
||||
QIcon icon;
|
||||
QString str;
|
||||
getReachable(currentAsset, icon, str);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
||||
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case TYPE:
|
||||
return currentAsset.mountingPointTypeId().underlying();
|
||||
case STATE:
|
||||
if(currentAsset.assetStateId().underlying() == InstrumentationAssetState::Mounted ||
|
||||
currentAsset.assetStateId().underlying() == InstrumentationAssetState::Unmounted)
|
||||
{
|
||||
return m_intactStr;
|
||||
}
|
||||
else
|
||||
return currentAsset.assetStateId().underlying();
|
||||
case REACHABILITY:
|
||||
{
|
||||
QIcon icon;
|
||||
QString str;
|
||||
const InstrumentationAsset &innerCurrentAsset = m_vecData.at(index.row());
|
||||
getReachable(innerCurrentAsset, icon, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
inline bool isMptRelevant(MountingPointType_def::type type)
|
||||
{
|
||||
return ((type == MountingPointType_def::IndoorCamera) ||
|
||||
(type == MountingPointType_def::OutdoorCamera) ||
|
||||
(type == MountingPointType_def::EffectGenerationControlUnit) ||
|
||||
(type == MountingPointType_def::BuildingSensorModule)
|
||||
);
|
||||
}
|
||||
|
||||
bool AssetListDialogModel::getReachable(const InstrumentationAsset ¤tAsset,
|
||||
QIcon &iconOut, QString &stringOut) const
|
||||
{
|
||||
bool bEnableTriggerUpdate = false;
|
||||
|
||||
const bool bIsRelevant = isMptRelevant(currentAsset.mountingPointTypeId().underlying());
|
||||
if (bIsRelevant)
|
||||
{
|
||||
const bool bIsMounted = currentAsset.assetStateId().underlying() == InfrastructureManagement::InstrumentationAssetState_def::Mounted;
|
||||
if (bIsMounted)
|
||||
{
|
||||
if (m_cmoDtc)
|
||||
{
|
||||
const ComponentMonitor::ComponentStatus &cs = m_cmoDtc->componentStatus(currentAsset.id());
|
||||
const ComponentMonitor::ComponentState state = cs.state();
|
||||
switch (state.underlying()) {
|
||||
case ComponentMonitor::ComponentState_def::Undefined:
|
||||
iconOut = m_reachabilityOrange;
|
||||
stringOut = tr("Undefined");
|
||||
break;
|
||||
case ComponentMonitor::ComponentState_def::Reachable:
|
||||
iconOut = m_reachabilityGreen;
|
||||
stringOut = tr("Reachable");
|
||||
break;
|
||||
case ComponentMonitor::ComponentState_def::Unreachable:
|
||||
iconOut = m_reachabilityRed;
|
||||
stringOut = tr("Unreachable");
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
}
|
||||
}
|
||||
bEnableTriggerUpdate = true;
|
||||
|
||||
} else {
|
||||
// GUEZE-1566: keine gelbe Ampel
|
||||
// iconOut = m_reachabilityYellow;
|
||||
// GUEZE-1566
|
||||
stringOut = QStringLiteral("-");
|
||||
}
|
||||
|
||||
} else { // if (bIsRelevant)
|
||||
// Icon stays empty
|
||||
iconOut = QIcon();
|
||||
stringOut = QStringLiteral("-");
|
||||
}
|
||||
return bEnableTriggerUpdate;
|
||||
}
|
||||
|
||||
bool AssetListDialogModel::triggerUpdateRequestUseful(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
|
||||
const InstrumentationAsset ¤tAsset = getRowData(index.row());
|
||||
return triggerUpdateRequestUseful(currentAsset);
|
||||
}
|
||||
|
||||
bool AssetListDialogModel::triggerUpdateRequestUseful(const InstrumentationAsset ¤tAsset) const
|
||||
{
|
||||
// GUEZE-1490:
|
||||
static QString dummyStr;
|
||||
static QIcon dummyIcon;
|
||||
bool bEnableTriggerUpdate = getReachable(currentAsset, dummyIcon, dummyStr);
|
||||
|
||||
return bEnableTriggerUpdate;
|
||||
}
|
||||
|
||||
void AssetListDialogModel::onUpdateFilter()
|
||||
{
|
||||
// // updateFilterStates content does not change
|
||||
updateFilterTypes();
|
||||
updateFilterReachability();
|
||||
}
|
||||
|
||||
void AssetListDialogModel::onComponentStatusChanged(const ComponentMonitor::ComponentStatus &data, DataModification modType)
|
||||
{
|
||||
// handle eRemoved also
|
||||
Q_UNUSED(modType);
|
||||
|
||||
const int row = findRowForId(data.id()); // ComponentStatus.id == InstrumentationAsset.id
|
||||
if (row < 0)
|
||||
return;
|
||||
|
||||
// For Tooltip:
|
||||
m_reachabilityLastCheck[data.id()] = data.last_check();
|
||||
|
||||
const auto idx(index(row, REACHABILITY));
|
||||
emit dataChanged(idx, idx, {Qt::DisplayRole, Qt::BackgroundRole, Qt::DecorationRole, Qt::ToolTipRole});
|
||||
|
||||
m_updateFilterTimer->start();
|
||||
}
|
||||
|
||||
|
||||
bool AssetListDialogModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ComponentMonitor::Interface::Dtc> &cmoDtc)
|
||||
{
|
||||
m_dtc = dtc;
|
||||
m_cmoDtc = cmoDtc;
|
||||
|
||||
if (!m_dtc->enableInstrumentationAsset())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Datatopic InstrumentationAsset of the Data Topic Client";
|
||||
return false;
|
||||
}
|
||||
if (!m_cmoDtc->enableComponentStatus())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Datatopic enableComponentStatus of cmo";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
disconnect(m_dtc.get(), &Interface::Dtc::instrumentationAssetChanged, this, &AssetListDialogModel::onDataChanged);
|
||||
clear();
|
||||
m_vecData.clear();
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::instrumentationAssetChanged,
|
||||
this, &AssetListDialogModel::onDataChanged);
|
||||
auto cb = [this](const InfrastructureManagement::InstrumentationAsset & data)
|
||||
{
|
||||
// avoid display information of following mountinhPointTypes
|
||||
if(data.mountingPointTypeId() == MountingPointType::MeteoDataUnit ||
|
||||
data.mountingPointTypeId() == MountingPointType::BuildingControlUnit /*||
|
||||
data.mountingPointTypeId() == MountingPointType::OutdoorIPS */)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
insertRow(data, true);
|
||||
QHash<int, bool> alteredCells;
|
||||
for (int i = 0; i <= LAST_UPDATED; ++i)
|
||||
alteredCells.insert(i, false);
|
||||
m_alteredCells.append(alteredCells);
|
||||
|
||||
QHash<int, QString> previousValues;
|
||||
for (int i = 0; i <= LAST_UPDATED; ++i)
|
||||
previousValues[i] = QString();
|
||||
m_alteredValues.append(previousValues);
|
||||
};
|
||||
m_dtc->instrumentationAssets(cb);
|
||||
emit dataAvailable(m_vecData.size() > 0);
|
||||
|
||||
if (m_cmoDtc)
|
||||
{
|
||||
connect(m_cmoDtc.get(), &ComponentMonitor::Interface::Dtc::componentStatusChanged,
|
||||
this, &AssetListDialogModel::onComponentStatusChanged, Qt::UniqueConnection);
|
||||
auto compStatCb = [this](const ComponentMonitor::ComponentStatus &data)
|
||||
{
|
||||
onComponentStatusChanged(data, DataModification::eAdded);
|
||||
};
|
||||
m_cmoDtc->componentStatuss(compStatCb);
|
||||
}
|
||||
|
||||
connect(this, &AssetListDialogModel::rowsInserted, this, &AssetListDialogModel::onUpdateFilter);
|
||||
connect(this, &AssetListDialogModel::rowsRemoved, this, &AssetListDialogModel::onUpdateFilter);
|
||||
connect(this, &AssetListDialogModel::modelReset, this, &AssetListDialogModel::onUpdateFilter);
|
||||
onUpdateFilter();
|
||||
|
||||
INFO_LOG(m_logger) << "initModel successfull";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
InstrumentationAsset AssetListDialogModel::assetByIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return InstrumentationAsset();
|
||||
return getRowData(index.row());
|
||||
}
|
||||
|
||||
void AssetListDialogModel::insertRow(const InstrumentationAsset &asset, bool b)
|
||||
{
|
||||
Q_UNUSED(b);
|
||||
LtsWidgets::LtsAbstractTableModel<InstrumentationAsset>::insertRow(asset);
|
||||
m_alteredCells.resize(rowCount());
|
||||
}
|
||||
|
||||
void AssetListDialogModel::setAlteredCells(const int row, const QHash<int, bool> &data)
|
||||
{
|
||||
if (data.isEmpty() || row < 0 || row >= m_alteredCells.size())
|
||||
return;
|
||||
m_alteredCells[row] = data;
|
||||
}
|
||||
|
||||
void AssetListDialogModel::removeBackgroundHighlighting()
|
||||
{
|
||||
for (int i = 0; i < this->rowCount(); ++i)
|
||||
{
|
||||
for (int j = 0; j < this->columnCount(); ++j)
|
||||
m_alteredCells[i].insert(j, false);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetListDialogModel::updateFilterStates()
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
const auto states = {
|
||||
InstrumentationAssetState::Mounted,
|
||||
//InstrumentationAssetState::Unmounted, // mounted and unmounted will are displayed as "intact" in asset list dialog
|
||||
InstrumentationAssetState::Defect,
|
||||
};
|
||||
for (const auto es : states)
|
||||
{
|
||||
if(es == InstrumentationAssetState::Mounted ||
|
||||
es == InstrumentationAssetState::Unmounted)
|
||||
{
|
||||
cfd.data = m_intactStr;
|
||||
cfd.text = m_intactStr;
|
||||
}
|
||||
else
|
||||
{
|
||||
cfd.data = es;
|
||||
cfd.text = toString(es);
|
||||
}
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = false;
|
||||
m_cbxFilterState = cfc.toVariant();
|
||||
}
|
||||
|
||||
void AssetListDialogModel::updateFilterTypes()
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
QSet<InfrastructureManagement::MountingPointType> types;
|
||||
for (const auto &r : qAsConst(m_vecData))
|
||||
types.insert(r.mountingPointTypeId());
|
||||
|
||||
for (const auto es : qAsConst(types))
|
||||
{
|
||||
if(es == MountingPointType::MeteoDataUnit ||
|
||||
es == MountingPointType::BuildingControlUnit /*||
|
||||
es == MountingPointType::OutdoorIPS*/ )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cfd.data = es.underlying();
|
||||
cfd.text = toString(es);
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = true;
|
||||
m_cbxFilterType = cfc.toVariant();
|
||||
}
|
||||
|
||||
void AssetListDialogModel::updateFilterReachability()
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
|
||||
QMap<QString, QIcon> values;
|
||||
for (const auto &item : qAsConst(m_vecData))
|
||||
{
|
||||
QIcon icon;
|
||||
QString str;
|
||||
getReachable(item, icon, str);
|
||||
values.insert(str, icon);
|
||||
}
|
||||
|
||||
QMapIterator<QString, QIcon> it(values);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
cfd.data = it.key();
|
||||
cfd.text = it.key();
|
||||
cfd.icon = it.value();
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
// for (const QPair<QIcon, QString> &val : qAsConst(values))
|
||||
// {
|
||||
// cfd.data = val.first;
|
||||
// cfd.text = val.first;
|
||||
// cfd.icon = val.second;
|
||||
// cfc.data.push_back(cfd);
|
||||
// }
|
||||
cfc.sortItems = true;
|
||||
m_cbxFilterReachability = cfc.toVariant();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+91
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetListDialogModel provices data for AssetListDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <ComponentMonitor/cmo_data_plugin_interface.h>
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class AssetListDialogModel final : public LtsWidgets::LtsAbstractTableModel<InstrumentationAsset>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AssetListDialogModel(QObject *parent = nullptr);
|
||||
|
||||
enum Columns
|
||||
{
|
||||
ID = 0,
|
||||
NAME,
|
||||
TYPE,
|
||||
STATE,
|
||||
REACHABILITY,
|
||||
BARCODE,
|
||||
HOSTNAME,
|
||||
MOUNTINGPOINT,
|
||||
PROPERTIES,
|
||||
LAST_UPDATED
|
||||
};
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ComponentMonitor::Interface::Dtc> &cmoDtc);
|
||||
InstrumentationAsset assetByIndex(const QModelIndex &index) const;
|
||||
QVector<QHash<int, bool>> alteredRows() const { return m_alteredCells; }
|
||||
void setAlteredCells(const int row, const QHash<int, bool> &data);
|
||||
QHash<int, QString> previousValues(const int row) const { return m_alteredValues[row]; }
|
||||
void setPreviousValues(const int row, const QHash<int, QString> &value) { m_alteredValues.insert(row, value); }
|
||||
void removeBackgroundHighlighting();
|
||||
|
||||
void insertRow(const InstrumentationAsset &asset, bool b);
|
||||
|
||||
void updateFilterStates();
|
||||
void updateFilterTypes();
|
||||
void updateFilterReachability();
|
||||
|
||||
bool getReachable(const InstrumentationAsset ¤tAsset,
|
||||
QIcon &iconOut, QString &stringOut) const;
|
||||
|
||||
bool triggerUpdateRequestUseful(const QModelIndex &index) const;
|
||||
bool triggerUpdateRequestUseful(const InstrumentationAsset ¤tAsset) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onUpdateFilter();
|
||||
void onComponentStatusChanged(const ComponentMonitor::ComponentStatus &data, DataModification modType);
|
||||
|
||||
signals:
|
||||
void dataAvailable(bool b);
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<ComponentMonitor::Interface::Dtc> m_cmoDtc; // CMO ComponentMonitor
|
||||
|
||||
QIcon m_reachabilityGreen;
|
||||
QIcon m_reachabilityYellow;
|
||||
QIcon m_reachabilityOrange;
|
||||
QIcon m_reachabilityRed;
|
||||
|
||||
|
||||
QVector<QHash<int, bool>> m_alteredCells;
|
||||
QVector<QHash<int, QString>> m_alteredValues;
|
||||
QVariant m_cbxFilterType;
|
||||
QVariant m_cbxFilterState;
|
||||
QVariant m_cbxFilterReachability;
|
||||
QHash<int, long long> m_reachabilityLastCheck; // SECONDS since Epoch
|
||||
QTimer *m_updateFilterTimer{nullptr};
|
||||
QString m_intactStr;
|
||||
LOGGER_T m_logger;
|
||||
}; // class AssetListDialogModel
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditAssetDialog offers an UI to edit the attributes of an instrumentaion asset
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-16
|
||||
*/
|
||||
|
||||
#include "ism_edit_asset_dialog.h"
|
||||
#include "ui_ism_edit_asset_dialog.h"
|
||||
#include "ism_set_properties_dialog.h"
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
/*!
|
||||
* \brief EditAssetDialog::EditAssetDialog
|
||||
* \param parent
|
||||
* \param ftc
|
||||
* \param assets
|
||||
*/
|
||||
EditAssetDialog::EditAssetDialog(QWidget *parent, const std::shared_ptr<Interface::Ftc> &ftc, const std::vector<InstrumentationAsset> &assets)
|
||||
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
|
||||
, m_ui(new Ui::EditAssetDialog)
|
||||
, m_ftc(ftc)
|
||||
, m_asset(assets)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("EditAssetDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
for(auto const &asset: assets)
|
||||
{
|
||||
m_ui->listWidget->addItem(QString::fromStdString(asset.name()));
|
||||
}
|
||||
connect(m_ui->toIntactBtn, &QPushButton::clicked, this, &EditAssetDialog::slotSetAssetToIntact);
|
||||
connect(m_ui->toDefectBtn, &QPushButton::clicked, this, &EditAssetDialog::slotSetAssetToDefect);
|
||||
connect(m_ui->cancelBtn, &QPushButton::clicked, this, &EditAssetDialog::slotClose);
|
||||
}
|
||||
/*!
|
||||
* \brief EditAssetDialog::~EditAssetDialog
|
||||
*/
|
||||
EditAssetDialog::~EditAssetDialog()
|
||||
{
|
||||
delete m_requestHelper;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief EditAssetDialog::slotSetAssetToIntact
|
||||
* Setting the asset state to 'Intact' means setting the state to umounted
|
||||
*/
|
||||
void EditAssetDialog::slotSetAssetToIntact()
|
||||
{
|
||||
const InstrumentationAssetState newState = InstrumentationAssetState::type::Unmounted;
|
||||
apply(newState);
|
||||
slotClose();
|
||||
}
|
||||
/*!
|
||||
* \brief EditAssetDialog::slotSetAssetToDefect
|
||||
* Setting the asset state to 'defect' => asset will be unmounted and state will be set to defect
|
||||
*/
|
||||
void EditAssetDialog::slotSetAssetToDefect()
|
||||
{
|
||||
const InstrumentationAssetState newState = InstrumentationAssetState::type::Defect;
|
||||
apply(newState);
|
||||
slotClose();
|
||||
|
||||
}
|
||||
/*!
|
||||
* \brief EditAssetDialog::slotClose
|
||||
* this Method close the modal dialog
|
||||
*/
|
||||
void EditAssetDialog::slotClose()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* \brief EditAssetDialog::apply
|
||||
* Apply the defined state to selected assets
|
||||
* \param newState
|
||||
* \return
|
||||
*/
|
||||
bool EditAssetDialog::apply(const InstrumentationAssetState newState)
|
||||
{
|
||||
const QString stateStr = (newState==InstrumentationAssetState::Mounted || newState==InstrumentationAssetState::Unmounted) ? tr("Intact") : tr("Defect");
|
||||
LtsWidgets::Button button = LtsWidgets::LtsMessageDialog::showMessage(
|
||||
this, tr(""), tr("Do you really want to apply \"%1\" state ?").arg(stateStr), LtsWidgets::Behaviour::Modal,
|
||||
{ LtsWidgets::Button::Yes, LtsWidgets::Button::No }
|
||||
);
|
||||
if (button == LtsWidgets::Button::Yes)
|
||||
{
|
||||
InstrumentationAssetSetStateRequest req;
|
||||
|
||||
for(const auto &asset : qAsConst(m_asset))
|
||||
{
|
||||
if (asset.id() == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (asset.assetStateId() == newState)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// if state is mounted or unmounted and the aim state is intact nothing will be done
|
||||
if (((asset.assetStateId() == InstrumentationAssetState::Mounted) || (asset.assetStateId() == InstrumentationAssetState::Unmounted)) &&
|
||||
(newState == InstrumentationAssetState::Unmounted)) // state intact
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
req.id(asset.id());
|
||||
req.instrumentationAssetStateId(newState);
|
||||
m_requestHelper->addRequest([req, this]()
|
||||
{
|
||||
return m_ftc->instrumentationAssetSetStateRequest(req, this);
|
||||
});
|
||||
}
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditAssetDialog offers an UI to edit the attributes of an instrumentaion asset
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-16
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsProgressDialogHelper;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EditAssetDialog;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class EditAssetDialog
|
||||
: public LtsWidgets::LtsFramelessDialog
|
||||
, protected Interface::Ftc::InstrumentationAssetModifyReplyHandler
|
||||
, protected Interface::Ftc::InstrumentationAssetSetStateReplyHandler
|
||||
, protected Interface::Ftc::StructureElementModifyReplyHandler
|
||||
, protected Interface::Ftc::InstrumentationAssetRemoveReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EditAssetDialog(QWidget *parent,const std::shared_ptr<Interface::Ftc> &ftc, const std::vector<InstrumentationAsset> &assets);
|
||||
~EditAssetDialog();
|
||||
|
||||
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onInstrumentationAssetRemoveReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onInstrumentationAssetSetStateReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
void onInstrumentationAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final { m_requestHelper->requestReply(replyObject); }
|
||||
|
||||
private slots:
|
||||
void slotSetAssetToIntact();
|
||||
void slotSetAssetToDefect();
|
||||
void slotClose();
|
||||
private:
|
||||
bool apply(const InstrumentationAssetState newState) ;
|
||||
|
||||
Ui::EditAssetDialog *m_ui;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::vector<InstrumentationAsset> m_asset;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class EditAssetDialog
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditAssetDialog</class>
|
||||
<widget class="QWidget" name="EditAssetDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>414</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Set Asset State</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Set State for following Assets:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QListWidget" name="listWidget">
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QPushButton" name="toIntactBtn">
|
||||
<property name="text">
|
||||
<string>to Intact</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toDefectBtn">
|
||||
<property name="text">
|
||||
<string>to Defect</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelBtn">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+101
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetFilterDialog shows options to export items, filtering items by certain criteria
|
||||
* $Id: ism_asset_list_dialog.h 37724 2017-12-07 11:54:11Z bueltel $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/InfrastructureManagement/Gui/ResourceManagement/AssetList/ism_asset_list_dialog.h $
|
||||
* $Author: bueltel $
|
||||
* Created by Malte Schroeder, NLSE, 2018-06-16
|
||||
*/
|
||||
|
||||
#include "ism_filter_asset_dialog.h"
|
||||
#include "ui_ism_filter_asset_dialog.h"
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
/**
|
||||
* @brief AssetFilterDialog::AssetFilterDialog
|
||||
* The AssetFilterDialog shows options to export items, filtering items by certain criteria
|
||||
* @param model
|
||||
* @param parent
|
||||
*/
|
||||
AssetFilterDialog::AssetFilterDialog(AssetListDialogModel *model, QWidget *parent)
|
||||
: LtsWidgets::LtsFramelessDialog(parent)
|
||||
, m_model(model)
|
||||
, m_ui(new Ui::AssetFilterDialog)
|
||||
, m_logger(getLogger("AssetFilterDialog"))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose, true);
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
AssetFilterDialog::~AssetFilterDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool AssetFilterDialog::init(bool selectedItems)
|
||||
{
|
||||
m_ui->buttonBox->setButtonVisible(LtsWidgets::DialogButton::Ok);
|
||||
m_ui->buttonBox->setButtonVisible(LtsWidgets::DialogButton::Close);
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(false);
|
||||
|
||||
m_ui->rbSelectedItems->setEnabled(selectedItems);
|
||||
m_ui->cmbType->setEnabled(false);
|
||||
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &AssetFilterDialog::onPbOk);
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &AssetFilterDialog::close);
|
||||
connect(m_ui->rbAll, &QRadioButton::toggled, this, &AssetFilterDialog::onRbToggled);
|
||||
connect(m_ui->rbSelectedItems, &QRadioButton::toggled, this, &AssetFilterDialog::onRbToggled);
|
||||
connect(m_ui->rbType, &QRadioButton::toggled, this, &AssetFilterDialog::onRbToggled);
|
||||
connect(m_ui->cmbType, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged), this, [ = ]()
|
||||
{
|
||||
onRbToggled (m_ui->cmbType->currentIndex() != 0 && m_ui->rbType->isChecked());
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AssetFilterDialog::fillAssetComboBoxes
|
||||
* examines every row of the model and inserts the types onefold in the combobox
|
||||
*/
|
||||
void AssetFilterDialog::fillAssetComboBoxes()
|
||||
{
|
||||
QSet<InfrastructureManagement::MountingPointType> types;
|
||||
types.reserve(20);
|
||||
for (int i = 0; i < m_model->rowCount(); ++i)
|
||||
types += m_model->getRowData(i).mountingPointTypeId();
|
||||
|
||||
m_ui->cmbType->addItem(QLatin1String("---"));
|
||||
for (const auto &type : qAsConst(types))
|
||||
m_ui->cmbType->addItem(InfrastructureManagement::toString(type), type.underlying());
|
||||
m_ui->cmbType->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void AssetFilterDialog::onPbOk()
|
||||
{
|
||||
if (m_ui->rbAll->isChecked())
|
||||
emit exportFilterSelected(Export::eAll);
|
||||
else if (m_ui->rbSelectedItems->isChecked())
|
||||
emit exportFilterSelected(Export::eSelected);
|
||||
else if (m_ui->rbType->isChecked())
|
||||
emit exportFilterSelected(Export::eSpecificType, m_ui->cmbType->currentText());
|
||||
}
|
||||
|
||||
void AssetFilterDialog::onRbToggled(bool b)
|
||||
{
|
||||
if (m_ui->rbAll->isChecked() ||
|
||||
m_ui->rbSelectedItems->isChecked() ||
|
||||
m_ui->rbType->isChecked())
|
||||
{
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(b);
|
||||
if (m_ui->rbType->isChecked() && m_ui->cmbType->currentIndex() == 0)
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(false);
|
||||
|
||||
m_ui->cmbType->setEnabled(m_ui->rbType->isChecked());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetFilterDialog shows options to export items, filtering items by certain criteria
|
||||
* $Id: ism_asset_list_dialog.h 37724 2017-12-07 11:54:11Z bueltel $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/InfrastructureManagement/Gui/ResourceManagement/AssetList/ism_asset_list_dialog.h $
|
||||
* $Author: bueltel $
|
||||
* Created by Malte Schroeder, NLSE, 2018-06-16
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ism_asset_list_dialog_model.h"
|
||||
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <LtsWidgets/lts_combo_box.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class AssetFilterDialog;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class AssetFilterDialog : public LtsWidgets::LtsFramelessDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AssetFilterDialog(AssetListDialogModel *model, QWidget *parent = nullptr);
|
||||
~AssetFilterDialog();
|
||||
bool init(bool selectedItems);
|
||||
void fillAssetComboBoxes();
|
||||
|
||||
enum class Export
|
||||
{
|
||||
eAll,
|
||||
eSelected,
|
||||
eSpecificType
|
||||
};
|
||||
|
||||
signals:
|
||||
void exportFilterSelected(const Export &ex, const QString &type = QString());
|
||||
|
||||
private slots:
|
||||
void onPbOk();
|
||||
void onRbToggled(bool b);
|
||||
|
||||
private:
|
||||
AssetListDialogModel *m_model;
|
||||
Ui::AssetFilterDialog *m_ui;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
Executable
+67
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AssetFilterDialog</class>
|
||||
<widget class="LtsWidgets::LtsFramelessDialog" name="AssetFilterDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>363</width>
|
||||
<height>144</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="4" column="1">
|
||||
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QRadioButton" name="rbType">
|
||||
<property name="text">
|
||||
<string>Specific Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cmbType"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QRadioButton" name="rbAll">
|
||||
<property name="text">
|
||||
<string>All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QRadioButton" name="rbSelectedItems">
|
||||
<property name="text">
|
||||
<string>Selected Ite&ms</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDialogButtonBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_dialog_button_box.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsFramelessDialog</class>
|
||||
<extends>QDialog</extends>
|
||||
<header>LtsWidgets/lts_frameless_dialog.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+163
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The SetPropertiesDialog offers an UI to edit the properties of an instrumentation asset
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-16
|
||||
*/
|
||||
|
||||
#include "ism_set_properties_dialog.h"
|
||||
#include "ui_ism_set_properties_dialog.h"
|
||||
|
||||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QLabel>
|
||||
#include <QtWidgets/QHBoxLayout>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
using namespace InfrastructureManagement;
|
||||
|
||||
SetPropertiesDialog::SetPropertiesDialog(QLineEdit *lineEdit, QWidget *parent)
|
||||
: LtsWidgets::LtsFramelessDialog(parent)
|
||||
, m_ui(new Ui::SetPropertiesDialog)
|
||||
, m_lineEdit(lineEdit)
|
||||
, m_logger(getLogger("SetPropertiesDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
init();
|
||||
}
|
||||
|
||||
SetPropertiesDialog::~SetPropertiesDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void SetPropertiesDialog::init()
|
||||
{
|
||||
m_ui->buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &SetPropertiesDialog::onAddClicked);
|
||||
// nicht über connectButton - gibt sonst komische Message-Boxes
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked,
|
||||
this, &SetPropertiesDialog::onOkClicked);
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked,
|
||||
this, &SetPropertiesDialog::reject);
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close)->setText(tr("Cancel")); //
|
||||
|
||||
m_ui->scrollArea->widget()->setLayout(m_ui->vlScrollBar);
|
||||
|
||||
if (!m_lineEdit->text().isEmpty())
|
||||
{
|
||||
QJsonParseError error;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(m_lineEdit->text().toUtf8(), &error);
|
||||
|
||||
if (error.error != QJsonParseError::NoError)
|
||||
{
|
||||
ERROR_LOG(m_logger) << error.errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!doc.isObject())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Properties String is no JSON-Object";
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject obj = doc.object();
|
||||
|
||||
for (auto it = obj.constBegin(); it != obj.constEnd(); ++it)
|
||||
addProperty(it.key(), it.value().toVariant());
|
||||
}
|
||||
}
|
||||
|
||||
void SetPropertiesDialog::onOkClicked()
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
for (auto it = m_properties.constBegin(); it != m_properties.constEnd(); ++it)
|
||||
{
|
||||
QString propVal(it.value()->text());
|
||||
QJsonValue jsonVal;
|
||||
|
||||
switch (propValType(propVal))
|
||||
{
|
||||
case PropValType::INT:
|
||||
jsonVal = propVal.toInt();
|
||||
break;
|
||||
case PropValType::DOUBLE:
|
||||
jsonVal = propVal.toDouble();
|
||||
break;
|
||||
case PropValType::BOOL:
|
||||
{
|
||||
if (propVal.toLower() == QStringLiteral("true"))
|
||||
jsonVal = true;
|
||||
if (propVal.toLower() == QStringLiteral("false"))
|
||||
jsonVal = false;
|
||||
break;
|
||||
}
|
||||
case PropValType::STRING:
|
||||
default:
|
||||
jsonVal = propVal;
|
||||
}
|
||||
|
||||
obj.insert(it.key()->text(), jsonVal);
|
||||
|
||||
}
|
||||
|
||||
m_lineEdit->setText(QString::fromUtf8(QJsonDocument(obj).toJson(QJsonDocument::Compact)));
|
||||
|
||||
close();
|
||||
}
|
||||
|
||||
void SetPropertiesDialog::onAddClicked()
|
||||
{
|
||||
addProperty(tr("name"), tr("value"));
|
||||
}
|
||||
|
||||
void SetPropertiesDialog::addProperty(const QString &propName, const QVariant &propValue)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout;
|
||||
QLineEdit *lePropName = new QLineEdit(propName, this);
|
||||
QLineEdit *lePropVal = new QLineEdit(propValue.toString(), this);
|
||||
QPushButton *pbRemove = new QPushButton(this);
|
||||
QLabel *colon = new QLabel(QStringLiteral(":"), this);
|
||||
|
||||
pbRemove->setText(tr("remove"));
|
||||
|
||||
layout->addWidget(lePropName);
|
||||
layout->addWidget(colon);
|
||||
layout->addWidget(lePropVal);
|
||||
layout->addWidget(pbRemove);
|
||||
|
||||
m_properties.insert(lePropName, lePropVal);
|
||||
m_ui->vlPorts->addLayout(layout);
|
||||
|
||||
connect(pbRemove, &QPushButton::clicked,
|
||||
this, [=]()
|
||||
{
|
||||
m_ui->vlPorts->removeItem(layout);
|
||||
m_properties.remove(lePropName);
|
||||
|
||||
delete lePropName;
|
||||
delete lePropVal;
|
||||
delete colon;
|
||||
pbRemove->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
SetPropertiesDialog::PropValType SetPropertiesDialog::propValType(const QString &prop)
|
||||
{
|
||||
bool isOk;
|
||||
|
||||
(void)prop.toInt(&isOk);
|
||||
if (isOk)
|
||||
return PropValType::INT;
|
||||
|
||||
(void)prop.toDouble(&isOk);
|
||||
if (isOk)
|
||||
return PropValType::DOUBLE;
|
||||
|
||||
if (prop.toLower() == QStringLiteral("true") || prop.toLower() == QStringLiteral("false"))
|
||||
return PropValType::BOOL;
|
||||
|
||||
return PropValType::STRING;
|
||||
}
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The SetPropertiesDialog offers an UI to edit the properties of an instrumentation asset
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-16
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
class QLineEdit;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SetPropertiesDialog;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class SetPropertiesDialog
|
||||
: public LtsWidgets::LtsFramelessDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SetPropertiesDialog(QLineEdit *lineEdit, QWidget *parent = nullptr);
|
||||
~SetPropertiesDialog();
|
||||
|
||||
private:
|
||||
void init();
|
||||
private Q_SLOTS:
|
||||
void onOkClicked();
|
||||
void onAddClicked();
|
||||
|
||||
private: // other
|
||||
enum class PropValType
|
||||
{
|
||||
INT,
|
||||
DOUBLE,
|
||||
BOOL,
|
||||
STRING
|
||||
};
|
||||
|
||||
private: // methods
|
||||
void addProperty(const QString &propName, const QVariant &propValue);
|
||||
PropValType propValType(const QString &prop);
|
||||
|
||||
private: // attributes
|
||||
Ui::SetPropertiesDialog *m_ui;
|
||||
QMap<QLineEdit *, QLineEdit *> m_properties; // <propname, propval>
|
||||
QLineEdit *m_lineEdit;
|
||||
LOGGER_T m_logger;
|
||||
}; // class SetPropertiesDialog
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SetPropertiesDialog</class>
|
||||
<widget class="QWidget" name="SetPropertiesDialog">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>200</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Set Ports</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>313</width>
|
||||
<height>153</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>340</x>
|
||||
<y>80</y>
|
||||
<width>160</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="vlScrollBar">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="vlPorts"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDialogButtonBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_dialog_button_box.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2016-10-28
|
||||
#
|
||||
|
||||
SET(src
|
||||
ExerciseAssignment/ism_exercise_assignment_dialog.cpp
|
||||
ExerciseAssignment/ism_exercise_assignment_dialog_model.cpp
|
||||
ExerciseAssignment/ism_exercise_assignment_dialog_requesters.cpp
|
||||
ExerciseAssignment/ism_exercise_assignment_dialog_proxy_model.cpp
|
||||
|
||||
Overview/ism_overview_dialog.cpp
|
||||
Overview/ism_overview_dialog_model.cpp
|
||||
Overview/ism_overview_mounting_point_list_dialog.cpp
|
||||
Overview/ism_overview_mounting_point_list_model.cpp
|
||||
Overview/ism_overview_conflicts_dialog.cpp
|
||||
Overview/ism_overview_conflicts_model.cpp
|
||||
|
||||
AssetList/ism_asset_list_dialog_model.cpp
|
||||
AssetList/ism_asset_list_dialog.cpp
|
||||
AssetList/ism_edit_asset_dialog.cpp
|
||||
AssetList/ism_filter_asset_dialog.cpp
|
||||
AssetList/ism_set_properties_dialog.cpp
|
||||
|
||||
MountingPointInfo/ism_mounting_point_info_dialog.cpp
|
||||
|
||||
MountingPointMapSelection/ism_dds_selector.cpp
|
||||
MountingPointMapSelection/ism_selector.cpp
|
||||
|
||||
MountingPointList/ism_mounting_point_list_dialog.cpp
|
||||
MountingPointList/ism_mounting_point_list_dialog_model.cpp
|
||||
MountingPointList/ism_mounting_point_list_dialog_checkbox_delegate.cpp
|
||||
MountingPointList/ism_mounting_point_list_dialog_checkbox_proxy_model.cpp
|
||||
MountingPointList/ism_mounting_point_list_dialog_list_sort_model.cpp
|
||||
|
||||
ApproachingPoints/ism_approaching_point_list_dialog_model.cpp
|
||||
ApproachingPoints/ism_approaching_point_list_dialog.cpp
|
||||
ApproachingPoints/ism_edit_approaching_point_dialog.cpp
|
||||
|
||||
# ScheduleDifferences ersetzt durch neuen VollständigkeitsCheck:
|
||||
# Overview/ism_overview_mounting_point_list{model, dialog}
|
||||
# ScheduleDifferences/ism_schedule_differences_list_dialog.cpp
|
||||
# ScheduleDifferences/ism_schedule_differences_list_model.cpp
|
||||
|
||||
ism_resource_gui_plugin.cpp
|
||||
ism_resource_gui_plugin.h
|
||||
|
||||
ism_building_mount_point_dialog.cpp
|
||||
ism_building_mount_point_model.cpp
|
||||
|
||||
ism_plan_dialog.cpp
|
||||
ism_plan_edit_dialog.cpp
|
||||
ism_plan_dialog_model.cpp
|
||||
|
||||
#Timeline/ism_plan_tln_delegate.cpp
|
||||
#Timeline/ism_plan_tln_delegate.h
|
||||
#Timeline/ism_plan_tln_dialog.cpp
|
||||
#Timeline/ism_plan_tln_dialog.h
|
||||
#Timeline/ism_plan_tln_model.cpp
|
||||
#Timeline/ism_plan_tln_model.h
|
||||
|
||||
PlanChooser/plan_chooser.cpp
|
||||
PlanChooser/new_plan_dialog.cpp
|
||||
|
||||
CustomViews/ism_schedule.cpp
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(src
|
||||
Overview/ism_overview_dialog.ui
|
||||
Overview/ism_overview_mounting_point_list_dialog.ui
|
||||
Overview/ism_overview_conflicts_dialog.ui
|
||||
AssetList/ism_asset_list_dialog.ui
|
||||
AssetList/ism_edit_asset_dialog.ui
|
||||
AssetList/ism_filter_asset_dialog.ui
|
||||
AssetList/ism_set_properties_dialog.ui
|
||||
MountingPointInfo/ism_mounting_point_info_dialog.ui
|
||||
MountingPointList/ism_mounting_point_list_dialog.ui
|
||||
# ScheduleDifferences/ism_schedule_differences_list_dialog.ui
|
||||
ism_building_mount_point_dialog.ui
|
||||
ism_plan_dialog.ui
|
||||
ism_plan_edit_dialog.ui
|
||||
#Timeline/ism_plan_tln_dialog.ui
|
||||
PlanChooser/plan_chooser.ui
|
||||
PlanChooser/new_plan_dialog.ui
|
||||
CustomViews/ism_schedule.ui
|
||||
ApproachingPoints/ism_approaching_point_list_dialog.ui
|
||||
ApproachingPoints/ism_edit_approaching_point_dialog.ui
|
||||
ExerciseAssignment/ism_exercise_assignment_dialog.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS IsmResGuiPlugin MODULE ${src})
|
||||
NGL_TARGET_LINK_LIBRARIES(IsmResGuiPlugin
|
||||
LtsPrinting
|
||||
NGLLogger
|
||||
nglwidgets
|
||||
ngltools
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsNotification
|
||||
AvmDataPluginInterface
|
||||
IsmResGuiPluginInterface
|
||||
IsmDataPluginInterface
|
||||
IsmShared
|
||||
Qt5::Widgets
|
||||
LtsWidgets
|
||||
LtsDataView
|
||||
LtsUtilsCore # json
|
||||
LtsUtilsGuiDds
|
||||
LtsCoordTrans
|
||||
ltsCoordWidget
|
||||
SituationMapGuiPluginInterface
|
||||
situationMap
|
||||
LtsUtilsGuiConnectDialog
|
||||
LtsUtilsSettings
|
||||
#LtsTimeline
|
||||
LtsSessionDataDds
|
||||
ExmDataPluginInterface
|
||||
CmoDataPluginInterface
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(IsmResGuiPlugin)
|
||||
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for Exercises
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
|
||||
#include "ism_schedule.h"
|
||||
#include "ui_ism_schedule.h"
|
||||
#include "ism_plan_dialog_model.h"
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
CustomViewSchedule::CustomViewSchedule(QWidget *parent)
|
||||
: AbstractDisplayWidget(parent)
|
||||
, m_ui(new Ui::CustomViewSchedule)
|
||||
, m_logger(getLogger("CustomViewSchedule"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
}
|
||||
|
||||
CustomViewSchedule::~CustomViewSchedule()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool CustomViewSchedule::init(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
const QString msName = rowData(idx, InfrastructureManagement::PlanDialogModel::NAME).toString();
|
||||
m_ui->lblName->setText(msName);
|
||||
|
||||
int msId = rowData(idx, InfrastructureManagement::PlanDialogModel::ID).toInt();
|
||||
if (msId == 0)
|
||||
{
|
||||
m_ui->lblName->setWordWrap(true);
|
||||
m_ui->lbCreated->hide();
|
||||
m_ui->lblCreated->hide();
|
||||
m_ui->lbBegin->hide();
|
||||
m_ui->lblBegin->hide();
|
||||
m_ui->lbEnd->hide();
|
||||
m_ui->lblEnd->hide();
|
||||
m_ui->lblStatus->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->lbCreated->hide();
|
||||
m_ui->lblCreated->hide();
|
||||
#ifndef LTS_DEBUG
|
||||
// m_ui->lblCreated->setVisible(true); // Should not be visible in Release build, but it is
|
||||
// m_ui->lbCreated->setVisible(true);
|
||||
#endif
|
||||
m_ui->lblCreated->setText(rowData(idx, InfrastructureManagement::PlanDialogModel::CREATED).toString());
|
||||
m_ui->lblBegin->setText(rowData(idx, InfrastructureManagement::PlanDialogModel::START).toString());
|
||||
m_ui->lblEnd->setText(rowData(idx, InfrastructureManagement::PlanDialogModel::END).toString());
|
||||
|
||||
m_ui->lblStatus->setText(rowData(idx, InfrastructureManagement::PlanDialogModel::STATUS).toString());
|
||||
|
||||
QPalette p = m_ui->lblStatus->palette();
|
||||
QColor newCol = rowData(idx, PlanDialogModel::STATUS, Qt::TextColorRole).value<QColor>();
|
||||
p.setColor(m_ui->lblStatus->backgroundRole(), newCol);
|
||||
p.setColor(m_ui->lblStatus->foregroundRole(), newCol);
|
||||
m_ui->lblStatus->setPalette(p);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for Exercises
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2016-04-08
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class CustomViewSchedule;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class CustomViewSchedule final : public LtsDataView::AbstractDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomViewSchedule(QWidget *parent = nullptr);
|
||||
~CustomViewSchedule();
|
||||
bool init(const QModelIndex &idx) override;
|
||||
|
||||
private:
|
||||
Ui::CustomViewSchedule* m_ui;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CustomViewSchedule</class>
|
||||
<widget class="QWidget" name="CustomViewSchedule">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>258</width>
|
||||
<height>133</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblName">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><Schedule Name></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbCreated">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Created:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblCreated">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><Created Date></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbBegin">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Begin:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblBegin">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><Begin Date></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbEnd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>End:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblEnd">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><End Date></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblStatus">
|
||||
<property name="text">
|
||||
<string notr="true"><Status></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ExerciseAssignmentDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id: ism_exercise_assignment_dialog.cpp 57783 2022-08-03 11:07:05Z ojog_i $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/22_09_resmgmt2.0/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ExerciseAssignment/ism_exercise_assignment_dialog.cpp $
|
||||
* $Author: ojog_i $
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
* Refreshed by Mike Wille, SLTE, 2022-09-26
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_dialog.h"
|
||||
#include "ui_ism_exercise_assignment_dialog.h"
|
||||
#include "ism_exercise_assignment_dialog_requesters.h"
|
||||
#include "ism_exercise_assignment_dialog_proxy_model.h"
|
||||
|
||||
#include <LtsUtilsCore/json_object.h>
|
||||
#include <ExerciseManagement/exm_data_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <LtsWidgets/lts_overlay_loading.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
using namespace LtsUtils;
|
||||
using namespace LtsWidgets;
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
ExerciseAssignmentDialog::ExerciseAssignmentDialog(LtsSession::LtsSession *session, QWidget *parent) noexcept(false)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_session(session)
|
||||
, m_ui(new Ui::ExerciseAssignmentDialog)
|
||||
, m_model(nullptr)
|
||||
, m_modelAssignedFilter(new ExerciseAssignmentDialogModelFilterProxy(this))
|
||||
, m_modelUnassignedFilter(new ExerciseAssignmentDialogModelFilterProxy(this))
|
||||
, m_logger(getLogger("ExerciseAssignmentDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &ExerciseAssignmentDialog::onPrint);
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Exercise_Assignment"));
|
||||
|
||||
std::shared_ptr<ExerciseManagement::Interface::Dtc> exmDtc;
|
||||
|
||||
if (!m_session->getDtc<DataInterface>(m_dtc) ||
|
||||
!m_session->getFtc<DataInterface>(m_ftc) ||
|
||||
!m_session->getDtc<ExerciseManagement::DataInterface>(exmDtc))
|
||||
throw std::exception();
|
||||
|
||||
if (!m_ftc->enableMainStructureElementModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MainStructureElementModify of ISM";
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
if (!exmDtc->enableExercise())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable DT Exercise of EXM";
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
// Add all available exercises to comboBox (do not add deleted or terminated exercises)
|
||||
exmDtc->exercises([this](const ExerciseManagement::Exercise &data)
|
||||
{
|
||||
if (data.isDeleted())
|
||||
return;
|
||||
|
||||
switch(data.state().underlying())
|
||||
{
|
||||
case ExerciseManagement::ExerciseState_def::Created:
|
||||
case ExerciseManagement::ExerciseState_def::Started:
|
||||
case ExerciseManagement::ExerciseState_def::Paused:
|
||||
case ExerciseManagement::ExerciseState_def::Stopped:
|
||||
{
|
||||
m_exercises.insert(data.id(), data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
for (const auto &exercise : qAsConst(m_exercises))
|
||||
m_ui->cbExercises->addItem(QString::fromStdString(exercise.name()), exercise.id());
|
||||
|
||||
|
||||
if (m_ui->cbExercises->count() == 0)
|
||||
{
|
||||
setEnabled(false);
|
||||
setUnchangeable();
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Print)->setEnabled(false);
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_ui->label->setVisible(false);
|
||||
|
||||
m_model = new ExerciseAssignmentDialogModel(m_exercises, this);
|
||||
|
||||
// set initial exercise filter to the assigned exercises so that only buildings for exercise x are visible
|
||||
auto exerciseChangedFn = [this](int index = -1)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
|
||||
m_modelAssignedFilter->setExerciseId(m_ui->cbExercises->currentData().toInt());
|
||||
//m_ui->assignedExercises->expandAll();
|
||||
};
|
||||
|
||||
connect(m_ui->cbExercises, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, exerciseChangedFn);
|
||||
exerciseChangedFn();
|
||||
|
||||
// NOT live, otherwise:
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainStructureElementChanged,
|
||||
this, &ExerciseAssignmentDialog::onMainStructureElementChanged);
|
||||
|
||||
auto cb = [this](const InfrastructureManagement::MainStructureElement &mse)
|
||||
{
|
||||
onMainStructureElementChanged(mse, DataModification::eAdded);
|
||||
};
|
||||
m_dtc->mainStructureElements(cb);
|
||||
|
||||
m_modelUnassignedFilter->setSourceModel(m_model);
|
||||
m_ui->availableExercises->setModel(m_modelUnassignedFilter);
|
||||
m_ui->availableExercises->setSortingEnabled(true);
|
||||
m_ui->availableExercises->sortByColumn(0, Qt::SortOrder::AscendingOrder);
|
||||
m_ui->availableExercises->setDragEnabled(true);
|
||||
m_ui->availableExercises->viewport()->setAcceptDrops(true);
|
||||
// m_ui->availableExercises->setDropIndicatorShown(true);
|
||||
m_ui->availableExercises->setDragDropMode(QAbstractItemView::DragDrop);
|
||||
m_ui->availableExercises->setDefaultDropAction(Qt::DropAction::MoveAction);
|
||||
|
||||
m_modelAssignedFilter->setSourceModel(m_model);
|
||||
m_ui->assignedExercises->setModel(m_modelAssignedFilter);
|
||||
m_ui->assignedExercises->setSortingEnabled(true);
|
||||
m_ui->assignedExercises->sortByColumn(0, Qt::SortOrder::AscendingOrder);
|
||||
m_ui->assignedExercises->setDragEnabled(true);
|
||||
m_ui->assignedExercises->viewport()->setAcceptDrops(true);
|
||||
// m_ui->assignedExercises->setDropIndicatorShown(true);
|
||||
m_ui->assignedExercises->setDragDropMode(QAbstractItemView::DragDrop);
|
||||
m_ui->assignedExercises->setDefaultDropAction(Qt::DropAction::MoveAction);
|
||||
|
||||
connect(m_modelAssignedFilter, &ExerciseAssignmentDialogModelFilterProxy::doRefilter,
|
||||
this, &ExerciseAssignmentDialog::onUnassignedNeedsUpdate);
|
||||
connect(m_modelUnassignedFilter, &ExerciseAssignmentDialogModelFilterProxy::doRefilter,
|
||||
this, &ExerciseAssignmentDialog::onAssignedNeedsUpdate);
|
||||
}
|
||||
|
||||
|
||||
ExerciseAssignmentDialog::~ExerciseAssignmentDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::onUnassignedNeedsUpdate(const QSet<QModelIndex> &setToExpand)
|
||||
{
|
||||
m_modelUnassignedFilter->invalidate();
|
||||
for(auto indexToExpand : setToExpand)
|
||||
m_ui->assignedExercises->expand(m_modelAssignedFilter->mapFromSource(indexToExpand));
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialog::onAssignedNeedsUpdate(const QSet<QModelIndex> &setToExpand)
|
||||
{
|
||||
m_modelAssignedFilter->invalidate();
|
||||
for(auto indexToExpand : setToExpand)
|
||||
m_ui->availableExercises->expand(m_modelUnassignedFilter->mapFromSource(indexToExpand));
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
|
||||
void ExerciseAssignmentDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Exercise Assignment"));
|
||||
}
|
||||
|
||||
|
||||
void ExerciseAssignmentDialog::onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &mse, DataModification modType)
|
||||
{
|
||||
auto seti = mse.structureElementTypeId();
|
||||
if (seti != StructureElementType::Building &&
|
||||
seti != StructureElementType::Announcement)
|
||||
return;
|
||||
|
||||
// read exercise id and add to assigned exercises
|
||||
QString displayName(m_dtc->getBuildingDisplayName(mse.id()));
|
||||
if (displayName.isEmpty())
|
||||
displayName = QString::fromStdString(mse.name());
|
||||
|
||||
int exerciseId;
|
||||
try
|
||||
{
|
||||
exerciseId = JsonObject::fromJson(mse.properties()).value<JsonArray>(QStringLiteral("available_in_exercise")).at<int>(0); // get exercise id from properties json
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
exerciseId = 0;
|
||||
}
|
||||
if (!m_exercises.contains(exerciseId)) // if building is part of a deleted / terminated exercise, just add it to the unassigned buildings model
|
||||
exerciseId = 0;
|
||||
|
||||
if (modType == DataModification::eModified)
|
||||
m_model->updateMse(mse.id(), mse.groupId(), displayName, exerciseId);
|
||||
else if (modType == DataModification::eAdded)
|
||||
m_model->addMse(mse.id(), mse.groupId(), displayName, exerciseId);
|
||||
else
|
||||
m_model->removeMse(mse.id());
|
||||
}
|
||||
|
||||
bool ExerciseAssignmentDialog::apply()
|
||||
{
|
||||
// XXX: HACK we don't know if user pressed ok or apply - apply() has to emidiately return, but the operation is async... so mimic ok/apply later, based on what was clicked
|
||||
bool wasOkay = (sender() == static_cast<QObject *>(m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)));
|
||||
|
||||
LtsOverlayLoading *lol = new LtsOverlayLoading;
|
||||
setOverlay(lol);
|
||||
|
||||
MSEModifyRequestCollector *collector = new MSEModifyRequestCollector(m_ftc, this);
|
||||
|
||||
{
|
||||
QPushButton *pbCancel = new QPushButton;
|
||||
pbCancel->setText(tr("Cancel"));
|
||||
connect(pbCancel, &QPushButton::clicked,
|
||||
this, [pbCancel, collector, lol]()
|
||||
{
|
||||
collector->cancel();
|
||||
lol->setText(tr("Canceling ..."));
|
||||
pbCancel->setEnabled(false);
|
||||
});
|
||||
|
||||
qobject_cast<QVBoxLayout *>(lol->layout())->addWidget(pbCancel, 0, Qt::AlignmentFlag::AlignCenter);
|
||||
}
|
||||
|
||||
const QVector<RequestInfos> &requestInfos = m_model->getRequestInfos();
|
||||
for (const RequestInfos &ri : qAsConst(requestInfos))
|
||||
{
|
||||
MainStructureElementModifyRequest request;
|
||||
MainStructureElement &mse = request;
|
||||
mse = m_dtc->mainStructureElement(ri.mseId);
|
||||
|
||||
QJsonObject root;
|
||||
try
|
||||
{
|
||||
root = JsonObject::fromJson(mse.properties()).object();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "can't parse json for mseId " << ri.mseId << " and excId " << ri.exerciseId << " - using new json";
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
if (LtsUtils::ProjectSettings::getInstance()->value(QStringLiteral("ism"), QStringLiteral("enableSetRecordingDialog")).toBool())
|
||||
setRecording(mse,ri.exerciseId != 0);
|
||||
|
||||
if (ri.exerciseId != 0)
|
||||
root[QStringLiteral("available_in_exercise")] = QJsonArray({{ri.exerciseId}});
|
||||
else
|
||||
root.remove(QStringLiteral("available_in_exercise"));
|
||||
|
||||
mse.properties(QString::fromUtf8(QJsonDocument(root).toJson()).toStdString());
|
||||
|
||||
collector->addRequest(ri, request);
|
||||
}
|
||||
|
||||
int initialCount = collector->count();
|
||||
const QString leText(QStringLiteral("%1<br />%3 / %2").arg(tr("Assigning building(s) to exercise(s)")).arg(initialCount));
|
||||
lol->setText(leText.arg(0));
|
||||
|
||||
|
||||
connect(collector, &MSEModifyRequestCollector::requestComplete,
|
||||
this, [collector, lol, leText, initialCount]()
|
||||
{
|
||||
lol->setText(leText.arg(initialCount - collector->count()));
|
||||
});
|
||||
|
||||
connect(collector, &MSEModifyRequestCollector::finished,
|
||||
this, [this, collector, wasOkay, lol](bool canceled)
|
||||
{
|
||||
unsetOverlay();
|
||||
lol->deleteLater();
|
||||
collector->deleteLater();
|
||||
|
||||
int failedCount = collector->failedCount();
|
||||
if (failedCount > 0)
|
||||
{
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("Error: %1 building(s) could not be assigned!").arg(failedCount));
|
||||
return;
|
||||
}
|
||||
|
||||
if (canceled)
|
||||
return;
|
||||
|
||||
__unchange__(); // 'apply' behaviour
|
||||
|
||||
if (!wasOkay) // 'ok' behaviour
|
||||
return;
|
||||
|
||||
closeRequest(); // we 'unchanged', so it will close directly
|
||||
});
|
||||
|
||||
collector->go();
|
||||
|
||||
return false; // our request is async, say false, show a blocking dialog and do ok-/apply-button stuff later
|
||||
}
|
||||
/*!
|
||||
* \brief ExerciseAssignmentDialog::setRecoding
|
||||
* The property of an element with type indoorcamera or outdoorcamera can be updated
|
||||
* \param mse
|
||||
* \param state
|
||||
*/
|
||||
void ExerciseAssignmentDialog::setRecording(MainStructureElement &mse, bool state)
|
||||
{
|
||||
for(auto &el : mse.elements())
|
||||
{
|
||||
if(el.mountingPointTypeId() != MountingPointType::IndoorCamera &&
|
||||
el.mountingPointTypeId() != MountingPointType::OutdoorCamera)
|
||||
continue;
|
||||
|
||||
QJsonDocument propsDoc = QJsonDocument::fromJson(QByteArray::fromStdString(el.properties()));
|
||||
QJsonObject propsObj;
|
||||
if (propsDoc.isObject()) // if the given properties are no valid JSON object, the properties will be made from scratch
|
||||
propsObj = propsDoc.object();
|
||||
propsObj.insert(QLatin1String("record"), state);
|
||||
el.properties(QJsonDocument(propsObj).toJson(QJsonDocument::Compact).toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ExerciseAssignmentDialog::onPrint()
|
||||
{
|
||||
QTreeView tv;
|
||||
tv.setModel(m_model);
|
||||
tv.expandAll();
|
||||
|
||||
LtsPrinting::printView(m_session, this, &tv);
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The AssetListDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id: ism_exercise_assignment_dialog.h 45935 2019-03-08 08:36:11Z ehrlicher $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/22_09_resmgmt2.0/Lts/Plugins/InfrastructureManagement/Gui/AudioVideoConfig/ExerciseAssignment/ism_exercise_assignment_dialog.h $
|
||||
* $Author: ehrlicher $
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-06-29
|
||||
* Refreshed by Mike Wille, SLTE, 2022-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ExerciseAssignmentDialog;
|
||||
}
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ExerciseAssignmentDialogModel;
|
||||
class ExerciseAssignmentDialogModelFilterProxy;
|
||||
|
||||
|
||||
class ExerciseAssignmentDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ExerciseAssignmentDialog(LtsSession::LtsSession *session, QWidget *parent = nullptr) noexcept(false);
|
||||
~ExerciseAssignmentDialog();
|
||||
|
||||
private slots:
|
||||
void onUnassignedNeedsUpdate(const QSet<QModelIndex> &setToExpand);
|
||||
void onAssignedNeedsUpdate(const QSet<QModelIndex> &setToExpand);
|
||||
|
||||
void onPrint();
|
||||
|
||||
private:
|
||||
void onMainStructureElementChanged(const InfrastructureManagement::MainStructureElement &mse, DataModification modType);
|
||||
void retranslate() override;
|
||||
bool apply() override;
|
||||
void setRecording(MainStructureElement &mse, bool state);
|
||||
private:
|
||||
LtsSession::LtsSession *m_session;
|
||||
Ui::ExerciseAssignmentDialog *m_ui;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
|
||||
ExerciseAssignmentDialogModel *m_model;
|
||||
ExerciseAssignmentDialogModelFilterProxy *m_modelAssignedFilter;
|
||||
ExerciseAssignmentDialogModelFilterProxy *m_modelUnassignedFilter;
|
||||
|
||||
QMap<qint32, ExerciseManagement::Exercise> m_exercises;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace InfrastructureManagement
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExerciseAssignmentDialog</class>
|
||||
<widget class="QWidget" name="ExerciseAssignmentDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>953</width>
|
||||
<height>681</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" color:#aa0000;">WARNING: There are no exercises available. You can't assign buildings.</span></p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<layout class="QGridLayout" name="gridLayout"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbExercises">
|
||||
<property name="text">
|
||||
<string>Assign to exercise:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="cbExercises">
|
||||
<property name="currentText">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QTreeView" name="availableExercises">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::CopyAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QTreeView" name="assignedExercises">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragDrop</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::CopyAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+353
@@ -0,0 +1,353 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id: $
|
||||
* $HeadURL: $
|
||||
* $Author: $
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_dialog_model.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QGuiApplication>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#ifdef LTS_DEBUG
|
||||
#include <QTimer> // ftc delay
|
||||
#endif
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
ExerciseAssignmentDialogModel::ExerciseAssignmentDialogModel(const QMap<qint32, ExerciseManagement::Exercise> &exercises, QObject *parent) noexcept(false)
|
||||
: QAbstractItemModel(parent)
|
||||
, m_rootItem(new TreeItem(0, 0, tr("InvisibleRootItem"), -1))
|
||||
, m_exercises(exercises)
|
||||
, m_logger(getLogger("ExerciseAssignmentDialogModel"))
|
||||
{
|
||||
for (int it = BuildingGroup_def::UnknownGroup;
|
||||
it <= BuildingGroup_def::Salchau; // WARNING: Change this, when enum changes!
|
||||
++it)
|
||||
{
|
||||
m_rootItem->appendChild(new TreeItem(0, it, toString(static_cast<BuildingGroup_def::type>(it)), -1, m_rootItem));
|
||||
}
|
||||
}
|
||||
|
||||
ExerciseAssignmentDialogModel::~ExerciseAssignmentDialogModel()
|
||||
{
|
||||
delete m_rootItem;
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialogModel::addMse(int mseId, int sectionId, const QString &displayName, int exerciseId)
|
||||
{
|
||||
const QList<TreeItem*> &childItems = m_rootItem->childItems();
|
||||
for (auto sectionItem : qAsConst(childItems))
|
||||
{
|
||||
if (sectionItem->sectionId() == sectionId)
|
||||
{
|
||||
beginInsertRows(index(sectionItem), sectionItem->childCount(), sectionItem->childCount());
|
||||
sectionItem->appendChild(new TreeItem(mseId, sectionId, displayName, exerciseId, sectionItem));
|
||||
endInsertRows();
|
||||
return;
|
||||
}
|
||||
}
|
||||
ERROR_LOG(m_logger) << "Did not find section with enum value " << sectionId;
|
||||
return;
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialogModel::updateMse(int mseId, int sectionId, const QString &displayName, int exerciseId)
|
||||
{
|
||||
// Todo: Change of display name or moving to another section not yet implemented
|
||||
Q_UNUSED(sectionId);
|
||||
Q_UNUSED(displayName);
|
||||
|
||||
QModelIndex mi = findItemByMseId(mseId);
|
||||
TreeItem* item = treeItem(mi);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (exerciseId != item->originalExerciseId())
|
||||
{
|
||||
item->setOriginalExerciseId(exerciseId);
|
||||
emit dataChanged(mi, mi);
|
||||
}
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialogModel::removeMse(int mseId)
|
||||
{
|
||||
QModelIndex mi = findItemByMseId(mseId);
|
||||
TreeItem* item = treeItem(mi);
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
TreeItem* parent = item->parentItem();
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
beginRemoveRows(index(parent),item->childNumber(),item->childNumber());
|
||||
parent->removeChild(item->childNumber());
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
Qt::DropActions ExerciseAssignmentDialogModel::supportedDropActions() const
|
||||
{
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
QVariant ExerciseAssignmentDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() ||
|
||||
(role != Qt::DisplayRole
|
||||
&& role != Qt::FontRole)
|
||||
)
|
||||
return {};
|
||||
|
||||
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
|
||||
if (!item)
|
||||
return {};
|
||||
|
||||
if (role == Qt::FontRole)
|
||||
{
|
||||
if (item->originalExerciseId() == item->exerciseId())
|
||||
return {};
|
||||
QFont f;
|
||||
f.setBold(true);
|
||||
return f;
|
||||
}
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (index.column() == 0)
|
||||
return item->displayName();
|
||||
if (index.column() == 1)
|
||||
{
|
||||
const int exerciseId = item->exerciseId();
|
||||
if (exerciseId < 0)
|
||||
return {};
|
||||
if (exerciseId == 0)
|
||||
return QStringLiteral("-");
|
||||
return QString::fromStdString(m_exercises.value(exerciseId).name());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant ExerciseAssignmentDialogModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation != Qt::Orientation::Horizontal || role != Qt::DisplayRole)
|
||||
return QAbstractItemModel::headerData(section, orientation, role);
|
||||
if (section == 0)
|
||||
return tr("Building");
|
||||
if (section == 1)
|
||||
return tr("Assigned Exercises");
|
||||
return {};
|
||||
}
|
||||
|
||||
QModelIndex ExerciseAssignmentDialogModel::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (!hasIndex(row, column, parent))
|
||||
return {};
|
||||
|
||||
TreeItem *parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = m_rootItem;
|
||||
else
|
||||
parentItem = static_cast<TreeItem*>(parent.internalPointer());
|
||||
|
||||
TreeItem *childItem = parentItem->child(row);
|
||||
if (childItem)
|
||||
return createIndex(row, column, childItem);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
QModelIndex ExerciseAssignmentDialogModel::parent(const QModelIndex &mi) const
|
||||
{
|
||||
if (!mi.isValid())
|
||||
return {};
|
||||
|
||||
TreeItem *childItem = static_cast<TreeItem*>(mi.internalPointer());
|
||||
TreeItem *parentItem = childItem->parentItem();
|
||||
|
||||
return index(parentItem);
|
||||
}
|
||||
|
||||
QModelIndex ExerciseAssignmentDialogModel::index(TreeItem *item) const
|
||||
{
|
||||
if (item == m_rootItem || !item)
|
||||
return {};
|
||||
return createIndex(item->childNumber(),0,item);
|
||||
}
|
||||
|
||||
|
||||
int ExerciseAssignmentDialogModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
TreeItem *parentItem;
|
||||
|
||||
if (!parent.isValid())
|
||||
parentItem = m_rootItem;
|
||||
else
|
||||
parentItem = treeItem(parent);
|
||||
|
||||
return parentItem->childCount();
|
||||
}
|
||||
|
||||
QSet<int> ExerciseAssignmentDialogModel::childMses(const QModelIndex &mi, int exerciseId) const
|
||||
{
|
||||
QSet<int> mses;
|
||||
const QList<TreeItem*> &childItems = treeItem(mi)->childItems();
|
||||
for(auto myChild : qAsConst(childItems))
|
||||
{
|
||||
if (myChild->exerciseId() == exerciseId)
|
||||
mses << myChild->mseId();
|
||||
}
|
||||
return mses;
|
||||
}
|
||||
|
||||
|
||||
TreeItem *ExerciseAssignmentDialogModel::treeItem(const QModelIndex &index) const
|
||||
{
|
||||
return static_cast<TreeItem*>(index.internalPointer());
|
||||
}
|
||||
|
||||
QModelIndex ExerciseAssignmentDialogModel::findItemByMseId(int mseId) const
|
||||
{
|
||||
// This only works as long as first level is section and second level is Building!
|
||||
// Otherwise we need to go into recursion!
|
||||
const QList<TreeItem*> &childItems = m_rootItem->childItems();
|
||||
for (auto sectionItem : qAsConst(childItems))
|
||||
{
|
||||
const QList<TreeItem*> §ionChildItems= sectionItem->childItems();
|
||||
for (auto mseItem : qAsConst(sectionChildItems))
|
||||
{
|
||||
if (mseItem->mseId() == mseId)
|
||||
return index(mseItem);
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialogModel::setExerciseId(const QModelIndex &mi, int exerciseId)
|
||||
{
|
||||
TreeItem *ti = treeItem(mi);
|
||||
if (!ti)
|
||||
return;
|
||||
ti->setExerciseId(exerciseId);
|
||||
emit dataChanged(mi, mi, {Qt::DisplayRole, Qt::FontRole});
|
||||
}
|
||||
|
||||
|
||||
QVector<RequestInfos> ExerciseAssignmentDialogModel::getRequestInfos(bool all) const
|
||||
{
|
||||
QVector<RequestInfos> requestInfos;
|
||||
m_rootItem->getAllUnderlyingRequestInfos(requestInfos, all);
|
||||
return requestInfos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
TreeItem::TreeItem(int mseId, int sectionId, const QString &displayName, int exerciseId, TreeItem *parentItem)
|
||||
: m_mseId(mseId)
|
||||
, m_sectionId(sectionId)
|
||||
, m_displayName(displayName)
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_originalExerciseId(exerciseId)
|
||||
, m_parentItem(parentItem)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TreeItem::~TreeItem()
|
||||
{
|
||||
qDeleteAll(m_childItems);
|
||||
}
|
||||
|
||||
void TreeItem::appendChild(TreeItem *child)
|
||||
{
|
||||
m_childItems.append(child);
|
||||
}
|
||||
|
||||
TreeItem *TreeItem::child(int row)
|
||||
{
|
||||
if (row < 0 || row >= m_childItems.size())
|
||||
return nullptr;
|
||||
return m_childItems.at(row);
|
||||
}
|
||||
|
||||
int TreeItem::childNumber() const
|
||||
{
|
||||
if (m_parentItem)
|
||||
return m_parentItem->childItems().indexOf(const_cast<TreeItem*>(this));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TreeItem::childCount() const
|
||||
{
|
||||
return m_childItems.count();
|
||||
}
|
||||
|
||||
void TreeItem::removeChild(int id)
|
||||
{
|
||||
delete(m_childItems.value(id));
|
||||
m_childItems.removeAt(id);
|
||||
}
|
||||
|
||||
void TreeItem::getAllUnderlyingRequestInfos(QVector<RequestInfos> &requestInfos, bool all) const
|
||||
{
|
||||
const QList<TreeItem*> &childItemsRef = childItems();
|
||||
for (auto myChild : qAsConst(childItemsRef))
|
||||
{
|
||||
if (all || (myChild->exerciseId() != myChild->originalExerciseId()))
|
||||
requestInfos.append({myChild->mseId(), myChild->exerciseId()});
|
||||
myChild->getAllUnderlyingRequestInfos(requestInfos, all);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id: $
|
||||
* $HeadURL: $
|
||||
* $Author: $
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <ExerciseManagement/exm.hpp>
|
||||
#include <QAbstractItemModel>
|
||||
#include <QSet>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
/// RequestInfos
|
||||
struct RequestInfos
|
||||
{
|
||||
int mseId;
|
||||
int exerciseId;
|
||||
};
|
||||
|
||||
// class ExerciseAssignmentDialogModel;
|
||||
class TreeItem
|
||||
{
|
||||
public:
|
||||
explicit TreeItem(int mseId, int sectionId, const QString &displayName, int exerciseId, TreeItem *parentItem = nullptr);
|
||||
~TreeItem();
|
||||
|
||||
void appendChild(TreeItem *child);
|
||||
void removeChild(int id);
|
||||
|
||||
TreeItem* child(int row);
|
||||
int childNumber() const;
|
||||
int childCount() const;
|
||||
const QList<TreeItem*> childItems() const { return m_childItems; }
|
||||
|
||||
int sectionId() const { return m_sectionId; }
|
||||
int mseId() const { return m_mseId; }
|
||||
QString displayName() const { return m_displayName; }
|
||||
|
||||
void setExerciseId(int exerciseId) { m_exerciseId = exerciseId; }
|
||||
int exerciseId() const { return m_exerciseId; }
|
||||
|
||||
void setOriginalExerciseId(int exerciseId) { m_originalExerciseId = exerciseId; }
|
||||
int originalExerciseId() const { return m_originalExerciseId; }
|
||||
|
||||
TreeItem* parentItem() { return m_parentItem; }
|
||||
|
||||
void getAllUnderlyingRequestInfos(QVector<RequestInfos> &requestInfos, bool all = false) const;
|
||||
|
||||
private:
|
||||
int m_mseId;
|
||||
int m_sectionId;
|
||||
QString m_displayName;
|
||||
int m_exerciseId;
|
||||
int m_originalExerciseId;
|
||||
QList<TreeItem*> m_childItems;
|
||||
TreeItem* m_parentItem;
|
||||
};
|
||||
|
||||
/// ExerciseAssignmentDialogModel
|
||||
class ExerciseAssignmentDialogModel : public QAbstractItemModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ExerciseAssignmentDialogModel(const QMap<qint32, ExerciseManagement::Exercise> &exercises, QObject *parent = nullptr) noexcept(false);
|
||||
~ExerciseAssignmentDialogModel();
|
||||
|
||||
void addMse(int mseId, int sectionId, const QString &displayName, int exerciseId);
|
||||
void updateMse(int mseId, int sectionId, const QString &displayName, int exerciseId);
|
||||
void removeMse(int mseId);
|
||||
|
||||
QModelIndex findItemByMseId(int mseId) const;
|
||||
|
||||
void setExerciseId(const QModelIndex &mi, int exerciseId);
|
||||
int exerciseId(const QModelIndex &mi) const { return treeItem(mi) ? treeItem(mi)->exerciseId() : -1; }
|
||||
|
||||
int mseId(const QModelIndex &mi) const { return treeItem(mi) ? treeItem(mi)->mseId() : 0; }
|
||||
|
||||
QVector<RequestInfos> getRequestInfos(bool all = false) const;
|
||||
QSet<int> childMses(const QModelIndex &mi, int exerciseId) const;
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
protected:
|
||||
int rowCount(const QModelIndex &parent = {}) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent) const override;
|
||||
QModelIndex parent(const QModelIndex &index) const override;
|
||||
int columnCount(const QModelIndex &) const override { return 2; }
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
|
||||
private:
|
||||
|
||||
TreeItem* treeItem(const QModelIndex &index) const;
|
||||
QModelIndex index(TreeItem *item) const;
|
||||
|
||||
TreeItem* m_rootItem;
|
||||
QMap<qint32, ExerciseManagement::Exercise> m_exercises;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id: $
|
||||
* $HeadURL: $
|
||||
* $Author: $
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_dialog_proxy_model.h"
|
||||
#include "ism_exercise_assignment_dialog_model.h"
|
||||
|
||||
#include <QMimeData>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
void ExerciseAssignmentDialogModelFilterProxy::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<ExerciseAssignmentDialogModel *>(sourceModel);
|
||||
Q_ASSERT(m_sourceModel != nullptr);
|
||||
QSortFilterProxyModel::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
void ExerciseAssignmentDialogModelFilterProxy::setExerciseId(int exerciseId)
|
||||
{
|
||||
m_exerciseId = exerciseId;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
|
||||
bool ExerciseAssignmentDialogModelFilterProxy::filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
const QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
|
||||
if (!sourceIndex.isValid())
|
||||
return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
|
||||
|
||||
// Parents are true automatically...
|
||||
if (m_sourceModel->mseId(sourceIndex) == 0)
|
||||
return false;
|
||||
|
||||
return (m_sourceModel->exerciseId(sourceIndex) == m_exerciseId);
|
||||
}
|
||||
|
||||
|
||||
bool ExerciseAssignmentDialogModelFilterProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
{
|
||||
return QString::localeAwareCompare(sourceModel()->data(left).toString(), sourceModel()->data(right).toString()) < 0;
|
||||
}
|
||||
|
||||
QVariant ExerciseAssignmentDialogModelFilterProxy::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (section == 0 && orientation == Qt::Orientation::Horizontal && role == Qt::DisplayRole)
|
||||
return m_exerciseId > 0 ? tr("Assigned Buildings") : tr("Unassigned Buildings");
|
||||
return m_sourceModel->headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QMimeData *ExerciseAssignmentDialogModelFilterProxy::mimeData(const QModelIndexList &indexes) const
|
||||
{
|
||||
QJsonObject root;
|
||||
QJsonArray mseIds;
|
||||
|
||||
for(const QModelIndex mi : indexes)
|
||||
{
|
||||
QModelIndex miSource = mapToSource(mi);
|
||||
int mseId = m_sourceModel->mseId(miSource);
|
||||
if (mseId <= 0)
|
||||
{
|
||||
const QSet<int> childMses = m_sourceModel->childMses(miSource, m_exerciseId);
|
||||
for (int mse : qAsConst(childMses))
|
||||
mseIds << mse;
|
||||
}
|
||||
else
|
||||
mseIds << mseId;
|
||||
}
|
||||
|
||||
root[QStringLiteral("eams")] = mseIds;
|
||||
root[QStringLiteral("oldExerciseId")] = m_exerciseId;
|
||||
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
mimeData->setData(QStringLiteral("rheinmetall/exercise-assignment"), QJsonDocument(root).toJson());
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
Qt::ItemFlags ExerciseAssignmentDialogModelFilterProxy::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags f = Qt::ItemIsDropEnabled | QAbstractItemModel::flags(index);
|
||||
|
||||
if (index.isValid())
|
||||
f |= Qt::ItemIsDragEnabled;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
bool ExerciseAssignmentDialogModelFilterProxy::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
|
||||
{
|
||||
if (!canDropMimeData(data, action, row, column, parent))
|
||||
return false;
|
||||
|
||||
const JsonObject root(JsonObject::fromJson(data->data(QStringLiteral("rheinmetall/exercise-assignment"))));
|
||||
const JsonArray eams(root.value<JsonArray>(QStringLiteral("eams")));
|
||||
QSet<QModelIndex> setToExpand;
|
||||
|
||||
const QVector<int> &eamsVec = eams.toVector<int>();
|
||||
for (int mseId : qAsConst(eamsVec))
|
||||
{
|
||||
QModelIndex sourceMi = m_sourceModel->findItemByMseId(mseId);
|
||||
setToExpand.insert(sourceMi.parent());
|
||||
if (sourceMi.isValid())
|
||||
m_sourceModel->setExerciseId(sourceMi, m_exerciseId);
|
||||
}
|
||||
// Don't know why we have to do this, as always "dataChanged()" is emitted...
|
||||
invalidateFilter();
|
||||
emit doRefilter(setToExpand);
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::DropActions ExerciseAssignmentDialogModelFilterProxy::supportedDropActions() const
|
||||
{
|
||||
return Qt::MoveAction;
|
||||
}
|
||||
|
||||
bool ExerciseAssignmentDialogModelFilterProxy::canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(row)
|
||||
Q_UNUSED(column)
|
||||
Q_UNUSED(parent)
|
||||
|
||||
if (action != supportedDropActions())
|
||||
return false;
|
||||
|
||||
const JsonObject root(JsonObject::fromJson(data->data(QStringLiteral("rheinmetall/exercise-assignment"))));
|
||||
int oldExerciseId = root.value<int>(QStringLiteral("oldExerciseId"));
|
||||
return oldExerciseId != m_exerciseId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id: $
|
||||
* $HeadURL: $
|
||||
* $Author: $
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <LtsUtilsCore/json_object.h>
|
||||
|
||||
using namespace LtsUtils;
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ExerciseAssignmentDialogModel;
|
||||
|
||||
|
||||
/// ExerciseAssignmentDialogModelFilterProxy
|
||||
class ExerciseAssignmentDialogModelFilterProxy : public QSortFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExerciseAssignmentDialogModelFilterProxy(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
, m_exerciseId(0)
|
||||
, m_logger(getLogger("ExerciseAssignmentDialogModelFilterProxy"))
|
||||
{
|
||||
setRecursiveFilteringEnabled(true);
|
||||
}
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
void setExerciseId(int exerciseId);
|
||||
|
||||
signals:
|
||||
void doRefilter(const QSet<QModelIndex> &setToExpand);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &rioght) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
int columnCount(const QModelIndex &) const override { return 1; }
|
||||
|
||||
QMimeData* mimeData(const QModelIndexList &_indexes) const override;
|
||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override;
|
||||
Qt::DropActions supportedDropActions() const override;
|
||||
bool canDropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) const override;
|
||||
QStringList mimeTypes() const override
|
||||
{
|
||||
return { QStringLiteral("rheinmetall/exercise-assignment") };
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ExerciseAssignmentMime
|
||||
{
|
||||
public:
|
||||
ExerciseAssignmentMime(const JsonObject &root) noexcept(false) // drop
|
||||
: m_mseId(root.value<int>(QStringLiteral("mseId")))
|
||||
{}
|
||||
|
||||
ExerciseAssignmentMime(int mseId) noexcept(false) // drag
|
||||
: m_mseId(mseId)
|
||||
{}
|
||||
|
||||
QJsonObject toJson() const
|
||||
{
|
||||
return { { QStringLiteral("mseId"), m_mseId } };
|
||||
}
|
||||
int mseId() const { return m_mseId; }
|
||||
|
||||
private:
|
||||
int m_mseId;
|
||||
};
|
||||
|
||||
private:
|
||||
int m_exerciseId;
|
||||
ExerciseAssignmentDialogModel *m_sourceModel;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id: $
|
||||
* $HeadURL: $
|
||||
* $Author: $
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#include "ism_exercise_assignment_dialog_requesters.h"
|
||||
#include "ism_exercise_assignment_dialog_model.h"
|
||||
|
||||
#include <QFont>
|
||||
#include <QGuiApplication>
|
||||
#include <QMimeData>
|
||||
#ifdef LTS_DEBUG
|
||||
#include <QTimer> // ftc delay
|
||||
#endif
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
/// MSEModifyRequestCollector
|
||||
void MSEModifyRequestCollector::next()
|
||||
{
|
||||
if (m_requests.isEmpty())
|
||||
{
|
||||
emit finished(m_canceled);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MSEModifyRequester *requester = new MSEModifyRequester;
|
||||
|
||||
const QPair<RequestInfos, MainStructureElementModifyRequest> request(m_requests.takeFirst());
|
||||
|
||||
connect(requester, &MSEModifyRequester::finished,
|
||||
this, [this](const QString &msg)
|
||||
{
|
||||
bool failed = (!msg.isEmpty());
|
||||
|
||||
if (failed)
|
||||
{
|
||||
m_failedCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ri.model->unchange(ri.rowId);
|
||||
}
|
||||
|
||||
emit requestComplete(failed);
|
||||
|
||||
if (m_canceled)
|
||||
m_requests.clear();
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
auto go = [this, request, requester]()
|
||||
{
|
||||
m_ftc->mainStructureElementModifyRequest(request.second, requester);
|
||||
};
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
if (QGuiApplication::keyboardModifiers().testFlag(Qt::KeyboardModifier::ControlModifier))
|
||||
{
|
||||
QTimer::singleShot(3000, this, go);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
go();
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id: $
|
||||
* $HeadURL: $
|
||||
* $Author: $
|
||||
*
|
||||
* Created by Mike Wille, SLTE, 2022-09-27
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ism_exercise_assignment_dialog_model.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QPair>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
/// MSEModifyRequester
|
||||
class MSEModifyRequester : public QObject,
|
||||
public Interface::Ftc::MainStructureElementModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MSEModifyRequester()
|
||||
: QObject() // do NOT parent!
|
||||
{}
|
||||
|
||||
void onMainStructureElementModifyReply(const Core::FunctionReplyObject &reply) override
|
||||
{
|
||||
if (reply.error())
|
||||
emit finished(reply.translated());
|
||||
else
|
||||
emit finished({});
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
signals:
|
||||
void finished(const QString &msg);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// MSEModifyRequestCollector
|
||||
class MSEModifyRequestCollector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MSEModifyRequestCollector(std::shared_ptr<Interface::Ftc> &ftc, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_ftc(ftc)
|
||||
{}
|
||||
|
||||
void addRequest(const RequestInfos &requestInfos, const MainStructureElementModifyRequest &request)
|
||||
{
|
||||
m_requests += QPair<RequestInfos, MainStructureElementModifyRequest>(requestInfos, request);
|
||||
}
|
||||
|
||||
void cancel()
|
||||
{
|
||||
m_canceled = true;
|
||||
}
|
||||
|
||||
void go()
|
||||
{
|
||||
next();
|
||||
}
|
||||
|
||||
int count() const
|
||||
{
|
||||
return m_requests.count();
|
||||
}
|
||||
|
||||
int failedCount() const
|
||||
{
|
||||
return m_failedCount;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void next();
|
||||
|
||||
signals:
|
||||
void finished(bool canceled);
|
||||
void requestComplete(bool failed);
|
||||
|
||||
private:
|
||||
QVector<QPair<RequestInfos, MainStructureElementModifyRequest> > m_requests;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
bool m_canceled = false;
|
||||
int m_failedCount = 0;
|
||||
};
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
+382
@@ -0,0 +1,382 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The MountingPointInfoDialog shows information about a single mounting point
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-01-12
|
||||
*/
|
||||
|
||||
#include "ism_mounting_point_info_dialog.h"
|
||||
#include "ui_ism_mounting_point_info_dialog.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
|
||||
#include <AudioVideoManagement/ava_session.h>
|
||||
#include <LtsCoordTrans/lts_coord_trans.h>
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
MountingPointInfoDialog::MountingPointInfoDialog(int32_t mountingPointId, int32_t scheduleId, const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_ui(new Ui::MountingPointInfoDialog)
|
||||
, m_mountingPointId(mountingPointId)
|
||||
, m_assetId(-1)
|
||||
, m_scheduleId(scheduleId)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_dtc(nullptr)
|
||||
, m_ismIfc(nullptr)
|
||||
, m_avmIfc(nullptr)
|
||||
, m_logger(getLogger("MountingPointInfoDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->gbxAsset->hide();
|
||||
}
|
||||
|
||||
MountingPointInfoDialog::~MountingPointInfoDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
qDeleteAll(m_dynamicAssetPropLabels);
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::retranslate()
|
||||
{
|
||||
//nfrastructureManagement::InstrumentationAsset ia = m_dtc->instrumentationAsset(m_mountingPointId);
|
||||
StructureElement se;
|
||||
m_dtc->getStructureElementById(m_mountingPointId, se);
|
||||
QString seName = QString::fromStdString(se.displayName()).trimmed();
|
||||
QString lbName;
|
||||
// display name is composed by mse name and se name => se.displayname
|
||||
// when se.displayname is empty > we will manually compose it.
|
||||
if(seName.isEmpty())
|
||||
{
|
||||
MainStructureElement mse= m_dtc->mainStructureElement(se.mainStructureElementId());
|
||||
lbName = QString::fromStdString(mse.name()) + QStringLiteral(" - ") + QString::fromStdString(se.name());
|
||||
}
|
||||
else
|
||||
{
|
||||
lbName = seName.replace(QStringLiteral("bldg_"), QStringLiteral(""));
|
||||
}
|
||||
|
||||
translate(m_ui, lbName);
|
||||
}
|
||||
|
||||
bool MountingPointInfoDialog::init(const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ForeignDataInterface> &ismIfc,
|
||||
const std::shared_ptr<AudioVideoManagement::ForeignDataInterface> &avmIfc)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Initializing MountingPointInfoDialog ...";
|
||||
|
||||
disconnect();
|
||||
m_dtc = dtc;
|
||||
m_ismIfc = ismIfc;
|
||||
m_avmIfc = avmIfc;
|
||||
|
||||
StructureElement mountingPointData;
|
||||
|
||||
if (!(dtc != nullptr &&
|
||||
m_dtc->enableInstrumentationAsset() &&
|
||||
m_dtc->enableMountingPointAsset() &&
|
||||
m_dtc->enableMainStructureElement() &&
|
||||
m_dtc->enableMainSchedule() &&
|
||||
m_dtc->waitForHistoricalDataInstrumentationAsset(10000) &&
|
||||
m_dtc->waitForHistoricalDataMountingPointAsset(10000) &&
|
||||
m_dtc->waitForHistoricalDataMainStructureElement(10000) &&
|
||||
m_dtc->waitForHistoricalDataMainSchedule(10000) &&
|
||||
m_dtc->getStructureElementById(m_mountingPointId, mountingPointData) &&
|
||||
connect(m_dtc.get(), &Interface::Dtc::instrumentationAssetChanged,
|
||||
this, &MountingPointInfoDialog::onInstrumentationAssetChanged) &&
|
||||
connect(m_dtc.get(), &Interface::Dtc::mountingPointAssetChanged,
|
||||
this, &MountingPointInfoDialog::onMountingPointAssetChanged) &&
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainScheduleChanged,
|
||||
this, &MountingPointInfoDialog::onMainScheduleChanged)
|
||||
))
|
||||
return false;
|
||||
|
||||
m_ui->lblNameEntry->setText(QString::fromStdString(mountingPointData.name()));
|
||||
m_ui->lblTypeEntry->setText(toString(mountingPointData.mountingPointTypeId()));
|
||||
|
||||
if (mountingPointData.mountingPointTypeId() != MountingPointType::OutdoorCamera &&
|
||||
mountingPointData.mountingPointTypeId() != MountingPointType::MeteoDataUnit &&
|
||||
mountingPointData.mountingPointTypeId() != MountingPointType::VirtualIPS)
|
||||
{
|
||||
// searching path backwards until we find a building structure element
|
||||
QMap<StructureElementType, QString> names;
|
||||
for (int parentId = mountingPointData.path().size() - 1; parentId >= 0; --parentId)
|
||||
{
|
||||
StructureElement parent;
|
||||
m_dtc->getStructureElementById(mountingPointData.path().at(parentId), parent);
|
||||
names[parent.structureElementTypeId()] = QString::fromStdString(parent.displayName().size() > 0 ? parent.displayName() : parent.name());
|
||||
|
||||
if (StructureElementType::Building == parent.structureElementTypeId().underlying())
|
||||
break;
|
||||
}
|
||||
|
||||
// Building lbl
|
||||
m_ui->lblBuildingEntry->setText(names.value(StructureElementType::Building));
|
||||
m_ui->lblPosition->hide();
|
||||
m_ui->lblPositionEntry->hide();
|
||||
|
||||
// Floor lbl
|
||||
if (names.contains(StructureElementType::Floor))
|
||||
m_ui->lblFloorEntry->setText(names.value(StructureElementType::Floor));
|
||||
else
|
||||
{
|
||||
m_ui->lblFloorEntry->hide();
|
||||
m_ui->lblFloor->hide();
|
||||
}
|
||||
|
||||
// Room lbl
|
||||
if (names.contains(StructureElementType::Room))
|
||||
m_ui->lblRoomEntry->setText(names.value(StructureElementType::Room));
|
||||
else
|
||||
{
|
||||
m_ui->lblRoomEntry->hide();
|
||||
m_ui->lblRoom->hide();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// hide what isn't needed
|
||||
m_ui->lblBuildingEntry->hide();
|
||||
m_ui->lblBuilding->hide();
|
||||
m_ui->lblFloorEntry->hide();
|
||||
m_ui->lblFloor->hide();
|
||||
m_ui->lblRoomEntry->hide();
|
||||
m_ui->lblRoom->hide();
|
||||
|
||||
MainStructureElement mainStructure = m_dtc->mainStructureElement(mountingPointData.mainStructureElementId());
|
||||
m_ui->lblPositionEntry->setText(LtsCoordTrans::mgrsFromGeographic(mainStructure.geoPosition().lon(),
|
||||
mainStructure.geoPosition().lat()));
|
||||
}
|
||||
|
||||
if (mountingPointData.mountingPointTypeId() == MountingPointType::OutdoorCamera ||
|
||||
mountingPointData.mountingPointTypeId() == MountingPointType::IndoorCamera)
|
||||
{
|
||||
connect(m_ui->pbShowStream, &QToolButton::clicked, this, &MountingPointInfoDialog::onShowStream);
|
||||
m_ui->pbShowStream->setVisible(m_avmIfc->hasAvsSession() && m_avmIfc->avaSession()->isEstablished());
|
||||
m_ui->pbAnnouncement->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(m_ui->pbAnnouncement, &QToolButton::clicked, this, &MountingPointInfoDialog::onAnnouncement);
|
||||
m_ui->pbShowStream->hide();
|
||||
m_ui->pbAnnouncement->setVisible(m_avmIfc->hasAvsSession() && m_avmIfc->avaSession()->isEstablished());
|
||||
}
|
||||
setIsIncluded(m_dtc->mainSchedule(m_scheduleId));
|
||||
|
||||
// set the asset (if possible)
|
||||
QMap<qint32, MountingPointAsset> mpAssets = m_dtc->mountingPointAssets();
|
||||
for (auto it = mpAssets.begin(); it != mpAssets.end(); ++it)
|
||||
{
|
||||
if (it.value().structureElementId() == m_mountingPointId)
|
||||
{
|
||||
showAsset(m_dtc->instrumentationAsset(it.value().assetId()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (mountingPointData.mountingPointTypeId().underlying())
|
||||
{
|
||||
case InfrastructureManagement::MountingPointType::BuildingSensorModule:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Building_Sensor_Module"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::BuildingControlUnit:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Building_Control_Unit"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::OutdoorCamera:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Outdoor_Camera"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::IndoorCamera:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Indoor_Camera"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::OutdoorIPS:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Outdoor_IPS"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::IndoorIPS:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Indoor_IPS"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::MeteoDataUnit:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Meteo_Data_Unit"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::AnnouncementUnit:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Announcement_Unit"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::VirtualIPS:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Virtual_IPS"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::EffectGenerationControlUnit:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Effect_Generation_Control_Unit"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::BuildingNetworkSwitch:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Building_Network_Switch_Control_Unit"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::OutdoorControlUnit:
|
||||
setOnlineHelpFilename(QStringLiteral("Info_Dialog-Outdoor_Control_Unit"));
|
||||
break;
|
||||
case InfrastructureManagement::MountingPointType::Unknown:
|
||||
default:
|
||||
WARNING_LOG(m_logger) << "Unknown MountingPointType found for assetId " << m_assetId << ": " << toString(mountingPointData.mountingPointTypeId());
|
||||
break;
|
||||
} // switch
|
||||
|
||||
DEBUG_LOG(m_logger) << "Initializing MountingPointInfoDialog done :)";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &data, DataModification modType)
|
||||
{
|
||||
if (data.id() != m_assetId)
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
removeAsset();
|
||||
else
|
||||
showAsset(data);
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::onMountingPointAssetChanged(const InfrastructureManagement::MountingPointAsset &data, DataModification modType)
|
||||
{
|
||||
if (data.structureElementId() != m_mountingPointId)
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
removeAsset();
|
||||
else
|
||||
showAsset(m_dtc->instrumentationAsset(data.assetId()));
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::onMainScheduleChanged(const InfrastructureManagement::MainSchedule &data, DataModification modType)
|
||||
{
|
||||
if (data.id() != m_scheduleId ||
|
||||
modType != DataModification::eModified)
|
||||
return;
|
||||
|
||||
setIsIncluded(data);
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::onShowStream() const
|
||||
{
|
||||
if (!m_avmIfc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "m_avmIfc is not loaded.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_avmIfc->showCamera(/*m_session->baseLayoutWidget()*/nullptr, m_mountingPointId);
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::onAnnouncement() const
|
||||
{
|
||||
if (!m_avmIfc)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "m_avmIfc is not loaded.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_avmIfc->showAnnouncementUnit(m_mountingPointId);
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::showAsset(const InfrastructureManagement::InstrumentationAsset &asset)
|
||||
{
|
||||
removeAsset();
|
||||
DEBUG_LOG(m_logger) << "Showing new asset";
|
||||
|
||||
m_assetId = asset.id();
|
||||
|
||||
addAssetProperty(tr("Name"), QString::fromStdString(asset.name()));
|
||||
addAssetProperty(tr("State"), toString(asset.assetStateId()));
|
||||
addAssetProperty(tr("Hostname"), QString::fromStdString(asset.hostname()));
|
||||
addAssetProperty(tr("Barcode"), QString::fromStdString(asset.barcode()));
|
||||
|
||||
const QJsonObject dynamicProps(QJsonDocument::fromJson(QByteArray::fromStdString(asset.properties())).object());
|
||||
|
||||
for (auto it = dynamicProps.begin(); it != dynamicProps.end(); ++it)
|
||||
{
|
||||
if (it.key() == QStringLiteral("hasSpeaker") && it.value() == true)
|
||||
{
|
||||
// Show Button Announcement
|
||||
connect(m_ui->pbAnnouncement, &QToolButton::clicked, this, &MountingPointInfoDialog::onAnnouncement);
|
||||
m_ui->pbAnnouncement->setVisible(m_avmIfc->hasAvsSession() && m_avmIfc->avaSession()->isEstablished());
|
||||
}
|
||||
addAssetProperty(it.key(), jsonValToString(it.value()));
|
||||
}
|
||||
|
||||
m_ui->gbxAsset->show();
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::removeAsset()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Removing asset information";
|
||||
|
||||
m_assetId = -1;
|
||||
m_ui->gbxAsset->hide();
|
||||
|
||||
for (QLabel *lbl : qAsConst(m_dynamicAssetPropLabels))
|
||||
m_ui->gbxAsset->layout()->removeWidget(lbl);
|
||||
|
||||
qDeleteAll(m_dynamicAssetPropLabels);
|
||||
m_dynamicAssetPropLabels.clear();
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::addAssetProperty(const QString &propName, const QString &propValue)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Adding asset property "
|
||||
<< propName
|
||||
<< ':'
|
||||
<< propValue;
|
||||
|
||||
QLabel *lblPropName = new LtsWidgets::LtsElidedLabel(propName + QLatin1Char(':'));
|
||||
QLabel *lblPropValue = new QLabel(propValue);
|
||||
|
||||
m_dynamicAssetPropLabels.append(lblPropName);
|
||||
m_dynamicAssetPropLabels.append(lblPropValue);
|
||||
|
||||
QGridLayout *assetsLayout = static_cast<QGridLayout *>(m_ui->gbxAsset->layout());
|
||||
int row = assetsLayout->rowCount();
|
||||
|
||||
assetsLayout->addWidget(lblPropName, row, 0);
|
||||
assetsLayout->addWidget(lblPropValue, row, 1);
|
||||
}
|
||||
|
||||
void MountingPointInfoDialog::setIsIncluded(const MainSchedule &schedule)
|
||||
{
|
||||
for (const MountingPointPlan ¤tPlan : schedule.elements())
|
||||
{
|
||||
if (currentPlan.structureElementId() == m_mountingPointId)
|
||||
{
|
||||
m_ui->lblIncludedEntry->setText(tr("Yes"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_ui->lblIncludedEntry->setText(tr("No"));
|
||||
}
|
||||
|
||||
QString MountingPointInfoDialog::jsonValToString(const QJsonValue &val) const
|
||||
{
|
||||
switch (val.type())
|
||||
{
|
||||
case QJsonValue::Bool:
|
||||
case QJsonValue::Double:
|
||||
case QJsonValue::String:
|
||||
return val.toVariant().toString();
|
||||
case QJsonValue::Array:
|
||||
return QString::fromUtf8(QJsonDocument(val.toArray()).toJson(QJsonDocument::Compact));
|
||||
case QJsonValue::Object:
|
||||
return QString::fromUtf8(QJsonDocument(val.toObject()).toJson(QJsonDocument::Compact));
|
||||
case QJsonValue::Null:
|
||||
case QJsonValue::Undefined:
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The MountingPointInfoDialog shows information about a single mounting point
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-01-12
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <Plugins/AudioVideoManagement/avm_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
class QJsonValue;
|
||||
class QLabel;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MountingPointInfoDialog;
|
||||
}
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class MountingPointInfoDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MountingPointInfoDialog(int32_t mountingPointId, int32_t scheduleId, const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~MountingPointInfoDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<InfrastructureManagement::ForeignDataInterface> &ismIfc,
|
||||
const std::shared_ptr<AudioVideoManagement::ForeignDataInterface> &avmIfc);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &data, DataModification modType);
|
||||
void onMountingPointAssetChanged(const InfrastructureManagement::MountingPointAsset &data, DataModification modType);
|
||||
void onMainScheduleChanged(const InfrastructureManagement::MainSchedule &data, DataModification modType);
|
||||
void onShowStream() const;
|
||||
void onAnnouncement() const;
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
|
||||
void showAsset(const InfrastructureManagement::InstrumentationAsset &asset);
|
||||
void removeAsset();
|
||||
void addAssetProperty(const QString &propName, const QString &propValue);
|
||||
void setIsIncluded(const MainSchedule &schedule);
|
||||
QString jsonValToString(const QJsonValue &val) const;
|
||||
|
||||
private: // attributes
|
||||
Ui::MountingPointInfoDialog *m_ui;
|
||||
int32_t m_mountingPointId;
|
||||
int32_t m_assetId;
|
||||
int32_t m_scheduleId;
|
||||
QString m_menuGroup;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_ismIfc;
|
||||
std::shared_ptr<AudioVideoManagement::ForeignDataInterface> m_avmIfc;
|
||||
QVector<QLabel *> m_dynamicAssetPropLabels;
|
||||
LOGGER_T m_logger;
|
||||
}; // class MountingPointInfoDialog
|
||||
} // namespace InfrastructureManagement
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MountingPointInfoDialog</class>
|
||||
<widget class="QWidget" name="MountingPointInfoDialog">
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="7" column="0" colspan="2">
|
||||
<widget class="LtsWidgets::LtsElidedLabel" name="lblPosition">
|
||||
<property name="text">
|
||||
<string>Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QToolButton" name="pbAnnouncement">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../Styles/Light/resources/rme_light_style.qrc">
|
||||
<normaloff>:/style/announcement_menu.svg</normaloff>:/style/announcement_menu.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QToolButton" name="pbShowStream">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../Styles/Light/resources/rme_light_style.qrc">
|
||||
<normaloff>:/style/video_menu.svg</normaloff>:/style/video_menu.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="LtsWidgets::LtsElidedLabel" name="lblBuilding">
|
||||
<property name="text">
|
||||
<string>Building:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="LtsWidgets::LtsElidedLabel" name="lblIncluded">
|
||||
<property name="text">
|
||||
<string>Included:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="2">
|
||||
<widget class="LtsWidgets::LtsElidedLabel" name="lblRoom">
|
||||
<property name="text">
|
||||
<string>Room:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblIcon">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="LtsWidgets::LtsElidedLabel" name="lblFloor">
|
||||
<property name="text">
|
||||
<string>Floor:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="LtsWidgets::LtsElidedLabel" name="lblType">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QLabel" name="lblNameEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><NAME></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="lblTypeEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><TYPE></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="4">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="4">
|
||||
<widget class="QGroupBox" name="gbxAsset">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Equipped asset</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2" colspan="2">
|
||||
<widget class="QLabel" name="lblPositionEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><POSITION></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2" colspan="2">
|
||||
<widget class="QLabel" name="lblRoomEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><ROOM></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2" colspan="2">
|
||||
<widget class="QLabel" name="lblFloorEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><FLOOR></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2" colspan="2">
|
||||
<widget class="QLabel" name="lblBuildingEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><TYPE></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2" colspan="2">
|
||||
<widget class="QLabel" name="lblIncludedEntry">
|
||||
<property name="text">
|
||||
<string notr="true"><INCLUDED></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsElidedLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>LtsWidgets/lts_elided_label.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../../../../Styles/Light/resources/rme_light_style.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
+811
@@ -0,0 +1,811 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The MountingPointListDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#include "ism_mounting_point_list_dialog.h"
|
||||
#include "ui_ism_mounting_point_list_dialog.h"
|
||||
#include "ism_mounting_point_list_dialog_model.h"
|
||||
#include "ism_mounting_point_list_dialog_checkbox_proxy_model.h"
|
||||
#include "ism_mounting_point_list_dialog_checkbox_delegate.h"
|
||||
#include "ism_mounting_point_list_dialog_list_sort_model.h"
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <LtsUtilsCore/dds_vector.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <InfrastructureManagement/ism_operator_rights.h>
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_helper.h> // getVisibleTypesOfFilter
|
||||
#include <SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <SituationMap/Map/map.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
|
||||
#include <QItemDelegate>
|
||||
#include <QTreeView>
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <QHeaderView>
|
||||
#include <QScrollBar>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
using namespace LtsWidgets;
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
/// DummyLtsColumnFilterProxyModel
|
||||
class DummyLtsColumnFilterProxyModel : public LtsColumnFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
void setColumnStringFilter(const QString &, int ) override {}
|
||||
void setColumnDataFilter(const QVariant &newFilterData, int column) override
|
||||
{
|
||||
emit signalSetColumnDataFilter(newFilterData, column);
|
||||
}
|
||||
|
||||
bool filterAcceptsRow(int /*source_row*/, const QModelIndex &/*source_parent*/) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
signals:
|
||||
void signalSetColumnDataFilter(const QVariant &newFilterData, int column);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// MountingPointListDialog
|
||||
MountingPointListDialog::MountingPointListDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_ismGuiIfc(nullptr)
|
||||
, m_mapGuiInterface(nullptr)
|
||||
, m_typeFilterColumn(0)
|
||||
, m_typeFilterRow(0)
|
||||
, m_ddsSelector(nullptr)
|
||||
, m_scheduleId(-1)
|
||||
, m_ui(new Ui::MountingPointListDialog)
|
||||
, m_logger(getLogger("MountingPointListDialog"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
m_ui->setupUi(this);
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Mounting_Point_List"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &MountingPointListDialog::onPrint);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
MountingPointListDialog::~MountingPointListDialog()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_mapGuiInterface->removeObjectIndicator();
|
||||
m_mapGuiInterface->setSkipMapObjectSelectionDialog(false);
|
||||
|
||||
if (m_ismGuiIfc)
|
||||
m_ismGuiIfc->setSelector(nullptr);
|
||||
|
||||
if (m_buildingComponentSettings)
|
||||
m_buildingComponentSettings->removeChangedCallback(this);
|
||||
|
||||
m_mapGuiInterface->setResourceManagerMode(m_oldResourceManagerMode);
|
||||
|
||||
delete m_ui;
|
||||
delete m_ddsSelector;
|
||||
delete m_requestHelper;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void MountingPointListDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, m_dtc->mainSchedule(m_scheduleId), tr("Mounting Point List"));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Unmount"));
|
||||
}
|
||||
|
||||
bool MountingPointListDialog::init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface,
|
||||
InfrastructureManagement::ForeignResourceManagementGuiInterface *ismGuiIfc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &mapIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> fltBuildingComponentIfc)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
m_dataIfc = dataInterface;
|
||||
m_session = session;
|
||||
m_mapGuiInterface = mapIfc;
|
||||
m_ismGuiIfc = ismGuiIfc;
|
||||
m_fltBuildingComponentIfc = fltBuildingComponentIfc;
|
||||
|
||||
disconnect(m_ui->mountingPointListView);
|
||||
disconnect(this);
|
||||
|
||||
if (!m_ftc->enableInstrumentationAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT InstrumentationAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableInstrumentationAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT enableInstrumentationAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableInstrumentationAssetRemove())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT enableInstrumentationAssetRemove of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableInstrumentationAssetUnmount())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT enableInstrumentationAssetUnmount of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableMountingPointAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MountingPointAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableMountingPointAssetRemove())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MountingPointAssetRemove of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableStructureElementModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT enableStructureElementModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
delete m_sourceModel;
|
||||
m_sourceModel = new MountingPointListDialogModel(this);
|
||||
const QSet<MountingPointType> filters = { MountingPointType::BuildingSensorModule,
|
||||
MountingPointType::OutdoorCamera,
|
||||
// MountingPointType::BuildingControlUnit,
|
||||
MountingPointType::IndoorCamera,
|
||||
MountingPointType::OutdoorIPS,
|
||||
MountingPointType::IndoorIPS,
|
||||
MountingPointType::EffectGenerationControlUnit,
|
||||
#ifndef GUEZ_MODE
|
||||
MountingPointType::AnnouncementUnit,
|
||||
MountingPointType::BuildingNetworkSwitch
|
||||
#endif
|
||||
};
|
||||
m_sourceModel->setMntPointFilterTypes(filters);
|
||||
if (!m_sourceModel->initModel(m_dtc, m_dataIfc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
delete m_sourceModel;
|
||||
m_sourceModel = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_sourceModel, &MountingPointListDialogModel::changesMade,
|
||||
this, &MountingPointListDialog::slotChangesMade); /*[this]
|
||||
{
|
||||
slotChangesMade();
|
||||
});*/
|
||||
|
||||
delete m_sortProxyModel;
|
||||
m_sortProxyModel = new MountingPointListSortModel(this);
|
||||
m_sortProxyModel->setTypeFilter(filters);
|
||||
m_sortProxyModel->setSourceModel(m_sourceModel);
|
||||
|
||||
delete m_checkboxProxyModel;
|
||||
m_checkboxProxyModel = new CheckboxProxyModel;
|
||||
|
||||
|
||||
|
||||
/* OKAY, get this...:
|
||||
* We need LtsDataView's filtering mechanism. But the CheckBoxProxyModel needs to be the *last* Proxy Model
|
||||
* because it checks which Checkbox state a leaf's parent and its parent's parents has. If the LtsDataView
|
||||
* does the filtering, then the CheckboxProxyModel doesn't know what lines were hidden, so the Checkbox
|
||||
* states don't match.
|
||||
* If LtsDataView is given an LtsColumnFilterProxyModel instead of an ItemModel, it will not create a
|
||||
* LtsColumnFilterProxyModel for filtering, but use the given one instead.
|
||||
* Here's the super hacky solution:
|
||||
* 1. First we need a barebones LtsColumnFilterProxyModel as the LAST model instance, for the LtsDataView,
|
||||
* which just sends a signa - when setColumnStringFilter was called - to ...
|
||||
* 2. the REAL LtsColumnFilterProxyModel, which does the real filtering. It needs to be put BEFORE
|
||||
* the CheckboxFilterProxy. So the CheckboxFilterProxy will see ALL rows that remain visible.
|
||||
*/
|
||||
|
||||
// Model => Sort => rcfpm => CheckboxProxy => dcfpm => View
|
||||
|
||||
m_sortProxyModel->setRecursiveFilteringEnabled(true); // non-leafs don't have a type to filter by, so tell LtsDataView's filter proxy model to ignore these and still show them if at least ONE child (recursive) of a non-leaf is visible
|
||||
|
||||
|
||||
LtsColumnFilterProxyModel *rcfpm = new LtsColumnFilterProxyModel; // the REAL filter, put before CheckboxFilterProxy.
|
||||
rcfpm->setSourceModel(m_sortProxyModel);
|
||||
rcfpm->setRecursiveFilteringEnabled(true); // non-leafs don't have a type to filter by, so tell LtsDataView's filter proxy model to ignore these and still show them if at least ONE child (recursive) of a non-leaf is visible
|
||||
|
||||
|
||||
m_checkboxProxyModel->setSourceModel(rcfpm);
|
||||
|
||||
|
||||
DummyLtsColumnFilterProxyModel *dcfpm = new DummyLtsColumnFilterProxyModel; // the fake filter, put as LAST instance. Source model is the CheckboxFilterProxy.
|
||||
dcfpm->setRecursiveFilteringEnabled(true); // non-leafs don't have a type to filter by, so tell LtsDataView's filter proxy model to ignore these and still show them if at least ONE child (recursive) of a non-leaf is visible
|
||||
connect(dcfpm, &DummyLtsColumnFilterProxyModel::signalSetColumnDataFilter,
|
||||
rcfpm, &LtsColumnFilterProxyModel::onSetColumnDataFilter);
|
||||
|
||||
dcfpm->setSourceModel(m_checkboxProxyModel);
|
||||
|
||||
m_ui->mountingPointListView->setModel(dcfpm);
|
||||
|
||||
// Needed as otherwise changes to the model do not affect the visibility of Rooms and Levels.
|
||||
connect(m_sourceModel, &MountingPointListDialogModel::dataChanged, m_sortProxyModel, &MountingPointListSortModel::invalidateFilter);
|
||||
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SystemConfiguration))
|
||||
{
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load, this, &MountingPointListDialog::onUnmountButtonClicked);
|
||||
m_buttonBox->setIcon(LtsWidgets::DialogButton::Load, QIcon(QLatin1String("icon:fixed_video_announcement.svg")));
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(false);
|
||||
}
|
||||
// connect signals of TableView/CustomView: (for MapObjectIndicator
|
||||
connect(m_ui->mountingPointListView, &LtsDataView::LtsDataView::clicked, this, &MountingPointListDialog::onDataViewClicked);
|
||||
connect(m_ui->mountingPointListView, &LtsDataView::LtsDataView::signalEntered, this, &MountingPointListDialog::onDataViewEntered);
|
||||
|
||||
|
||||
//------------- Filter ----------------
|
||||
// SWPÄ 2/22 / GUEZE-1478:
|
||||
// Diese Filter werden ersetzt durch übergeordnete BuildingComponentnFilter (Extras | SituationMap | BuildingComponent)
|
||||
|
||||
// subscribe to Filter:
|
||||
if (m_fltBuildingComponentIfc)
|
||||
{
|
||||
const int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
m_buildingComponentSettings = m_fltBuildingComponentIfc->buildingComponentSettingsForOperator(operatorId, m_session->workspaceId());
|
||||
if (m_buildingComponentSettings)
|
||||
m_buildingComponentSettings->addChangedCallback(this); // will call onBuildingComponentSettingsChanged
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " addChangedCallback fltBuildingComponentIfc failed";
|
||||
#ifdef LTS_DEBUG
|
||||
Q_ASSERT(false);
|
||||
#endif // LTS_DEBUG
|
||||
}
|
||||
// call on init:
|
||||
onBuildingComponentSettingsChanged();
|
||||
}else
|
||||
{
|
||||
ERROR_LOG(m_logger) << "No BuildingCOmponentIfc ";
|
||||
}
|
||||
|
||||
// honor visibilityChanged (dialog toogles between foreground/background)
|
||||
connect(this, &MountingPointListDialog::visibilityChanged, this, &MountingPointListDialog::onVisibilityChanged);
|
||||
|
||||
// show first tree level when activating the dialog
|
||||
m_ui->mountingPointListView->treeView()->expandToDepth(0);
|
||||
|
||||
delete m_ddsSelector;
|
||||
m_ddsSelector = nullptr;
|
||||
|
||||
m_ddsSelector = new DdsSelector(dtc, ftc, m_dataIfc, m_requestHelper);
|
||||
|
||||
// always select from the map when the dialog is visible
|
||||
m_ismGuiIfc->setSelector(m_ddsSelector);
|
||||
|
||||
|
||||
// SWPÄ GUEZE-1478 (?)
|
||||
// Mit Aufschalten des Dialog wird umgeschaltet auf Modus SituationMap::ResourceManagerMode::RMM_PlanDefinitionView
|
||||
// mit RMM_PlanDefinitionView sollte die Notification disabled werden...
|
||||
// bis Ende des Dialoges...
|
||||
m_oldResourceManagerMode = m_mapGuiInterface->resourceManagerMode();
|
||||
|
||||
// since switching _to_ RMM_PlanDefinitionView could be timeconsuming:
|
||||
// (and give the GlobalWaitDialog time being displayed)
|
||||
QTimer::singleShot(100, this, [this] () {
|
||||
m_mapGuiInterface->setResourceManagerMode(SituationMap::ResourceManagerMode::RMM_PlanDefinitionView);
|
||||
});
|
||||
|
||||
m_mapGuiInterface->setSkipMapObjectSelectionDialog(true);
|
||||
|
||||
|
||||
m_scheduleId = m_dataIfc->scheduleId();
|
||||
connect(m_dataIfc.get(), &ForeignDataInterface::scheduleIdChanged,
|
||||
this, &MountingPointListDialog::onScheduleIdChanged);
|
||||
|
||||
m_ui->mountingPointListView->setContextMenuPolicyPerView(LtsDataView::LtsDataView::Page::TABLE, Qt::CustomContextMenu);
|
||||
connect(m_ui->mountingPointListView->treeView(), &QTreeView::customContextMenuRequested,
|
||||
this, &MountingPointListDialog::onCustomContextMenu);
|
||||
|
||||
m_ui->mountingPointListView->treeView()->setColumnWidth(0, 500);
|
||||
m_ui->mountingPointListView->treeView()->setColumnWidth(1, 300);
|
||||
m_ui->mountingPointListView->treeView()->setColumnWidth(2, 300);
|
||||
m_ui->mountingPointListView->treeView()->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
|
||||
|
||||
m_ui->mountingPointListView->searchView()->setColumnWidth(0, 500);
|
||||
m_ui->mountingPointListView->searchView()->setColumnWidth(1, 300);
|
||||
m_ui->mountingPointListView->searchView()->setColumnWidth(2, 300);
|
||||
m_ui->mountingPointListView->searchView()->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
|
||||
connect(m_ui->mountingPointListView->searchView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(m_ui->mountingPointListView->treeView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
m_ui->mountingPointListView->treeView()->setItemDelegateForColumn(MountingPointListDialogModel::Columns::NAME, new CheckboxDelegate);
|
||||
|
||||
// connect onEscapePressed of Map:
|
||||
if (m_mapGuiInterface && m_mapGuiInterface->map())
|
||||
connect(m_mapGuiInterface->map().data(), &SituationMap::Map::escapePressed,
|
||||
this, &MountingPointListDialog::onEscapePressed, Qt::UniqueConnection);
|
||||
|
||||
// InfoMountButton:
|
||||
connect(m_ui->tbMountMode, &QToolButton::clicked,
|
||||
this, &MountingPointListDialog::onInfoMountButtonClicked, Qt::UniqueConnection);
|
||||
onUpdateInfoMountButtonAndBehaviour();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void MountingPointListDialog::getMountingPointPlanData(const QModelIndex &index, std::vector<MountingPointPlan>&modify, const QHash<int, MountingPointPlan> &mppMap)
|
||||
{
|
||||
NGLTreeItem *item = m_sourceModel->privateData(index);
|
||||
if (!item)
|
||||
return;
|
||||
if (item->data().canConvert<SimpleMountingPointData>())
|
||||
{
|
||||
const SimpleMountingPointData &data = item->data().value<SimpleMountingPointData>();
|
||||
DEBUG_LOG(m_logger) << "Item: " << m_sourceModel->data(index, Qt::DisplayRole).toString()
|
||||
<< ", Structure Element Id: " << data.id;
|
||||
|
||||
if (mppMap.contains(data.id))
|
||||
{
|
||||
if (data.aimState != mppMap[data.id].mountingPointState())
|
||||
modify.push_back(MountingPointPlan(data.id, data.aimState));
|
||||
}
|
||||
else if (data.aimState != MountingPointState_def::Idle)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Not available in Map. Desired: " << data.aimState;
|
||||
modify.push_back(MountingPointPlan(data.id, data.aimState));
|
||||
}
|
||||
}
|
||||
for (int i =0 ; i< m_sourceModel->rowCount(index); i++ )
|
||||
getMountingPointPlanData(m_sourceModel->index(i, 0, index), modify, mppMap);
|
||||
}
|
||||
|
||||
bool MountingPointListDialog::hasMountingPointMountedAsset(const QModelIndex &index)
|
||||
{
|
||||
NGLTreeItem *treeItem = m_sourceModel->privateData(mapToSourciest(index));
|
||||
if (!treeItem)
|
||||
return false;
|
||||
QVariant v = treeItem->data();
|
||||
if (v.canConvert<SimpleMountingPointData>())
|
||||
{
|
||||
// MountingPoint:
|
||||
const SimpleMountingPointData itemData = v.value<SimpleMountingPointData>();
|
||||
int assetId = m_dtc->getMountedAssetId(itemData.id);
|
||||
return !(assetId == -1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onMountingPointPlanModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onInstrumentationAssetModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onInstrumentationAssetUnmountReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onMountingPointAssetModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onMountingPointAssetRemoveReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onBuildingComponentSettingsChanged()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
// update view via m_sortProxyModel:
|
||||
|
||||
if (!m_buildingComponentSettings)
|
||||
return;
|
||||
const FilterManagement::BuildingComponentSettings::BldCmpSettings &bldCmpSettings =
|
||||
m_buildingComponentSettings->bldCmpSettings();
|
||||
|
||||
// 1) setTypeFilter:
|
||||
{
|
||||
const QSet<MountingPointType> visibleTypes = FilterManagement::getVisibleTypesOfFilter(bldCmpSettings);
|
||||
m_sortProxyModel->setTypeFilter(visibleTypes);
|
||||
}
|
||||
|
||||
// 2) floor:
|
||||
{
|
||||
// '-10' is floorId of Exterior / Outdoor
|
||||
// Filter has HIDDEN floorIds
|
||||
// (good reason: if filter not available (or nothing is checked), show all item on map...)
|
||||
// so translate here to visibleFloors:
|
||||
const QSet<int> &hiddenFloorIds = bldCmpSettings.buildingSettings.hiddenFloorIds;
|
||||
const QSet<int> &availableFloors = m_sourceModel->getAvailableFloors();
|
||||
QSet<int> visibleFloors;
|
||||
for (int floor : availableFloors)
|
||||
if (!hiddenFloorIds.contains(floor))
|
||||
visibleFloors.insert(floor);
|
||||
|
||||
// qCritical() << " hiddenFloorIds" << hiddenFloorIds;
|
||||
// qCritical() << " availableFloors" << availableFloors;
|
||||
// qCritical() << " visibleFloors" << visibleFloors;
|
||||
|
||||
m_sortProxyModel->setFloorFilter(visibleFloors);
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool MountingPointListDialog::apply()
|
||||
{
|
||||
std::vector<MountingPointPlan> modify;
|
||||
const QModelIndex root = m_sourceModel->getIndexOfVisibleRootItem();
|
||||
if (!root.isValid())
|
||||
return false;
|
||||
|
||||
MainSchedule mainSchedule = m_dataIfc->mainSchedule(m_dataIfc->scheduleId());
|
||||
|
||||
QHash<int,MountingPointPlan> mppMap;
|
||||
for(const auto &elem : mainSchedule.elements())
|
||||
mppMap[elem.structureElementId()] = elem;
|
||||
|
||||
getMountingPointPlanData(root, modify, mppMap);
|
||||
|
||||
if (modify.empty())
|
||||
return true;
|
||||
|
||||
MountingPointPlanModifyRequest req(m_dataIfc->scheduleId(), modify);
|
||||
return m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->mountingPointPlanModifyRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onPrint()
|
||||
{
|
||||
MainSchedule ms = m_dtc->mainSchedule(m_dataIfc->scheduleId());
|
||||
QString header;
|
||||
header += QStringLiteral("<p>");
|
||||
header += tr("Instrumentation Plan: %1").arg(QString::fromStdString(ms.name()));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += tr("Status: %1").arg(toString(ms.statusId()));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += tr("Created: %1").arg(DTG::toStringMSec(ms.timeCreated()));
|
||||
header += QStringLiteral("<br/>");
|
||||
if (ms.timeStart().is_set())
|
||||
header += tr("START: %1").arg(DTG::toStringMSec(ms.timeStart().get()));
|
||||
else
|
||||
header += tr("START: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral(" - ");
|
||||
if (ms.timeEnd().is_set())
|
||||
header += tr("END: %1").arg(DTG::toStringMSec(ms.timeEnd().get()));
|
||||
else
|
||||
header += tr("END: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += QStringLiteral("</p>");
|
||||
|
||||
m_ui->mountingPointListView->expandAll();
|
||||
|
||||
LtsPrinting::printView(m_session, this, m_ui->mountingPointListView->treeView(), header);
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onScheduleIdChanged(int32_t scheduleId)
|
||||
{
|
||||
if (scheduleId == m_scheduleId)
|
||||
return;
|
||||
|
||||
// scheduleId changed, data is maybe invalid -> close dialog:
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onVisibilityChanged(bool visible)
|
||||
{
|
||||
Q_UNUSED(visible);
|
||||
// maybe dialog is put to background -> leave mount mode:
|
||||
onUpdateInfoMountButtonAndBehaviour();
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onCustomContextMenu(QPoint pos)
|
||||
{
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
contextMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->expandAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->collapseAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->addSeparator();
|
||||
QModelIndex index = m_ui->mountingPointListView->treeView()->indexAt(pos);
|
||||
bool hasChildren = m_ui->mountingPointListView->treeView()->model()->rowCount(index) > 0;
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,13,0)
|
||||
m_ui->mountingPointListView->treeView()->expand(index);
|
||||
#else
|
||||
m_ui->mountingPointListView->treeView()->expandRecursively(index);
|
||||
#endif
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
m_ui->mountingPointListView->treeView()->collapse(index);
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->popup(m_ui->mountingPointListView->treeView()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onDataViewClicked(const QModelIndex &mi)
|
||||
{
|
||||
m_clickedObjectStore.reset();
|
||||
onDataViewEntered(mi);
|
||||
|
||||
// suppress Entered for a while:
|
||||
m_clickedObjectStore.timestampMsec = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
bool enabled = LtsSessionData::LtsSessionData::getInstance()->hasOperatorRight(OperatorRights::SystemConfiguration);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setEnabled(hasMountingPointMountedAsset(mi) && enabled);
|
||||
}
|
||||
|
||||
QModelIndex MountingPointListDialog::mapToSourciest(const QModelIndex &index)
|
||||
{
|
||||
QModelIndex currentIndex = index;
|
||||
const QAbstractItemModel *model = index.model();
|
||||
//qWarning() << "start" << model << currentIndex;
|
||||
|
||||
while (true)
|
||||
{
|
||||
const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel *>(model);
|
||||
|
||||
if (proxyModel == nullptr)
|
||||
break;
|
||||
|
||||
model = proxyModel->sourceModel();
|
||||
currentIndex = proxyModel->mapToSource(currentIndex);
|
||||
//qWarning() << "new" << model << currentIndex;
|
||||
}
|
||||
|
||||
//qWarning() << "done" << model << currentIndex;
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onDataViewEntered(const QModelIndex & mi)
|
||||
{
|
||||
if ( (QDateTime::currentMSecsSinceEpoch() - m_clickedObjectStore.timestampMsec) < 500)
|
||||
return;
|
||||
|
||||
const QModelIndex &theIndex(mapToSourciest(mi));
|
||||
NGLTreeItem *treeItem = m_sourceModel->privateData(theIndex);
|
||||
if (!treeItem)
|
||||
return;
|
||||
|
||||
const QVariant v(treeItem->data());
|
||||
if (v.canConvert<SimpleStructureElementData>())
|
||||
{
|
||||
// Building:
|
||||
const SimpleStructureElementData itemData = v.value<SimpleStructureElementData>();
|
||||
m_clickedObjectStore.mot = SituationMap::MapObjectType::MOT_Building;
|
||||
m_clickedObjectStore.entityId = itemData.mseId;
|
||||
|
||||
}
|
||||
else if (v.canConvert<SimpleMountingPointData>())
|
||||
{
|
||||
// MountingPoint:
|
||||
const SimpleMountingPointData itemData = v.value<SimpleMountingPointData>();
|
||||
m_clickedObjectStore.mot = SituationMap::MapObjectType::MOT_MountingPoint;
|
||||
m_clickedObjectStore.entityId = itemData.id;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_clickedObjectStore.reset();
|
||||
}
|
||||
|
||||
if (m_clickedObjectStore.entityId>=0)
|
||||
{
|
||||
m_mapGuiInterface->objectIndicatorToMapObject(m_clickedObjectStore.mot, m_clickedObjectStore.entityId, true);
|
||||
if (QGuiApplication::keyboardModifiers().testFlag(Qt::KeyboardModifier::ShiftModifier))
|
||||
m_mapGuiInterface->centerMapToMapObject(m_clickedObjectStore.mot, m_clickedObjectStore.entityId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onEscapePressed()
|
||||
{
|
||||
if (!m_mapGuiInterface)
|
||||
return;
|
||||
m_mapGuiInterface->removeObjectIndicator();
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onUnmountButtonClicked()
|
||||
{
|
||||
if (m_ui->mountingPointListView->selectionModel()->selectedRows().size() < 1)
|
||||
return;
|
||||
|
||||
NGLTreeItem *treeItem = m_sourceModel->privateData(mapToSourciest(m_ui->mountingPointListView->currentIndex()));
|
||||
if (!treeItem)
|
||||
return;
|
||||
|
||||
const QVariant v = treeItem->data();
|
||||
if (v.canConvert<SimpleMountingPointData>())
|
||||
{
|
||||
const SimpleMountingPointData itemData = v.value<SimpleMountingPointData>();
|
||||
|
||||
LtsWidgets::Button button = LtsWidgets::LtsMessageDialog::showMessage(
|
||||
this, tr("Do you really want to unmount asset on selected mounting point?"), tr("Unmount Assets"), LtsWidgets::Behaviour::Modal,
|
||||
{ LtsWidgets::Button::Yes, LtsWidgets::Button::No });
|
||||
if (button == LtsWidgets::Button::Yes)
|
||||
{
|
||||
const int assetId = m_dtc->getMountedAssetId(itemData.id);
|
||||
if (assetId > 0)
|
||||
{
|
||||
InstrumentationAssetUnmountRequest req(assetId);
|
||||
bool ret = m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->instrumentationAssetUnmountRequest(req, this);
|
||||
});
|
||||
|
||||
if (!ret)
|
||||
WARNING_LOG(m_logger)<<" couldn't unmount asset on MountingPoinAsset id: "<<req.id();
|
||||
else
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load,false);
|
||||
}
|
||||
else // mounted asset id not found
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(
|
||||
this, tr("No mounted asset found on this mounting point"), tr("Unmount Assets"), LtsWidgets::Behaviour::Modal, LtsWidgets::Button::Ok);
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Load,false);
|
||||
}
|
||||
} // end if allow unmount asset
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger)<<" Couldn't convert to SimpleMountingPointData: ";
|
||||
}
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onInfoMountButtonClicked(bool)
|
||||
{
|
||||
// toggle btn and sitMap behaviour, but keep visibility in mind:
|
||||
|
||||
switch (m_infoMount) {
|
||||
case InfoMount::IM_INFO:
|
||||
m_infoMount = InfoMount::IM_MOUNT;
|
||||
break;
|
||||
case InfoMount::IM_MOUNT:
|
||||
m_infoMount = InfoMount::IM_INFO;
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
|
||||
onUpdateInfoMountButtonAndBehaviour();
|
||||
}
|
||||
|
||||
void MountingPointListDialog::onUpdateInfoMountButtonAndBehaviour()
|
||||
{
|
||||
// // maybe dialog is put to background and is hidden now -> leave mount mode:
|
||||
// // in that case switch to 'IM_INFO' tempoary:
|
||||
InfoMount infoMountTemp = m_infoMount;
|
||||
const bool bDialogIsVisi = this->isVisible();
|
||||
if (!bDialogIsVisi)
|
||||
infoMountTemp = InfoMount::IM_INFO;
|
||||
|
||||
switch (infoMountTemp) {
|
||||
case InfoMount::IM_INFO:
|
||||
{
|
||||
QColor backgroundColor = QToolButton().palette().window().color();
|
||||
QColor textColor = QGuiApplication::palette().color(QPalette::Text);
|
||||
QString style = QStringLiteral("QToolButton { background-color: rgb(%1,%2,%3); color: rgb(%4,%5,%6) }")
|
||||
.arg(backgroundColor.red()).arg(backgroundColor.green()).arg(backgroundColor.blue())
|
||||
.arg(textColor.red()).arg(textColor.green()).arg(textColor.blue());
|
||||
m_ui->tbMountMode->setText(tr("Info"));
|
||||
m_ui->tbMountMode->setStyleSheet(style);
|
||||
m_ui->tbMountMode->setToolTip(tr("Click on map object opens info dialog"));
|
||||
|
||||
m_ismGuiIfc->setSelector(nullptr);
|
||||
m_mapGuiInterface->setSkipMapObjectSelectionDialog(false);
|
||||
}
|
||||
break;
|
||||
case InfoMount::IM_MOUNT:
|
||||
{
|
||||
QColor color = QGuiApplication::palette().color(QPalette::Link);
|
||||
QString style = QStringLiteral("QToolButton { background-color: rgb(%1,%2,%3); color: white }").arg(
|
||||
QString::number(color.red()), QString::number(color.green()), QString::number(color.blue())
|
||||
);
|
||||
m_ui->tbMountMode->setStyleSheet(style);
|
||||
m_ui->tbMountMode->setText(tr("Map Selection"));
|
||||
m_ui->tbMountMode->setToolTip(tr("Click on map object toogles aim state"));
|
||||
|
||||
m_ismGuiIfc->setSelector(m_ddsSelector);
|
||||
m_mapGuiInterface->setSkipMapObjectSelectionDialog(true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// empty
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//( class ClickedObjectStore
|
||||
//------------------------------------------------------------------------------
|
||||
void MountingPointListDialog::ClickedObjectStore::reset()
|
||||
{
|
||||
mot = SituationMap::MapObjectType::MOT_Undefined;
|
||||
entityId = -1;
|
||||
timestampMsec = 0;
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
|
||||
#include "ism_mounting_point_list_dialog.moc"
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The MountingPointListDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
#include <InfrastructureManagement/Gui/ResourceManagement/MountingPointMapSelection/ism_dds_selector.h>
|
||||
#include <InfrastructureManagement/Gui/ResourceManagement/MountingPointMapSelection/ism_selector.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h> // honor current filter settings (menue SituationMap)
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h> // hold current filter settings (and for addCSubscriberCallback)
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsDataView/check_state_proxy_model.h>
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
#include <QItemDelegate>
|
||||
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class MountingPointListDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
enum class MapObjectType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class MountingPointListDialogModel;
|
||||
class MountingPointListSortModel;
|
||||
class CheckboxProxyModel;
|
||||
|
||||
|
||||
|
||||
class MountingPointListDialog final
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::MountingPointPlanModifyReplyHandler
|
||||
, protected Interface::Ftc::InstrumentationAssetUnmountReplyHandler
|
||||
, protected Interface::Ftc::StructureElementModifyReplyHandler
|
||||
, protected Interface::Ftc::InstrumentationAssetModifyReplyHandler
|
||||
, protected Interface::Ftc::MountingPointAssetModifyReplyHandler
|
||||
, protected Interface::Ftc::MountingPointAssetRemoveReplyHandler
|
||||
, protected FilterManagement::BuildingComponentSettings::SettingsChangedCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MountingPointListDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~MountingPointListDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface,
|
||||
InfrastructureManagement::ForeignResourceManagementGuiInterface *ismGuiIfc,
|
||||
const std::shared_ptr<SituationMap::ForeignGuiInterface> &mapIfc,
|
||||
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> fltBuildingComponentIfc
|
||||
);
|
||||
|
||||
void onMountingPointPlanModifyReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
void onInstrumentationAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onInstrumentationAssetUnmountReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
void onStructureElementModifyReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
void onMountingPointAssetModifyReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onMountingPointAssetRemoveReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
void onBuildingComponentSettingsChanged() override final;
|
||||
|
||||
void getMountingPointPlanData(const QModelIndex &index, std::vector<MountingPointPlan> &add, const QHash<int, MountingPointPlan> &mppMap);
|
||||
bool hasMountingPointMountedAsset(const QModelIndex &index);
|
||||
friend class MountingPointSelector;
|
||||
|
||||
private slots:
|
||||
void onVisibilityChanged(bool visible);
|
||||
void onPrint();
|
||||
void onScheduleIdChanged(int32_t scheduleId);
|
||||
void onCustomContextMenu(QPoint pos);
|
||||
|
||||
void onDataViewClicked(const QModelIndex &mi);
|
||||
void onDataViewEntered(const QModelIndex &mi);
|
||||
void onEscapePressed();
|
||||
void onUnmountButtonClicked();
|
||||
|
||||
void onInfoMountButtonClicked(bool);
|
||||
void onUpdateInfoMountButtonAndBehaviour();
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
bool apply() override final;
|
||||
bool isIncludedId(int32_t mountingPointId) const;
|
||||
QModelIndex mapToSourciest(const QModelIndex &index);
|
||||
|
||||
private: // attributes
|
||||
MountingPointListDialogModel *m_sourceModel{nullptr};
|
||||
MountingPointListSortModel *m_sortProxyModel{nullptr};
|
||||
CheckboxProxyModel *m_checkboxProxyModel{nullptr};
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<ForeignDataInterface> m_dataIfc;
|
||||
LtsUtils::RequestHelper *m_requestHelper{nullptr};
|
||||
QString m_menuGroup;
|
||||
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
ForeignResourceManagementGuiInterface *m_ismGuiIfc{nullptr};
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> m_mapGuiInterface;
|
||||
|
||||
struct ClickedObjectStore
|
||||
{
|
||||
SituationMap::MapObjectType mot {SituationMap::MapObjectType::MOT_Undefined};
|
||||
int entityId {-1};
|
||||
qint64 timestampMsec {-1};
|
||||
void reset();
|
||||
} m_clickedObjectStore;
|
||||
|
||||
unsigned int m_typeFilterColumn;
|
||||
unsigned int m_typeFilterRow;
|
||||
DdsSelector *m_ddsSelector{nullptr};
|
||||
int32_t m_scheduleId;
|
||||
|
||||
// click leads to a) InfoDialog or b) mounting/changing aimState (Idle, Equipped, Empty)
|
||||
enum class InfoMount
|
||||
{
|
||||
IM_INFO, ///! on Click on MapObject, normal map behaviour: info dialog
|
||||
IM_MOUNT ///! on Click on MapObject, change aim state
|
||||
}
|
||||
m_infoMount{InfoMount::IM_INFO};
|
||||
|
||||
SituationMap::ResourceManagerMode m_oldResourceManagerMode{SituationMap::ResourceManagerMode::Undefined};
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
|
||||
std::shared_ptr<FilterManagement::BuildingComponentSettings> m_buildingComponentSettings;
|
||||
|
||||
|
||||
Ui::MountingPointListDialog *m_ui{nullptr};
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class MountingPointListDialog
|
||||
} // namespace InfrastructureManagement
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MountingPointListDialog</class>
|
||||
<widget class="QWidget" name="MountingPointListDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>833</width>
|
||||
<height>478</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Asset Stocks</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="LtsDataView::LtsDataView" name="mountingPointListView" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="rootIsDecorated" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>439</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QToolButton" name="tbMountMode">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">mountMode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#include "ism_mounting_point_list_dialog_checkbox_delegate.h"
|
||||
#include "ism_mounting_point_list_dialog_model.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
CheckboxDelegate::CheckboxDelegate(QObject *parent)
|
||||
: QItemDelegate(parent)
|
||||
{}
|
||||
|
||||
|
||||
void CheckboxDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
QItemDelegate::paint(painter, option, index);
|
||||
|
||||
if (index.column() != MountingPointListDialogModel::Columns::NAME)
|
||||
return;
|
||||
|
||||
painter->save();
|
||||
painter->setClipRect(option.rect);
|
||||
painter->setClipping(true);
|
||||
|
||||
const QVariant value(index.data(Qt::UserRole + 1));
|
||||
if (value.isValid() && value.canConvert<int>())
|
||||
{
|
||||
QPixmap x(QStringLiteral(":/style/checkbox-multi-state.svg"));
|
||||
|
||||
switch (value.toInt())
|
||||
{
|
||||
case MountingPointState::Equipped:
|
||||
x = QPixmap(QStringLiteral(":/style/checkbox-true.svg"));
|
||||
break;
|
||||
case MountingPointState::Idle:
|
||||
x = QPixmap(QStringLiteral(":/style/checkbox-empty.svg"));
|
||||
break;
|
||||
case MountingPointState::Empty:
|
||||
x = QPixmap(QStringLiteral(":/style/checkbox-false.svg"));
|
||||
break;
|
||||
}
|
||||
|
||||
const QStyleOptionViewItem opt = setOptions(index, option);
|
||||
const QRect checkRect(QItemDelegate::doCheck(opt, opt.rect, /*value*/1));
|
||||
|
||||
painter->drawPixmap(checkRect.adjusted(3,0,3,0), x, QRect());
|
||||
//QItemDelegate::drawCheck(painter, opt, checkRect, Qt::CheckState::Checked); // test
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
} // namespace InfrastructureManagement
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "ism_mounting_point_list_dialog_checkbox_delegate.h"
|
||||
|
||||
#include <QItemDelegate>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class CheckboxDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CheckboxDelegate(QObject *parent = nullptr);
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
||||
};
|
||||
} // namespace InfrastructureManagement
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
#include "ism_mounting_point_list_dialog_checkbox_proxy_model.h"
|
||||
#include "ism_mounting_point_list_dialog_model.h"
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
Qt::ItemFlags CheckboxProxyModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return sourceModel()->flags(index); // delegate to source model for further processing if necessary
|
||||
|
||||
// Sets only the checkbox nodes on user checkable,
|
||||
// checkbox leaves must be handled in source model.
|
||||
QModelIndex sourceIndex = mapToSource(index);
|
||||
Qt::ItemFlags fl = sourceModel()->flags(sourceIndex);
|
||||
if (index.column() == 0)
|
||||
return fl | Qt::ItemIsUserCheckable;
|
||||
return fl;
|
||||
}
|
||||
|
||||
|
||||
QVariant CheckboxProxyModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return {};
|
||||
|
||||
const QModelIndex sourceIndex(mapToSource(index));
|
||||
|
||||
// delegate everything except CheckStateRole to source model
|
||||
if (role != (Qt::UserRole + 1))
|
||||
return sourceModel()->data(sourceIndex, role);
|
||||
|
||||
// delegate a leaf too with CheckStateRole to source model
|
||||
if (isLeaf(index))
|
||||
return sourceModel()->data(sourceIndex, role);
|
||||
|
||||
// delegate to source model for further processing of further columns if necessary
|
||||
if (index.column() != MountingPointListDialogModel::Columns::NAME)
|
||||
return sourceModel()->data(sourceIndex, role);
|
||||
|
||||
// sets the node checkboxes and decoration depending on the entries in the tree structure
|
||||
bool lastMpsSet = false; // std::optional >_>
|
||||
int lastMps = -2;
|
||||
int childCount = rowCount(index);
|
||||
for (int childRow = 0; childRow < childCount; ++childRow)
|
||||
{
|
||||
const QModelIndex childIndex(this->index(childRow, 0, index));
|
||||
|
||||
const QVariant value(data(childIndex, (Qt::UserRole + 1)));
|
||||
if (value.isValid() && value.canConvert<int>())
|
||||
{
|
||||
int state = value.toInt();
|
||||
|
||||
if (!lastMpsSet)
|
||||
{
|
||||
lastMpsSet = true;
|
||||
lastMps = state;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lastMps != state) // if at one point there is a different status inside one parent, show the 'partial' checkbox state as there are mixed states
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
return lastMps;
|
||||
}
|
||||
|
||||
|
||||
QString mpsToString(const int mps)
|
||||
{
|
||||
switch ((int)mps)
|
||||
{
|
||||
case -2:
|
||||
return QStringLiteral("PARTIALLY");
|
||||
case -1:
|
||||
return QStringLiteral("EMPTY");
|
||||
case 0:
|
||||
return QStringLiteral("IDLE");
|
||||
case 1:
|
||||
return QStringLiteral("EQUIPPED");
|
||||
default:
|
||||
return QStringLiteral("( !UNKNOWN! )");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString mpsToString(const MountingPointState_def::type mps)
|
||||
{
|
||||
return mpsToString((int)mps);
|
||||
}
|
||||
|
||||
|
||||
bool CheckboxProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
/* this setData is called if the user clicks on a checkbox
|
||||
* then this setData calls the sourceModel's setData to finally
|
||||
* set the underlying checkboxes */
|
||||
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
|
||||
const QModelIndex sourceIndex(mapToSource(index));
|
||||
|
||||
// delegate to source model for further processing of further columns if necessary
|
||||
if (index.column() != MountingPointListDialogModel::Columns::NAME)
|
||||
return sourceModel()->setData(sourceIndex, value, role);
|
||||
|
||||
|
||||
/* Qt calls setData with role == Qt::CheckStateRole if the user clicks on a checkbox.
|
||||
* We need to know at this point if wither the call to this method was called by Qt,
|
||||
* or if this method called setData recursively. If this is the first call, the new
|
||||
* checkbox state has to be determined at this point. To determine if the call to
|
||||
* setData is a recursive call, we set role to Qt::UserRole+1. Kind of a hack. */
|
||||
|
||||
int newMps = value.toInt();
|
||||
|
||||
if (role == Qt::CheckStateRole)
|
||||
{
|
||||
//newMps = (int)MountingPointState_def::Idle;
|
||||
int mps = index.data(Qt::UserRole + 1).toInt();
|
||||
switch (mps)
|
||||
{
|
||||
case -2: // SPECIAL CASE, not a real MPS, but the indicator that there are mixed states on the underlying children
|
||||
newMps = (int)MountingPointState_def::Idle;
|
||||
break;
|
||||
case (int)MountingPointState_def::Idle:
|
||||
newMps = (int)MountingPointState_def::Equipped;
|
||||
break;
|
||||
case (int)MountingPointState_def::Equipped:
|
||||
newMps = (int)MountingPointState_def::Empty;
|
||||
break;
|
||||
case (int)MountingPointState_def::Empty:
|
||||
newMps = (int)MountingPointState_def::Idle;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isLeaf(index))
|
||||
{
|
||||
// delegate a leaf to source model
|
||||
sourceModel()->setData(sourceIndex, newMps, role);
|
||||
}
|
||||
else
|
||||
{
|
||||
// update underlying children recursively (Additional nodes with leaves may also exist)
|
||||
const int childCount = rowCount(index);
|
||||
for (int childRow = 0; childRow < childCount; ++childRow)
|
||||
{
|
||||
const QModelIndex childIndex(this->index(childRow, 0, index));
|
||||
setData(childIndex, newMps, (Qt::UserRole + 1));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CheckboxProxyModel::isLeaf(const QModelIndex &index) const
|
||||
{
|
||||
const QModelIndex sourceIndex(mapToSource(index));
|
||||
return sourceModel()->flags(sourceIndex).testFlag(Qt::ItemIsUserCheckable);
|
||||
}
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <QIdentityProxyModel>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class CheckboxProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
public:
|
||||
using QIdentityProxyModel::QIdentityProxyModel;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
private:
|
||||
bool isLeaf(const QModelIndex &index) const;
|
||||
};
|
||||
} // namespace InfrastructureManagement
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
#include "ism_mounting_point_list_dialog_list_sort_model.h"
|
||||
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
void MountingPointListSortModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<MountingPointListDialogModel*>(sourceModel);
|
||||
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(m_sourceModel);
|
||||
}
|
||||
|
||||
void MountingPointListSortModel::setTypeFilter(const QSet<MountingPointType> &visibleTypes)
|
||||
{
|
||||
if (m_visibleTypes == visibleTypes)
|
||||
return;
|
||||
m_visibleTypes = visibleTypes;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void MountingPointListSortModel::addToTypeFilter(MountingPointType mpt, bool bAdd)
|
||||
{
|
||||
auto visibleTypes = m_visibleTypes;
|
||||
if (bAdd)
|
||||
{
|
||||
if(mpt == MountingPointType::IndoorIPS)
|
||||
{
|
||||
visibleTypes.insert(MountingPointType::OutdoorIPS);
|
||||
}
|
||||
visibleTypes.insert(mpt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mpt == MountingPointType::IndoorIPS)
|
||||
{
|
||||
visibleTypes.remove(MountingPointType::OutdoorIPS);
|
||||
}
|
||||
visibleTypes.remove(mpt);
|
||||
}
|
||||
setTypeFilter(visibleTypes);
|
||||
}
|
||||
|
||||
void MountingPointListSortModel::setFloorFilter(const QSet<int> &visibleFloors)
|
||||
{
|
||||
if (m_visibleFloors == visibleFloors)
|
||||
return;
|
||||
m_visibleFloors = visibleFloors;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void MountingPointListSortModel::addToFloorFilter(int floor, bool bAdd)
|
||||
{
|
||||
auto visibleFloors = m_visibleFloors;
|
||||
if (bAdd)
|
||||
visibleFloors.insert(floor);
|
||||
else
|
||||
visibleFloors.remove(floor);
|
||||
setFloorFilter(visibleFloors);
|
||||
}
|
||||
|
||||
bool MountingPointListSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (!m_sourceModel)
|
||||
return true;
|
||||
|
||||
bool isRootItem = !source_parent.isValid();
|
||||
if (isRootItem)
|
||||
{
|
||||
Q_ASSERT(source_row == 0);
|
||||
return true; // root item shall always be visible
|
||||
}
|
||||
|
||||
const QModelIndex childIdx = m_sourceModel->index(source_row, 0, source_parent);
|
||||
const NGLTreeItem *itemChild = m_sourceModel->privateData(childIdx);
|
||||
Q_ASSERT(itemChild);
|
||||
|
||||
bool isLeaf = itemChild->data().canConvert<SimpleMountingPointData>();
|
||||
if (isLeaf)
|
||||
{
|
||||
const SimpleMountingPointData data = itemChild->data().value<SimpleMountingPointData>();
|
||||
Q_ASSERT(data.isMountingPoint());
|
||||
|
||||
return m_visibleTypes.contains(data.mpType) && m_visibleFloors.contains(data.floor);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!itemChild->data().canConvert<SimpleStructureElementData>())
|
||||
return true;
|
||||
const SimpleStructureElementData ssed = itemChild->data().value<SimpleStructureElementData>();
|
||||
if (ssed.floor != -20 && !m_visibleFloors.contains(ssed.floor))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Qt5.11: setRecursiveFilteringEnabled(true);
|
||||
for (int i = 0; i < itemChild->childCount(); ++i)
|
||||
{
|
||||
if (filterAcceptsRow(i, childIdx))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MountingPointListSortModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
if (!m_sourceModel || source_left.column() != source_right.column())
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
|
||||
const NGLTreeItem *itemLeft = m_sourceModel->privateData(source_left);
|
||||
const NGLTreeItem *itemRight = m_sourceModel->privateData(source_right);
|
||||
if (!itemLeft || !itemRight)
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
|
||||
const SimpleMountingPointData left = itemLeft->data().value<SimpleMountingPointData>();
|
||||
const SimpleMountingPointData right = itemRight->data().value<SimpleMountingPointData>();
|
||||
if (left.name != right.name)
|
||||
return left.name < right.name;
|
||||
return left.id < right.id;
|
||||
}
|
||||
} // namespace InfrastructureManagement
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include "ism_mounting_point_list_dialog_model.h"
|
||||
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
#include <QSet>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class MountingPointListSortModel final : public LtsWidgets::LtsColumnFilterProxyModel
|
||||
{
|
||||
using BaseClass = LtsWidgets::LtsColumnFilterProxyModel;
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
void setTypeFilter(const QSet<MountingPointType> &visibleTypes);
|
||||
void addToTypeFilter(MountingPointType mpt, bool bAdd);
|
||||
|
||||
void setFloorFilter(const QSet<int> &visibleFloors);
|
||||
void addToFloorFilter(int floor, bool bAdd);
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::invalidateFilter;
|
||||
|
||||
private:
|
||||
MountingPointListDialogModel *m_sourceModel = nullptr;
|
||||
QSet<MountingPointType> m_visibleTypes;
|
||||
QSet<int> m_visibleFloors;
|
||||
};
|
||||
} // namespace InfrastructureManagement
|
||||
+478
@@ -0,0 +1,478 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The MountingPointListDialogModel provices data for MountingPointListDialog
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#include "ism_mounting_point_list_dialog_model.h"
|
||||
#include "ism_mounting_point_list_dialog_list_sort_model.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
// #define BENCHMARK
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# include <QElapsedTimer>
|
||||
# include <QDebug>
|
||||
#endif
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
MountingPointListDialogModel::MountingPointListDialogModel(QObject *parent)
|
||||
: NGLTreeModel(parent, new NGLTreeItem(QVariant()), { tr("Name"), tr("Type"), tr("Asset"), tr("Aim State") })
|
||||
, m_visRoot(new NGLTreeItem(tr("Mounting Points")))
|
||||
, m_dtc(nullptr)
|
||||
, m_scheduleId(-1)
|
||||
, m_dataChangedTimer(new QTimer(this))
|
||||
, m_logger(getLogger("MountingPointListDialogModel"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_dataChangedTimer->setSingleShot(true);
|
||||
m_dataChangedTimer->setInterval(100);
|
||||
connect(m_dataChangedTimer, &QTimer::timeout, this, &MountingPointListDialogModel::emitDataChanged);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
QVariant MountingPointListDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
return QVariant();
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
const int indexColumn = index.column();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (indexColumn != NAME && !item->data().canConvert<SimpleMountingPointData>())
|
||||
return QVariant();
|
||||
|
||||
const SimpleMountingPointData itemData = item->data().value<SimpleMountingPointData>();
|
||||
|
||||
switch (indexColumn)
|
||||
{
|
||||
case NAME:
|
||||
if (item->data().canConvert<SimpleMountingPointData>())
|
||||
return item->data().value<SimpleMountingPointData>().name;
|
||||
if (item->data().canConvert<SimpleStructureElementData>())
|
||||
return item->data().value<SimpleStructureElementData>().name;
|
||||
if (item->data().canConvert<SimpleBuildingGroupData>())
|
||||
return item->data().value<SimpleBuildingGroupData>().name;
|
||||
return tr("all");
|
||||
case STATE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
return toString(itemData.aimState);
|
||||
break;
|
||||
case ASSET_BARCODE:
|
||||
if (item->data().canConvert<SimpleMountingPointData>())
|
||||
return item->data().value<SimpleMountingPointData>().assetBarcode;
|
||||
break;
|
||||
case TYPE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
{
|
||||
if(itemData.mpType == MountingPointType::OutdoorIPS)
|
||||
return toString(MountingPointType::IndoorIPS);
|
||||
return toString(itemData.mpType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole
|
||||
&& indexColumn == TYPE)
|
||||
{
|
||||
const SimpleMountingPointData itemData = item->data().value<SimpleMountingPointData>();
|
||||
if (itemData.mpType.underlying() == MountingPointType::Unknown)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "unknown!!!";
|
||||
return QVariant(); // return INVALID QVariant to let LtsDataView's proxy filter model ignore this row while filtering / aka. don't hide it when filtering
|
||||
}
|
||||
|
||||
ERROR_LOG(m_logger) << "mpType = " << itemData.mpType.underlying();
|
||||
if(itemData.mpType == MountingPointType::OutdoorIPS)
|
||||
return MountingPointType::IndoorIPS;
|
||||
|
||||
return itemData.mpType.underlying();
|
||||
}
|
||||
|
||||
if (role == Qt::CheckStateRole && index.column() == NAME)
|
||||
return Qt::Unchecked; // dummy
|
||||
|
||||
if (role == Qt::UserRole && item->data().canConvert<SimpleMountingPointData>())
|
||||
return item->data().value<SimpleMountingPointData>().id;
|
||||
|
||||
if (role == (Qt::UserRole + 1) && item->data().canConvert<SimpleMountingPointData>())
|
||||
return item->data().value<SimpleMountingPointData>().aimState.underlying();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
bool MountingPointListDialogModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<ForeignDataInterface> &dataInterface)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_dtc == dtc)
|
||||
return true;
|
||||
|
||||
if (!(dtc->enableMainStructureElement() &&
|
||||
dtc->enableMountingPointAsset()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Datatopics";
|
||||
return false;
|
||||
}
|
||||
m_dtc = dtc;
|
||||
|
||||
m_dataInterface = dataInterface;
|
||||
m_scheduleId = m_dataInterface->scheduleId();
|
||||
|
||||
connect(m_dataInterface.get(), &ForeignDataInterface::mountingPointChanged,
|
||||
this, &MountingPointListDialogModel::onMountingPointChanged);
|
||||
|
||||
DEBUG_LOG(m_logger) << "initModel successful";
|
||||
|
||||
initData();
|
||||
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
return true;
|
||||
}
|
||||
|
||||
QModelIndex MountingPointListDialogModel::getIndexOfVisibleRootItem() const
|
||||
{
|
||||
return indexFromItem(m_visRoot);
|
||||
}
|
||||
|
||||
void MountingPointListDialogModel::initData()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
#ifdef BENCHMARK
|
||||
QElapsedTimer elapsedTimer1;
|
||||
elapsedTimer1.start();
|
||||
#endif // BENCHMARK
|
||||
|
||||
|
||||
NGLTreeModel::resetModel();
|
||||
|
||||
m_rootItem->appendChild(m_visRoot);
|
||||
|
||||
// const InfrastructureManagement::MainSchedule ¤tSchedule = m_dtc->mainSchedule(m_scheduleId);
|
||||
const QMap<int, InfrastructureManagement::MainStructureElement> &mainStructEles = m_dtc->mainStructureElements();
|
||||
|
||||
|
||||
// cfroebel 2018-11-07:
|
||||
// The algorithm of building the tree structure assumes that
|
||||
// the StructureElements are hierarchically ordered, i.e. that the
|
||||
// MountingPoint comes after its Room, Level and Building.
|
||||
// Is that guaranteed by the service?
|
||||
m_mountingPointIndexes.reserve(mainStructEles.size());
|
||||
m_availableBuildingGroups.reserve(mainStructEles.size());
|
||||
|
||||
for (const MainStructureElement &mse : mainStructEles)
|
||||
{
|
||||
// only consider buildings
|
||||
if (mse.structureElementTypeId() != StructureElementType::Building)
|
||||
continue;
|
||||
|
||||
// 1- if a buildingGroup modelIndex for current building dosen't exist
|
||||
// a new one will be first added and used as parentIndex for the blg_Index.
|
||||
QModelIndex groupIndex;
|
||||
const StructureElement bse= setBuildingGroup(mse.groupId());
|
||||
// Outdoor camera will not be displayed
|
||||
if (mse.groupId() != BuildingGroup::OutdoorCameras)
|
||||
{
|
||||
if (m_availableBuildingGroups.contains(bse.id()) == false)
|
||||
{
|
||||
SimpleBuildingGroupData buildingGroup;
|
||||
buildingGroup.name = QString::fromStdString(bse.displayName());
|
||||
NGLTreeItem *groupItem = new NGLTreeItem(QVariant::fromValue(buildingGroup));
|
||||
QModelIndex groupParentIndex;
|
||||
groupParentIndex = indexFromItem(m_visRoot);
|
||||
insertRow(rowCount(groupParentIndex), groupParentIndex, groupItem);
|
||||
groupIndex = index(groupItem->row(), 0, groupParentIndex);
|
||||
m_mountingPointIndexes.insert(bse.id(), groupIndex);
|
||||
m_availableBuildingGroups.insert(bse.id());
|
||||
}
|
||||
else
|
||||
{
|
||||
groupIndex = m_mountingPointIndexes.value(bse.id(), indexFromItem(m_visRoot));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (const StructureElement ¤tElement : mse.elements())
|
||||
{
|
||||
NGLTreeItem *item;
|
||||
|
||||
if (currentElement.structureElementTypeId() == StructureElementType::MountingPoint)
|
||||
{
|
||||
const MountingPoint &mountingPoint = m_dataInterface->mountingPoint(currentElement.id());
|
||||
|
||||
if (!mountingPoint.isValid())
|
||||
continue;
|
||||
|
||||
if (mountingPoint.type() == MountingPointType::Unknown ||
|
||||
mountingPoint.type() == MountingPointType::BuildingControlUnit ||
|
||||
mountingPoint.type() == MountingPointType::VirtualIPS ||
|
||||
mountingPoint.type() == MountingPointType::MeteoDataUnit ||
|
||||
mountingPoint.type() == MountingPointType::BuildingNetworkSwitch ||
|
||||
mountingPoint.type() == MountingPointType::OutdoorCamera)
|
||||
continue;
|
||||
|
||||
SimpleMountingPointData mpData;
|
||||
mpData.seType = currentElement.structureElementTypeId();
|
||||
mpData.id = mountingPoint.id();
|
||||
mpData.name = mountingPoint.name();
|
||||
mpData.aimState = mountingPoint.aimState();
|
||||
mpData.mpType = mountingPoint.type();
|
||||
mpData.floor = mountingPoint.floor();
|
||||
|
||||
// attention: getMountedAssetId could be expensive
|
||||
// const int assetId = m_dtc->getMountedAssetId(mountingPoint.data().id());
|
||||
// use already available mountingPoint instead: :-)
|
||||
const int assetId = mountingPoint.associatedAssetId();
|
||||
mpData.assetBarcode = QStringLiteral("-");
|
||||
if(assetId != -1)
|
||||
{
|
||||
mpData.assetBarcode = QString::fromStdString(m_dtc->instrumentationAsset(assetId).barcode());
|
||||
}
|
||||
|
||||
item = new NGLTreeItem(QVariant::fromValue(mpData));
|
||||
}
|
||||
else
|
||||
{
|
||||
SimpleStructureElementData ssed;
|
||||
ssed.mseId = mse.id();
|
||||
if (currentElement.structureElementTypeId() == StructureElementType::Floor)
|
||||
ssed.floor = QString::fromStdString(currentElement.name()).split(QLatin1Literal("_")).value(1, QLatin1String("-10")).toInt();
|
||||
else
|
||||
ssed.floor = -20;
|
||||
ssed.name = currentElement.displayName().empty() ? QString::fromStdString(currentElement.name()) : QString::fromStdString(currentElement.displayName());
|
||||
item = new NGLTreeItem(QVariant::fromValue(ssed));
|
||||
m_availableFloors << ssed.floor;
|
||||
}
|
||||
|
||||
const auto &path = currentElement.path();
|
||||
|
||||
QModelIndex parentIndex;
|
||||
if (path.size() > 1)
|
||||
{
|
||||
parentIndex = m_mountingPointIndexes.value(path.at(path.size() - 2), indexFromItem(m_visRoot)); //default sollte nie erreicht werden
|
||||
if (!parentIndex.isValid())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Did not find parent for structure element with id " << currentElement.id() << " mseid: " << mse.id();
|
||||
for (const StructureElement &se : mse.elements())
|
||||
ERROR_LOG(m_logger) << " se: " << se.id() << ", " << se.displayName() << ", " << se.name();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 2- Append building to it section index
|
||||
if(groupIndex.isValid() == false)
|
||||
{
|
||||
parentIndex = indexFromItem(m_visRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
parentIndex = groupIndex;
|
||||
}
|
||||
}
|
||||
insertRow(rowCount(parentIndex), parentIndex, item);
|
||||
|
||||
m_mountingPointIndexes.insert(currentElement.id(), index(item->row(), 0, parentIndex));
|
||||
}
|
||||
}
|
||||
|
||||
m_availableFloors << -10;
|
||||
|
||||
#ifdef BENCHMARK
|
||||
qCritical() << " MountingPointListDialogModel::init-BENCHMARK: took " << elapsedTimer1.elapsed() << " [ms]";
|
||||
#endif // BENCHMARK
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
QSet<int> MountingPointListDialogModel::getAvailableFloors() const
|
||||
{
|
||||
return m_availableFloors;
|
||||
}
|
||||
|
||||
StructureElement MountingPointListDialogModel::setBuildingGroup(int groupId)
|
||||
{
|
||||
StructureElement se{};
|
||||
InfrastructureManagement::BuildingGroup_def::type buildingGroup = static_cast<InfrastructureManagement::BuildingGroup_def::type>(groupId);
|
||||
if(buildingGroup == 0)
|
||||
{
|
||||
buildingGroup = InfrastructureManagement::BuildingGroup_def::UnknownGroup;
|
||||
}
|
||||
|
||||
se.id() = maxIntValue - static_cast<int>(buildingGroup);
|
||||
se.name() = InfrastructureManagement::toString(buildingGroup).toStdString();
|
||||
se.displayName() = InfrastructureManagement::toString(buildingGroup).toStdString();
|
||||
se.structureElementTypeId() = InfrastructureManagement::StructureElementType::Section;
|
||||
return se;
|
||||
}
|
||||
|
||||
Qt::ItemFlags MountingPointListDialogModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags fl = NGLTreeModel::flags(index);
|
||||
if (!index.isValid())
|
||||
return fl;
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
bool isLeaf = item->data().canConvert<SimpleMountingPointData>();
|
||||
if (isLeaf && index.column() == Columns::NAME)
|
||||
return fl | Qt::ItemIsUserCheckable | Qt::ItemIsUserTristate;
|
||||
return fl;
|
||||
}
|
||||
|
||||
bool MountingPointListDialogModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
// is called by the CheckboxProxyModel's setData method
|
||||
|
||||
if (index.column() != NAME || !index.isValid())
|
||||
return NGLTreeModel::/**/setData(index, value, role);
|
||||
|
||||
auto lambda = [this, &value](const QModelIndex &idx)
|
||||
{
|
||||
NGLTreeItem *item = privateData(idx);
|
||||
|
||||
if (!item->data().canConvert<SimpleMountingPointData>()) // not a leaf?
|
||||
{
|
||||
Q_ASSERT(false); // CheckboxProxyModel never calls this model's setData if the index is not a leaf
|
||||
|
||||
/* we don't know what state the parent is, wo don't know how many children there REALLY are.
|
||||
* all this is hidden behind multiple proxy models. so send a signal to the dialog,
|
||||
* get the clicked parent's state and set all its (visible!) children.
|
||||
* at least that's the plan .... */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleMountingPointData smpd = item->data().value<SimpleMountingPointData>();
|
||||
smpd.aimState = (MountingPointState::inner_enum)value.toInt();
|
||||
|
||||
item->setData(QVariant::fromValue(smpd));
|
||||
|
||||
emit changesMade();
|
||||
};
|
||||
|
||||
if (index.parent().isValid())
|
||||
{
|
||||
lambda(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const QModelIndex &idx : qAsConst(m_mountingPointIndexes))
|
||||
lambda(idx);
|
||||
}
|
||||
|
||||
m_dataChangedTimer->start(); // ugly hack
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVariant MountingPointListDialogModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal
|
||||
&& role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole
|
||||
&& section == TYPE)
|
||||
return m_cbxFilterType;
|
||||
return BaseClass::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
|
||||
void MountingPointListDialogModel::setMntPointFilterTypes(QSet<MountingPointType> types)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (const auto es : qAsConst(types))
|
||||
{
|
||||
if (es == MountingPointType::OutdoorIPS)
|
||||
continue;
|
||||
cfd.data = es.underlying();
|
||||
cfd.text = toString(es);
|
||||
cfc.data.push_back(cfd);
|
||||
|
||||
// DEBUG_LOG(m_logger)<<" cfd.text: "<<cfd.text;
|
||||
}
|
||||
cfc.sortItems = true;
|
||||
m_cbxFilterType = cfc.toVariant();
|
||||
}
|
||||
|
||||
void MountingPointListDialogModel::onMountingPointChanged(const MountingPoint &mountingPoint, DataModification modType)
|
||||
{
|
||||
if (modType != DataModification::eModified)
|
||||
return;
|
||||
|
||||
QModelIndex index = m_mountingPointIndexes.value(mountingPoint.id());
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
if (!(item && item->data().canConvert<SimpleMountingPointData>()))
|
||||
return;
|
||||
|
||||
SimpleMountingPointData mpData = item->data().value<SimpleMountingPointData>();
|
||||
|
||||
mpData.name = mountingPoint.name();
|
||||
mpData.aimState = mountingPoint.aimState();
|
||||
const int assetId = mountingPoint.associatedAssetId(); // (m_dtc->getMountedAssetId(mountingPoint.data().id());
|
||||
mpData.assetBarcode = QStringLiteral("-");
|
||||
mpData.floor = mountingPoint.floor();
|
||||
|
||||
if(assetId != -1)
|
||||
{
|
||||
mpData.assetBarcode = QString::fromStdString(m_dtc->instrumentationAsset(assetId).barcode());
|
||||
}
|
||||
item->setData(QVariant::fromValue(mpData));
|
||||
m_dataChangedTimer->start();
|
||||
}
|
||||
|
||||
void MountingPointListDialogModel::onScheduleIdChanged(int32_t scheduleId)
|
||||
{
|
||||
// is this unreachable code?
|
||||
|
||||
if (scheduleId == m_scheduleId)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "onScheduleIdChanged: " << scheduleId;
|
||||
|
||||
m_scheduleId = scheduleId;
|
||||
|
||||
// !!! Maybe this is critical !!!
|
||||
// !!! Maybe this is critical !!!
|
||||
// !!! Maybe this is critical !!!
|
||||
// m_dataInterface::setScheduleId will update the MountingPoints (aimState) according schedule!!!
|
||||
m_dataInterface->setScheduleId(m_scheduleId);
|
||||
initData();
|
||||
}
|
||||
|
||||
void MountingPointListDialogModel::emitDataChanged()
|
||||
{
|
||||
QModelIndex vri = getIndexOfVisibleRootItem();
|
||||
emit dataChanged(vri, index(rowCount(vri) -1, Columns::STATE, vri), {Qt::DisplayRole, Qt::CheckStateRole});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// MountingPointListSortModel
|
||||
//
|
||||
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The MountingPointListDialogModel provices data for MountingPointListDialog
|
||||
* Modified version using the checkStateProxyModel to allow setting via the checkboxes of the tree structure hjl 5/19
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <QSet>
|
||||
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
#include <LtsDataView/check_state_proxy_model.h>
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
struct SimpleMountingPointData
|
||||
{
|
||||
QString name;
|
||||
int32_t id = 0; // StructureElementId
|
||||
StructureElementType seType;
|
||||
MountingPointType mpType;
|
||||
MountingPointState aimState;
|
||||
// int assetId; Chance to only reload assetBarcode, if assetId changes...
|
||||
QString assetBarcode;
|
||||
int32_t floor;
|
||||
|
||||
bool isMountingPoint() const { return seType == StructureElementType::MountingPoint; }
|
||||
};
|
||||
|
||||
struct SimpleStructureElementData
|
||||
{
|
||||
int mseId;
|
||||
QString name;
|
||||
int floor;
|
||||
};
|
||||
|
||||
struct SimpleBuildingGroupData
|
||||
{
|
||||
QString name;
|
||||
};
|
||||
|
||||
class MountingPointListDialogModel final : public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = NGLTreeModel;
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
NAME,
|
||||
TYPE,
|
||||
ASSET_BARCODE,
|
||||
STATE
|
||||
};
|
||||
explicit MountingPointListDialogModel(QObject *parent = nullptr);
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
/**
|
||||
* Handles the representation of data.
|
||||
* In case of CheckStateRole only leafs will be handled.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
* @param[in] role role to which the data relates
|
||||
*
|
||||
*/
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<ForeignDataInterface> &dataInterface);
|
||||
|
||||
QModelIndex getIndexOfVisibleRootItem() const;
|
||||
|
||||
/**
|
||||
* Sets only the leafs of the tree view to Qt::ItemIsUserCheckable.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
*
|
||||
*/
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override final;
|
||||
|
||||
/**
|
||||
* Sets the check state data according to their check box in the internal model.
|
||||
* CheckState data can be set for leafs only.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
* @param[in] value value to be set
|
||||
* @param[in] role role to which the data relates (here especially Qt::CheckStateRole)
|
||||
*
|
||||
*/
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
void setMntPointFilterTypes(QSet<InfrastructureManagement::MountingPointType> types);
|
||||
QSet<int> getAvailableFloors() const;
|
||||
StructureElement setBuildingGroup(int groupId);
|
||||
static const int maxIntValue = std::numeric_limits<int>::max();
|
||||
|
||||
signals:
|
||||
void changesMade();
|
||||
|
||||
public slots:
|
||||
void onMountingPointChanged(const MountingPoint &mountingPoint, DataModification modType);
|
||||
|
||||
private slots:
|
||||
void onScheduleIdChanged(int32_t scheduleId);
|
||||
void emitDataChanged();
|
||||
|
||||
private:
|
||||
void initData();
|
||||
friend class MountingPointListSortModel;
|
||||
|
||||
NGLTreeItem *m_visRoot;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_dataInterface;
|
||||
int32_t m_scheduleId;
|
||||
QHash<int, QModelIndex> m_mountingPointIndexes;
|
||||
QTimer *m_dataChangedTimer{nullptr};
|
||||
QSet<int> m_availableFloors;
|
||||
QSet<int> m_availableBuildingGroups;
|
||||
QVariant m_cbxFilterType;
|
||||
LOGGER_T m_logger;
|
||||
}; // class MountingPointListDialogModel
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::SimpleMountingPointData)
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::SimpleStructureElementData)
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::SimpleBuildingGroupData)
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class which adds single mounting points to the current schedule by id
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-04-06
|
||||
*/
|
||||
|
||||
#include "ism_dds_selector.h"
|
||||
|
||||
#include <LtsUtilsCore/dds_vector.h>
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <QApplication>
|
||||
|
||||
using namespace InfrastructureManagement;
|
||||
|
||||
DdsSelector::DdsSelector(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<Interface::Ftc> &ftc, const std::shared_ptr<ForeignDataInterface> &ismDataIfc, LtsUtils::RequestHelper *requestHelper)
|
||||
: MountingPointSelector(dtc, ftc, ismDataIfc, requestHelper, getLogger(QStringLiteral("DdsSelector")))
|
||||
{
|
||||
}
|
||||
|
||||
void DdsSelector::addMountingPoints(const QVector<int32_t> &mountingPointIds, const QMap<int32_t, MountingPointState> &states, QWidget *parentWidget)
|
||||
{
|
||||
if (mountingPointIds.isEmpty())
|
||||
return;
|
||||
|
||||
Q_UNUSED(states)
|
||||
|
||||
std::vector<MountingPointPlan> modifyVec;
|
||||
modifyVec.reserve(mountingPointIds.size());
|
||||
|
||||
MainSchedule mainSchedule = m_ismDataIfc->mainSchedule(m_ismDataIfc->scheduleId());
|
||||
|
||||
MountingPointState mps = m_ismDataIfc->mountingPoint(mountingPointIds.first()).aimState();
|
||||
bool override = false;
|
||||
for (int32_t currentMountingPointId : mountingPointIds)
|
||||
{
|
||||
MountingPoint mountingPoint = m_ismDataIfc->mountingPoint(currentMountingPointId);
|
||||
|
||||
if (!mountingPoint.isValid())
|
||||
continue;
|
||||
|
||||
if (mountingPoint.aimState() == mps)
|
||||
continue;
|
||||
|
||||
LtsWidgets::Button resButton = LtsWidgets::LtsMessageDialog::showMessage(parentWidget,
|
||||
QApplication::translate("Ism::Selector", "Multiple selected components have different states.\nPlease select desired state"),
|
||||
QApplication::translate("Ism::Selector", "Inconsistent component state"),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes | LtsWidgets::Button::No | LtsWidgets::Button::Discard,
|
||||
{ {LtsWidgets::Button::Yes, QApplication::translate("Ism::Selector", "Equipped")},
|
||||
{LtsWidgets::Button::No, QApplication::translate("Ism::Selector", "Empty")},
|
||||
{LtsWidgets::Button::Discard, QApplication::translate("Ism::Selector", "Idle")}
|
||||
});
|
||||
switch(resButton)
|
||||
{
|
||||
case LtsWidgets::Button::Yes:
|
||||
mps = MountingPointState::Equipped;
|
||||
break;
|
||||
case LtsWidgets::Button::No:
|
||||
mps = MountingPointState::Empty;
|
||||
break;
|
||||
case LtsWidgets::Button::Discard:
|
||||
default:
|
||||
mps = MountingPointState::Idle;
|
||||
break;
|
||||
}
|
||||
override = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
for (int32_t currentMountingPointId : mountingPointIds)
|
||||
{
|
||||
MountingPoint mountingPoint = m_ismDataIfc->mountingPoint(currentMountingPointId);
|
||||
|
||||
if (!mountingPoint.isValid())
|
||||
continue;
|
||||
|
||||
MountingPointState aimState = override ? mps : mountingPoint.getNextMountingPointState(mountingPoint.aimState());
|
||||
|
||||
auto it = std::find_if(mainSchedule.elements().cbegin(), mainSchedule.elements().cend(), [currentMountingPointId](const MountingPointPlan &mpp){ return (mpp.structureElementId() == currentMountingPointId); });
|
||||
|
||||
if (it != mainSchedule.elements().cend())
|
||||
{
|
||||
if ((*it).mountingPointState() == aimState)
|
||||
continue;
|
||||
|
||||
MountingPointPlan mpp = (*it);
|
||||
mpp.mountingPointState() = aimState;
|
||||
modifyVec.push_back(mpp);
|
||||
}
|
||||
else if (aimState != MountingPointState::Idle)
|
||||
modifyVec.push_back(MountingPointPlan(currentMountingPointId,aimState));
|
||||
}
|
||||
|
||||
if (!modifyVec.empty())
|
||||
startModifyRequest(modifyVec);
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class which adds single mounting points to the current schedule by id
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-04-06
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ism_selector.h"
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class DdsSelector
|
||||
: public MountingPointSelector
|
||||
{
|
||||
public:
|
||||
explicit DdsSelector(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<Interface::Ftc> &ftc, const std::shared_ptr<ForeignDataInterface> &ismDataIfc, LtsUtils::RequestHelper *requestHelper);
|
||||
|
||||
void addMountingPoints(const QVector<int32_t> &mountingPointIds, const QMap<int32_t, MountingPointState> &states, QWidget *parentWidget) override final;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Abstract class which defines selection behavior when clicking on mounting points on the map
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-04-05
|
||||
*/
|
||||
|
||||
#include "ism_selector.h"
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
MountingPointSelector::MountingPointSelector(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &ismDataIfc,
|
||||
LtsUtils::RequestHelper *requestHelper,
|
||||
LOGGER_T logger)
|
||||
: m_ismDataIfc(ismDataIfc)
|
||||
, m_ftc(ftc)
|
||||
, m_dtc(dtc)
|
||||
, m_requestHelper(requestHelper)
|
||||
, m_logger(logger)
|
||||
{
|
||||
if (!m_ftc->enableMountingPointPlanModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT MountingPointPlanModify of ISM";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MountingPointSelector::onMountingPointPlanModifyReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
|
||||
if (replyObject.error())
|
||||
ERROR_LOG(m_logger) << "MountingPointPlansRemove error: "
|
||||
<< replyObject.str();
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "MountingPointPlansRemove success";
|
||||
}
|
||||
|
||||
|
||||
void MountingPointSelector::startModifyRequest(const std::vector<MountingPointPlan> &data)
|
||||
{
|
||||
if (data.empty())
|
||||
return;
|
||||
MountingPointPlanModifyRequest req(m_ismDataIfc->scheduleId(), data);
|
||||
m_requestHelper->startSingleRequest([req, this]()
|
||||
{
|
||||
return m_ftc->mountingPointPlanModifyRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Lts/Plugins/InfrastructureManagement/Gui/ResourceManagement/MountingPointMapSelection/ism_selector.h
Executable
+47
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Abstract class which defines selection behavior when clicking on mounting points on the map
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-04-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class MountingPointSelector
|
||||
: public Interface::Ftc::MountingPointPlanModifyReplyHandler
|
||||
{
|
||||
public:
|
||||
explicit MountingPointSelector(const std::shared_ptr<Interface::Dtc> &dtc, const std::shared_ptr<Interface::Ftc> &ftc, const std::shared_ptr<ForeignDataInterface> &ismDataIfc, LtsUtils::RequestHelper *requestHelper, LOGGER_T logger);
|
||||
virtual ~MountingPointSelector() = default;
|
||||
|
||||
virtual void addMountingPoints(const QVector<int32_t> &mountingPointIds, const QMap<int32_t, MountingPointState> &states, QWidget *parentWidget) = 0;
|
||||
|
||||
void onMountingPointPlanModifyReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
protected: //methods
|
||||
void startModifyRequest(const std::vector<MountingPointPlan> &data);
|
||||
|
||||
protected: // attributes
|
||||
std::shared_ptr<ForeignDataInterface> m_ismDataIfc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+233
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ConflictsDialog shows conflicts between 2 instrumentation plans
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLTE, 2022-11-15
|
||||
*/
|
||||
|
||||
#include "ism_overview_conflicts_dialog.h"
|
||||
#include "ui_ism_overview_conflicts_dialog.h"
|
||||
#include "ism_overview_conflicts_model.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QTreeView>
|
||||
#include <QHeaderView>
|
||||
#include <QScrollBar>
|
||||
|
||||
using namespace InfrastructureManagement;
|
||||
ConflictsDialog::ConflictsDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkCancel)
|
||||
, m_ui(new Ui::ConflictsDialog)
|
||||
, m_sourceModel(nullptr)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_logger(getLogger("ConflictsDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Conflicts"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &ConflictsDialog::onPrint);
|
||||
}
|
||||
|
||||
ConflictsDialog::~ConflictsDialog()
|
||||
{
|
||||
if (m_sourceModel)
|
||||
{
|
||||
delete m_sourceModel;
|
||||
m_sourceModel = nullptr;
|
||||
}
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void ConflictsDialog::retranslate()
|
||||
{
|
||||
QString plan1 = QString::fromStdString(m_dtc->mainSchedule(m_scheduleId).name());
|
||||
QString plan2 = QString::fromStdString(m_dtc->mainSchedule(m_anotherScheduleId).name());
|
||||
translate(m_ui, tr("Conflicts: %1 - %2").arg(plan1, plan2));
|
||||
}
|
||||
|
||||
bool ConflictsDialog::init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
int scheduleId,
|
||||
int anotherScheduleId)
|
||||
{
|
||||
m_session = session;
|
||||
m_dtc = dtc;
|
||||
m_scheduleId = scheduleId;
|
||||
m_anotherScheduleId = anotherScheduleId;
|
||||
|
||||
if (m_scheduleId <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Invalid id for Instrumentation plan: " << m_scheduleId;
|
||||
return false;
|
||||
}
|
||||
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainScheduleChanged, this, &ConflictsDialog::dataChanged);
|
||||
|
||||
m_sourceModel = new ConflictsDialogModel(this);
|
||||
|
||||
if (!m_sourceModel->initModel(m_scheduleId, m_anotherScheduleId, m_dtc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init ConflictsDialogModel";
|
||||
delete m_sourceModel;
|
||||
m_sourceModel = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_ui->dvConflicts->setModel(m_sourceModel);
|
||||
|
||||
m_ui->dvConflicts->setContextMenuPolicyPerView(LtsDataView::LtsDataView::Page::TABLE, Qt::CustomContextMenu);
|
||||
connect(m_ui->dvConflicts->treeView(), &QTreeView::customContextMenuRequested,
|
||||
this, &ConflictsDialog::onCustomContextMenu);
|
||||
|
||||
// show first tree level when activating the dialog
|
||||
m_ui->dvConflicts->treeView()->expandToDepth(0);
|
||||
|
||||
m_ui->dvConflicts->treeView()->setColumnWidth(0, 400);
|
||||
m_ui->dvConflicts->treeView()->setColumnWidth(1, 200);
|
||||
m_ui->dvConflicts->treeView()->setColumnWidth(2, 200);
|
||||
m_ui->dvConflicts->treeView()->setColumnWidth(3, 200);
|
||||
m_ui->dvConflicts->searchView()->setColumnWidth(0, 400);
|
||||
m_ui->dvConflicts->searchView()->setColumnWidth(1, 200);
|
||||
m_ui->dvConflicts->searchView()->setColumnWidth(2, 200);
|
||||
m_ui->dvConflicts->searchView()->setColumnWidth(3, 200);
|
||||
|
||||
connect(m_ui->dvConflicts->searchView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->dvConflicts->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(m_ui->dvConflicts->treeView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->dvConflicts->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
m_ui->dvConflicts->treeView()->expandAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConflictsDialog::updateModel()
|
||||
{
|
||||
if(m_sourceModel)
|
||||
{
|
||||
m_sourceModel->onConflictedDataChanged();
|
||||
m_ui->dvConflicts->treeView()->expandAll();
|
||||
}
|
||||
}
|
||||
|
||||
void ConflictsDialog::dataChanged(const InfrastructureManagement::MainSchedule &data, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
if (data.id() == m_scheduleId)
|
||||
m_sourceModel->initModel(m_scheduleId, m_anotherScheduleId, m_dtc);
|
||||
}
|
||||
|
||||
void ConflictsDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->dvConflicts->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
void ConflictsDialog::onPrint()
|
||||
{
|
||||
MainSchedule plan1 = m_dtc->mainSchedule(m_scheduleId);
|
||||
MainSchedule plan2 = m_dtc->mainSchedule(m_anotherScheduleId);
|
||||
|
||||
m_ui->dvConflicts->treeView()->expandAll();
|
||||
|
||||
QString header;
|
||||
header += QStringLiteral("<p>");
|
||||
header += QStringLiteral("<b>") + tr("Overview Conflicts") + QStringLiteral("</b>");
|
||||
header += QStringLiteral("<hr/>");
|
||||
header += tr("Current Instrumentation Plan: %1").arg(QString::fromStdString(plan1.name()));
|
||||
|
||||
header += QStringLiteral(" - ");
|
||||
if (plan1.timeStart().is_set())
|
||||
header += tr("START: %1").arg(DTG::toStringMSec(plan1.timeStart().get()));
|
||||
else
|
||||
header += tr("START: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral(" - ");
|
||||
if (plan1.timeEnd().is_set())
|
||||
header += tr("END: %1").arg(DTG::toStringMSec(plan1.timeEnd().get()));
|
||||
else
|
||||
header += tr("END: %1").arg(tr("[N/A]"));
|
||||
|
||||
header += QStringLiteral("<br/>");
|
||||
|
||||
header += tr("Compared Instrumentation Plan: %1").arg(QString::fromStdString(plan2.name()));
|
||||
|
||||
header += QStringLiteral(" - ");
|
||||
if (plan2.timeStart().is_set())
|
||||
header += tr("START: %1").arg(DTG::toStringMSec(plan2.timeStart().get()));
|
||||
else
|
||||
header += tr("START: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral(" - ");
|
||||
if (plan2.timeEnd().is_set())
|
||||
header += tr("END: %1").arg(DTG::toStringMSec(plan2.timeEnd().get()));
|
||||
else
|
||||
header += tr("END: %1").arg(tr("[N/A]"));
|
||||
|
||||
header += QStringLiteral("<br/>");
|
||||
header += QStringLiteral("</p>");
|
||||
LtsPrinting::printView(m_session, this, m_ui->dvConflicts->treeView(), header);
|
||||
}
|
||||
|
||||
void ConflictsDialog::onCustomContextMenu(QPoint pos)
|
||||
{
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
contextMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->dvConflicts->expandAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->dvConflicts->collapseAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->addSeparator();
|
||||
QModelIndex index = m_ui->dvConflicts->treeView()->indexAt(pos);
|
||||
bool hasChildren = m_ui->dvConflicts->treeView()->model()->rowCount(index) > 0;
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,13,0)
|
||||
m_ui->dvConflicts->treeView()->expand(index);
|
||||
#else
|
||||
m_ui->dvConflicts->treeView()->expandRecursively(index);
|
||||
#endif
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
m_ui->dvConflicts->treeView()->collapse(index);
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->popup(m_ui->dvConflicts->treeView()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
Lts/Plugins/InfrastructureManagement/Gui/ResourceManagement/Overview/ism_overview_conflicts_dialog.h
Executable
+64
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ConflictsDialog shows differences between 2 instrumentation plans
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLTE, 2022-11-15
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ConflictsDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ConflictsDialogModel;
|
||||
|
||||
class ConflictsDialog final
|
||||
: public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ConflictsDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~ConflictsDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
int scheduleId,
|
||||
int anotherScheduleId);
|
||||
void updateModel();
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
void dataChanged(const InfrastructureManagement::MainSchedule &data, DataModification modType);
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
private slots:
|
||||
void onPrint();
|
||||
void onCustomContextMenu(QPoint pos);
|
||||
|
||||
private: // attributes
|
||||
Ui::ConflictsDialog *m_ui{nullptr};
|
||||
ConflictsDialogModel *m_sourceModel{nullptr};
|
||||
std::shared_ptr<Interface::Dtc> m_dtc{nullptr};
|
||||
QString m_menuGroup;
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
int m_scheduleId{-1};
|
||||
int m_anotherScheduleId{-1};
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class ConflictsDialog
|
||||
} // namespace InfrastructureManagement
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ConflictsDialog</class>
|
||||
<widget class="QWidget" name="ConflictsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1169</width>
|
||||
<height>517</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Differences</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="LtsDataView::LtsDataView" name="dvConflicts" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="rootIsDecorated" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+388
@@ -0,0 +1,388 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ConflictsDialog shows differences between 2 instrumentation plans
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLTE, 2022-11-15
|
||||
*/
|
||||
|
||||
#include "ism_overview_conflicts_model.h"
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
// #define BENCHMARK
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# include <QElapsedTimer>
|
||||
# include <QDebug>
|
||||
#endif
|
||||
|
||||
static const int maxIntValue = std::numeric_limits<int>::max();
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
ConflictsDialogModel::ConflictsDialogModel(QObject *parent)
|
||||
: NGLTreeModel(parent, new NGLTreeItem(QVariant()), { tr("Name"), tr("Type"), tr("Aim State"), tr("Conflict State") })
|
||||
, m_dtc(nullptr)
|
||||
, m_scheduleId(-1)
|
||||
, m_anotherScheduleId(-1)
|
||||
, m_logger(getLogger("OverviewConflictsDialogModel"))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVariant ConflictsDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ( !index.isValid() && (role == Qt::DisplayRole || role == Qt::DecorationRole) )
|
||||
return QVariant();
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (index.column() != NAME && !item->data().canConvert<ConflictMountingPointData>())
|
||||
return QVariant();
|
||||
|
||||
const ConflictMountingPointData itemData = item->data().value<ConflictMountingPointData>();
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
if (item->data().canConvert<ConflictMountingPointData>())
|
||||
return item->data().value<ConflictMountingPointData>().name;
|
||||
if (item->data().canConvert<ConflictStructureElementData>())
|
||||
return item->data().value<ConflictStructureElementData>().name;
|
||||
return tr("all");
|
||||
case AIM_STATE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
return toString(itemData.aimState);
|
||||
break;
|
||||
case CONFLICT_STATE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
return toString(itemData.conflictState);
|
||||
break;
|
||||
case TYPE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
{
|
||||
const MountingPointType mpt = itemData.mpType == MountingPointType::OutdoorIPS ? MountingPointType::IndoorIPS : itemData.mpType;
|
||||
return toString(mpt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::DecorationRole)
|
||||
{
|
||||
if (!item->data().canConvert<ConflictMountingPointData>())
|
||||
return QVariant();
|
||||
const ConflictMountingPointData itemData = item->data().value<ConflictMountingPointData>();
|
||||
|
||||
static const QIcon green(QLatin1String("icon:green_light.svg"));
|
||||
static const QIcon red(QLatin1String("icon:red_light.svg"));
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case AIM_STATE:
|
||||
{
|
||||
return itemData.aimState == MountingPointState_def::Equipped ? green : red;
|
||||
}
|
||||
case CONFLICT_STATE:
|
||||
{
|
||||
return itemData.conflictState == MountingPointState_def::Equipped ? green : red;
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant ConflictsDialogModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
QString plan1 = QString::fromStdString(m_dtc->mainSchedule(m_scheduleId).name());
|
||||
QString plan2 = QString::fromStdString(m_dtc->mainSchedule(m_anotherScheduleId).name());
|
||||
|
||||
Columns col = static_cast<Columns>(section);
|
||||
switch (col)
|
||||
{
|
||||
case NAME:
|
||||
return tr("Name");
|
||||
case TYPE:
|
||||
return tr("Type");
|
||||
case AIM_STATE:
|
||||
return tr("Aim State (%1)").arg(plan1);
|
||||
case CONFLICT_STATE:
|
||||
return tr("Conflict State (%1)").arg(plan2);
|
||||
}
|
||||
}
|
||||
return NGLTreeModel::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
bool ConflictsDialogModel::initModel(int scheduleId,
|
||||
int anotherScheduleId,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc)
|
||||
{
|
||||
if (m_dtc == dtc) //already initialized...
|
||||
return true;
|
||||
|
||||
if (!(dtc->enableMainStructureElement() &&
|
||||
dtc->enableMainSchedule()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Data Topics";
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Stand 2022.11.16
|
||||
struct MountingPointType_def {
|
||||
enum type {
|
||||
Unknown = 0,
|
||||
BuildingSensorModule = 1,
|
||||
BuildingControlUnit = 2,
|
||||
OutdoorCamera = 3,
|
||||
IndoorCamera = 4,
|
||||
OutdoorIPS = 5,
|
||||
IndoorIPS = 6,
|
||||
MeteoDataUnit = 7,
|
||||
AnnouncementUnit = 10,
|
||||
VirtualIPS = 11,
|
||||
EffectGenerationControlUnit = 12,
|
||||
OutdoorControlUnit = 13,
|
||||
BuildingNetworkSwitch = 14
|
||||
};
|
||||
*/
|
||||
// same as filters in Mounting Points Dialog (ism_mounting_point_list_dialog.cpp:196)?
|
||||
m_visibleTypes = { MountingPointType_def::BuildingSensorModule,
|
||||
// MountingPointType_def::OutdoorCamera,
|
||||
MountingPointType_def::IndoorCamera,
|
||||
MountingPointType_def::OutdoorIPS,
|
||||
MountingPointType_def::IndoorIPS,
|
||||
MountingPointType_def::EffectGenerationControlUnit
|
||||
};
|
||||
|
||||
m_dtc = dtc;
|
||||
|
||||
m_scheduleId = scheduleId;
|
||||
m_anotherScheduleId = anotherScheduleId;
|
||||
|
||||
initData();
|
||||
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
return true;
|
||||
}
|
||||
|
||||
StructureElement ConflictsDialogModel::setBuildingGroup(int groupId)
|
||||
{
|
||||
StructureElement se;
|
||||
BuildingGroup_def::type buildingGroup = static_cast<BuildingGroup_def::type>(groupId);
|
||||
|
||||
se.id() = maxIntValue - static_cast<int>(buildingGroup);
|
||||
se.name() = InfrastructureManagement::toString(buildingGroup).toStdString();
|
||||
se.displayName() = InfrastructureManagement::toString(buildingGroup).toStdString();
|
||||
se.structureElementTypeId() = StructureElementType_def::Section;
|
||||
return se;
|
||||
}
|
||||
|
||||
void ConflictsDialogModel::onConflictedDataChanged()
|
||||
{
|
||||
if(m_rootItem)
|
||||
initData();
|
||||
}
|
||||
|
||||
void ConflictsDialogModel::initData()
|
||||
{
|
||||
|
||||
NGLTreeModel::resetModel();
|
||||
m_availableBuildingGroups.clear();
|
||||
m_mountingPointIndexes.clear();
|
||||
|
||||
QHash<int /*<structureElementId>*/, MountingPointPlan> currentMountingPoints;
|
||||
QHash<int /*<structureElementId>*/, MountingPointPlan> compareMountingPoints;
|
||||
QHash<int/*<mse.id>*/, InfrastructureManagement::MainStructureElement> conflictedMainStructElements;
|
||||
QSet<int> conflictedStructElIds;
|
||||
|
||||
#ifdef BENCHMARK
|
||||
QElapsedTimer elapsedTimer1;
|
||||
QElapsedTimer elapsedTimer2;
|
||||
elapsedTimer1.start();
|
||||
elapsedTimer2.start();
|
||||
#endif // BENCHMARK
|
||||
// Plan 1
|
||||
InfrastructureManagement::MainSchedule currentSchedule = m_dtc->mainSchedule(m_scheduleId);
|
||||
for (const InfrastructureManagement::MountingPointPlan ¤tPlan : currentSchedule.elements())
|
||||
{
|
||||
StructureElement se;
|
||||
if (!m_dtc->getStructureElementById(currentPlan.structureElementId(), se))
|
||||
continue;
|
||||
|
||||
if (m_visibleTypes.contains(se.mountingPointTypeId()))
|
||||
currentMountingPoints.insert(currentPlan.structureElementId(), currentPlan);
|
||||
}
|
||||
|
||||
// Plan 2
|
||||
InfrastructureManagement::MainSchedule compareSchedule = m_dtc->mainSchedule(m_anotherScheduleId);
|
||||
for (const InfrastructureManagement::MountingPointPlan &comparePlan : compareSchedule.elements())
|
||||
{
|
||||
if (!currentMountingPoints.contains(comparePlan.structureElementId()))
|
||||
continue;
|
||||
|
||||
StructureElement structEl;
|
||||
if (!m_dtc->getStructureElementById(comparePlan.structureElementId(), structEl))
|
||||
continue;
|
||||
if (!m_visibleTypes.contains(structEl.mountingPointTypeId()))
|
||||
continue;
|
||||
|
||||
// calculate final state for this MP, except conflicts
|
||||
// p1 | p2 | final
|
||||
// equipped equipped +1
|
||||
// equipped idle +1
|
||||
// idle equipped +1
|
||||
// empty empty 0
|
||||
// idle idle 0
|
||||
// empty idle 0
|
||||
// idle empty 0
|
||||
// equipped empty - conflict
|
||||
// empty equipped - conflict
|
||||
const MountingPointPlan &mp1 = currentMountingPoints[comparePlan.structureElementId()];
|
||||
if ((mp1.mountingPointState() == MountingPointState::Equipped && comparePlan.mountingPointState() == MountingPointState::Empty) ||
|
||||
(mp1.mountingPointState() == MountingPointState::Empty && comparePlan.mountingPointState() == MountingPointState::Equipped))
|
||||
{
|
||||
compareMountingPoints.insert(comparePlan.structureElementId(), comparePlan);
|
||||
StructureElement se;
|
||||
// get mounting point path: (building id, floor id, room id)
|
||||
if (!m_dtc->getStructureElementById(comparePlan.structureElementId(), se))
|
||||
continue;
|
||||
|
||||
const std::vector<int> &path = se.path();
|
||||
for(const auto &seId : path)
|
||||
conflictedStructElIds.insert(seId);
|
||||
|
||||
if(conflictedMainStructElements.contains(se.mainStructureElementId()))
|
||||
continue;
|
||||
|
||||
const MainStructureElement &mse = m_dtc->mainStructureElement(se.mainStructureElementId());
|
||||
conflictedMainStructElements.insert(mse.id(), mse);
|
||||
}// end if currentMountingPoint contains cmp mounting point plan
|
||||
}
|
||||
|
||||
#ifdef BENCHMARK
|
||||
qCritical() << " OverviewDialogModel::initData-BENCHMARK: compareSchedule took " << elapsedTimer1.elapsed() << " [ms]";
|
||||
#endif // BENCHMARK
|
||||
for (const MainStructureElement &mse : conflictedMainStructElements)
|
||||
{
|
||||
// only consider buildings
|
||||
if (mse.structureElementTypeId() != StructureElementType::Building)
|
||||
continue;
|
||||
|
||||
// 1- if a buildingGroup modelIndex for current building doesn't exist
|
||||
// a new one will be first added and used as parentIndex for the blg_Index.
|
||||
QModelIndex groupIndex;
|
||||
const StructureElement bse = setBuildingGroup(mse.groupId());
|
||||
if(!m_availableBuildingGroups.contains(bse.id()))
|
||||
{
|
||||
ConflictStructureElementData buildingGroup;
|
||||
buildingGroup.name = QString::fromStdString(bse.displayName());
|
||||
NGLTreeItem *groupItem = new NGLTreeItem(QVariant::fromValue(buildingGroup));
|
||||
QModelIndex groupParentIndex;
|
||||
groupParentIndex = indexFromItem(m_rootItem);
|
||||
|
||||
insertRow(rowCount(groupParentIndex), groupParentIndex, groupItem);
|
||||
groupIndex = index(groupItem->row(), 0, groupParentIndex);
|
||||
m_mountingPointIndexes.insert(bse.id(), groupIndex);
|
||||
|
||||
m_availableBuildingGroups.insert(bse.id());
|
||||
}
|
||||
else
|
||||
{
|
||||
groupIndex = m_mountingPointIndexes.value(bse.id(), indexFromItem(m_rootItem));
|
||||
}
|
||||
|
||||
for (const StructureElement ¤tElement : mse.elements())
|
||||
{
|
||||
NGLTreeItem *item = nullptr;
|
||||
if (!conflictedStructElIds.contains(currentElement.id()))
|
||||
continue;
|
||||
|
||||
if (currentElement.structureElementTypeId() == StructureElementType::MountingPoint)
|
||||
{
|
||||
if (!currentMountingPoints.contains(currentElement.id()))
|
||||
continue;
|
||||
|
||||
const MountingPointPlan &mountingPoint = currentMountingPoints[currentElement.id()];
|
||||
|
||||
// we don't care about Idle items
|
||||
if (mountingPoint.mountingPointState() == MountingPointState::Idle)
|
||||
continue;
|
||||
|
||||
auto compareMountingPointState = compareMountingPoints.value(currentElement.id()).mountingPointState();
|
||||
|
||||
if (mountingPoint.mountingPointState() == compareMountingPointState)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "No conflict for mounting point id = " << currentElement.id() << " - " << currentElement.name();
|
||||
continue;
|
||||
}
|
||||
|
||||
ConflictMountingPointData mpData;
|
||||
mpData.seType = currentElement.structureElementTypeId();
|
||||
mpData.id = currentElement.id();
|
||||
mpData.name = currentElement.displayName().empty() ? QString::fromStdString(currentElement.name()) : QString::fromStdString(currentElement.displayName());
|
||||
mpData.aimState = mountingPoint.mountingPointState();
|
||||
mpData.conflictState = compareMountingPointState;
|
||||
mpData.mpType = currentElement.mountingPointTypeId();
|
||||
|
||||
DEBUG_LOG(m_logger) << "## MP Id = " << mpData.id;
|
||||
DEBUG_LOG(m_logger) << "## MP Name = " << mpData.name;
|
||||
DEBUG_LOG(m_logger) << "## Aim state = " << mpData.aimState;
|
||||
|
||||
DEBUG_LOG(m_logger) << "Adding mounting point id = " << mpData.id << " - " << mpData.name;
|
||||
|
||||
item = new NGLTreeItem(QVariant::fromValue(mpData));
|
||||
}
|
||||
else
|
||||
{
|
||||
ConflictStructureElementData ssed;
|
||||
ssed.name = currentElement.displayName().empty() ? QString::fromStdString(currentElement.name()) : QString::fromStdString(currentElement.displayName());
|
||||
|
||||
item = new NGLTreeItem(QVariant::fromValue(ssed));
|
||||
}
|
||||
|
||||
const auto &path = currentElement.path();
|
||||
|
||||
QModelIndex parentIndex;
|
||||
if (path.size() > 1)
|
||||
{
|
||||
parentIndex = m_mountingPointIndexes.value(path.at(path.size() - 2), indexFromItem(m_rootItem)); //default sollte nie erreicht werden
|
||||
if (!parentIndex.isValid())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Did not find parent for structure element with id " << currentElement.id() << " mseid: " << mse.id();
|
||||
for (const StructureElement &se : mse.elements())
|
||||
DEBUG_LOG(m_logger) << " se: " << se.id() << ", " << se.displayName() << ", " << se.name();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Isn't indexFrom RootItem == QModelIndex() ?!?
|
||||
parentIndex = groupIndex.isValid() ? groupIndex : indexFromItem(m_rootItem);
|
||||
DEBUG_LOG(m_logger) << "Insert row under root: " << currentElement.displayName();
|
||||
}
|
||||
|
||||
insertRow(rowCount(parentIndex), parentIndex, item);
|
||||
|
||||
m_mountingPointIndexes.insert(currentElement.id(), index(item->row(), 0, parentIndex));
|
||||
}//end for-loop over conflicted structureelements
|
||||
|
||||
} //end for-loop over conflicted mainstructureelements
|
||||
|
||||
#ifdef BENCHMARK
|
||||
qCritical() << " OverviewDialogModel::initData-BENCHMARK: initData took " << elapsedTimer2.elapsed() << " [ms]";
|
||||
#endif // BENCHMARK
|
||||
}
|
||||
|
||||
}// namespace InfrastructureManagement
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The ConflictsDialog shows differences between 2 instrumentation plans
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Iuliana Ojog, SLTE, 2022-11-15
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
#include <QHash>
|
||||
#include <QTimer>
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
struct ConflictMountingPointData
|
||||
{
|
||||
int32_t id = 0; // se_id
|
||||
QString name; // se_name
|
||||
StructureElementType seType;
|
||||
MountingPointType mpType;
|
||||
MountingPointState aimState; // in Plan1 (m_scheduleId)
|
||||
MountingPointState conflictState; // in Plan2 (m_anotherScheduleId)
|
||||
|
||||
bool isMountingPoint() const { return seType == StructureElementType::MountingPoint; }
|
||||
};
|
||||
struct ConflictBuildingGroupData
|
||||
{
|
||||
QString name;
|
||||
};
|
||||
|
||||
struct ConflictStructureElementData
|
||||
{
|
||||
QString name;
|
||||
};
|
||||
|
||||
class ConflictsDialogModel final : public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
NAME,
|
||||
TYPE,
|
||||
AIM_STATE,
|
||||
CONFLICT_STATE
|
||||
};
|
||||
|
||||
explicit ConflictsDialogModel(QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override final;
|
||||
|
||||
bool initModel(int scheduleId, int anotherScheduleId,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc);
|
||||
|
||||
StructureElement setBuildingGroup(int groupId);
|
||||
|
||||
public slots:
|
||||
void onConflictedDataChanged();
|
||||
private:
|
||||
void initData();
|
||||
// friend class ConflictsDialogSortModel;
|
||||
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
|
||||
int32_t m_scheduleId;
|
||||
int32_t m_anotherScheduleId;
|
||||
|
||||
QHash<int, QModelIndex> m_mountingPointIndexes;
|
||||
QSet<int> m_availableBuildingGroups;
|
||||
QList<MountingPointType> m_visibleTypes;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
class ConflictsDialogSortModel final : public LtsWidgets::LtsColumnFilterProxyModel
|
||||
{
|
||||
using BaseClass = LtsWidgets::LtsColumnFilterProxyModel;
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel ) override;
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
|
||||
//QList<MountingPointType> getVisibleTypes() { return m_visibleTypes ;}
|
||||
|
||||
//using LtsWidgets::LtsColumnFilterProxyModel::invalidateFilter;
|
||||
|
||||
private:
|
||||
ConflictsDialogModel *m_sourceModel = nullptr;
|
||||
QList<MountingPointType> m_visibleTypes;
|
||||
};
|
||||
*/
|
||||
} // namespace InfrastructureManagement
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::ConflictMountingPointData)
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::ConflictStructureElementData)
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::ConflictBuildingGroupData)
|
||||
|
||||
|
||||
|
||||
Executable
+231
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The OverviewDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#include "ism_overview_dialog.h"
|
||||
#include "ism_overview_conflicts_dialog.h"
|
||||
#include "ui_ism_overview_dialog.h"
|
||||
#include "ism_overview_dialog_model.h"
|
||||
#include "ism_overview_conflicts_dialog.h"
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QDateTime>
|
||||
#include <QComboBox>
|
||||
#include <QTimer>
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
OverviewDialog::OverviewDialog(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_session(session)
|
||||
, m_ui(new Ui::OverviewDialog)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_logger(getLogger("OverviewDialog"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->setupUi(this);
|
||||
m_timerUpdateView = new QTimer(this);
|
||||
m_timerUpdateView->setSingleShot(true);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &OverviewDialog::onPrint);
|
||||
connect(m_ui->cbComparePlan, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &OverviewDialog::onCbComparePlanIndexChanged);
|
||||
connect(m_ui->cbBasePlan, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &OverviewDialog::onCbBasePlanIndexChanged);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Overview"));
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
OverviewDialog::~OverviewDialog()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
delete m_ui;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void OverviewDialog::aboutToClose()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "About to close";
|
||||
if (m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts")))
|
||||
m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts"))->closeRequest();
|
||||
}
|
||||
|
||||
void OverviewDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, m_dtc->mainSchedule(m_scheduleId), tr("Overview"));
|
||||
}
|
||||
|
||||
void OverviewDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->overviewView->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
bool OverviewDialog::init(int planId,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_scheduleId = planId;
|
||||
m_dtc = dtc;
|
||||
m_ftc = ftc;
|
||||
m_dataIfc = dataInterface;
|
||||
delete m_model;
|
||||
|
||||
setCbComparePlan();
|
||||
setCbBasePlan();
|
||||
m_model = new OverviewDialogModel(this);
|
||||
if (!m_model->initModel(m_scheduleId, m_dtc, 0))
|
||||
{
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
return false;
|
||||
}
|
||||
m_ui->overviewView->setModel(m_model);
|
||||
connect(m_dataIfc.get(), &ForeignDataInterface::scheduleIdChanged, this, &OverviewDialog::onScheduleIdChanged);
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainStructureElementChanged, this, &OverviewDialog::onPlansDataChanged);
|
||||
connect(m_dtc.get(), &Interface::Dtc::instrumentationAssetChanged, this, &OverviewDialog::onPlansDataChanged);
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainScheduleChanged, this, &OverviewDialog::onPlansDataChanged);
|
||||
|
||||
|
||||
connect(m_timerUpdateView, &QTimer::timeout, this, &OverviewDialog::reloadModel);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void OverviewDialog::setCbBasePlan()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->cbBasePlan->clear();
|
||||
m_ui->cbBasePlan->addItem(tr("Actual Mountings"), 0);
|
||||
m_ui->cbBasePlan->insertSeparator(1);
|
||||
for (auto ms : m_dtc->mainSchedules())
|
||||
m_ui->cbBasePlan->addItem(QString::fromStdString(ms.name()), ms.id());
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
void OverviewDialog::setCbComparePlan()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->cbComparePlan->clear();
|
||||
m_ui->cbComparePlan->addItem(tr("All active(*) plans"),0);
|
||||
m_ui->cbComparePlan->insertSeparator(1);
|
||||
for (auto ms : m_dtc->mainSchedules())
|
||||
m_ui->cbComparePlan->addItem((ms.statusId() == ScheduleStatus_def::Active ? QLatin1Literal("* ") : QLatin1Literal(" ")) +
|
||||
QString::fromStdString(ms.name()), ms.id());
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void OverviewDialog::onPrint()
|
||||
{
|
||||
MainSchedule ms = m_dtc->mainSchedule(m_scheduleId);
|
||||
|
||||
QString header;
|
||||
header += QStringLiteral("<p>");
|
||||
header += tr("Instrumentation Plan: %1").arg(QString::fromStdString(ms.name()));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += tr("Status: %1").arg(toString(ms.statusId()));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += tr("Created: %1").arg(DTG::toStringMSec(ms.timeCreated()));
|
||||
header += QStringLiteral("<br/>");
|
||||
if (ms.timeStart().is_set())
|
||||
header += tr("START: %1").arg(DTG::toStringMSec(ms.timeStart().get()));
|
||||
else
|
||||
header += tr("START: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral(" - ");
|
||||
if (ms.timeEnd().is_set())
|
||||
header += tr("END: %1").arg(DTG::toStringMSec(ms.timeEnd().get()));
|
||||
else
|
||||
header += tr("END: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += QStringLiteral("</p>");
|
||||
|
||||
LtsPrinting::printView(m_session, this, m_ui->overviewView->treeView() , header);
|
||||
}
|
||||
|
||||
void OverviewDialog::onScheduleIdChanged(int32_t scheduleId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_scheduleId == scheduleId)
|
||||
return;
|
||||
setCbComparePlan();
|
||||
setCbBasePlan();
|
||||
m_scheduleId = scheduleId;
|
||||
updateOverviewData();
|
||||
|
||||
// close Dialog OverviewConflicts, if open
|
||||
if (m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts")))
|
||||
m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts"))->closeRequest();
|
||||
|
||||
retranslate();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void OverviewDialog::onCbComparePlanIndexChanged(int index)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
Q_UNUSED(index);
|
||||
updateOverviewData();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void OverviewDialog::onCbBasePlanIndexChanged(int index)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
Q_UNUSED(index);
|
||||
updateOverviewData();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void OverviewDialog::onPlansDataChanged()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
updateOverviewData(); //reloadModel();
|
||||
ConflictsDialog *dialog = static_cast<ConflictsDialog*>(m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts")));
|
||||
if (dialog)
|
||||
{
|
||||
dialog->updateModel();
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void OverviewDialog::updateOverviewData()
|
||||
{
|
||||
m_timerUpdateView->start(100);
|
||||
}
|
||||
|
||||
void OverviewDialog::reloadModel()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_model == nullptr)
|
||||
return;
|
||||
|
||||
const int simPlanId = m_ui->cbBasePlan->currentData().toInt();
|
||||
const int cmpPlanId = m_ui->cbComparePlan->currentData().toInt();
|
||||
|
||||
m_model->initModel(m_scheduleId, m_dtc, cmpPlanId, simPlanId);
|
||||
|
||||
// close conflict dialog if opened
|
||||
if (m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts")))
|
||||
m_session->baseLayout()->getWidget(m_menuGroup, QStringLiteral("OverviewConflicts"))->closeRequest();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The OverviewDialog shows how many assets are needed for a specific schedule, needed elsewhere,
|
||||
* totally possessed, free, and missing
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <Plugins/InfrastructureManagement/Data/ism_data_plugin.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class OverviewDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class OverviewDialogModel;
|
||||
|
||||
class OverviewDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit OverviewDialog(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent = nullptr);
|
||||
~OverviewDialog();
|
||||
|
||||
bool init(int planId,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface);
|
||||
void setCbComparePlan();
|
||||
void setCbBasePlan();
|
||||
|
||||
protected:
|
||||
void aboutToClose() override;
|
||||
|
||||
private slots:
|
||||
void onPrint();
|
||||
void onScheduleIdChanged(int32_t scheduleId);
|
||||
void onCbComparePlanIndexChanged(int index);
|
||||
void onCbBasePlanIndexChanged(int index);
|
||||
void onPlansDataChanged();
|
||||
void updateOverviewData();
|
||||
void reloadModel();
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
Ui::OverviewDialog *m_ui{nullptr};
|
||||
int m_scheduleId{-1};
|
||||
OverviewDialogModel *m_model{nullptr};
|
||||
QString m_menuGroup;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc{nullptr};
|
||||
std::shared_ptr<Interface::Ftc> m_ftc{nullptr};
|
||||
std::shared_ptr<ForeignDataInterface> m_dataIfc{nullptr};
|
||||
ForeignResourceManagementGuiInterface *m_ismGuiIfc{nullptr};
|
||||
QTimer *m_timerUpdateView{nullptr};
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+86
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OverviewDialog</class>
|
||||
<widget class="QWidget" name="OverviewDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>630</width>
|
||||
<height>328</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Asset Availability</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbxBasePlan">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Base Plan:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbBasePlan"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbxComparePlan">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Plan to compare:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbComparePlan"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="overviewView" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+466
@@ -0,0 +1,466 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The OverviewDialogModel provides data for OverviewDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#include "ism_overview_dialog_model.h"
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
#include <algorithm>
|
||||
//#define BENCHMARK
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# include <QElapsedTimer>
|
||||
# include <QDebug>
|
||||
#endif
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
OverviewDialogModel::OverviewDialogModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<RowData>( {tr("Type"),
|
||||
tr("Base Demand"),
|
||||
tr("Compare Demand"),
|
||||
tr("Total Demand"),
|
||||
tr("Assets"),
|
||||
tr("Free assets"),
|
||||
tr("Available")
|
||||
},
|
||||
parent)
|
||||
, m_loadedScheduleId(-1)
|
||||
, m_comparedScheduleId(0)
|
||||
, m_dtc(nullptr)
|
||||
, m_logger(getLogger("OverviewDialogModel"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
//#define TEST
|
||||
|
||||
m_vecData = {RowData(MountingPointType::BuildingSensorModule),
|
||||
RowData(MountingPointType::EffectGenerationControlUnit),
|
||||
#ifdef TEST
|
||||
MountingPointType::BuildingControlUnit,
|
||||
MountingPointType::BuildingNetworkSwitch,
|
||||
MountingPointType::OutdoorCamera,
|
||||
MountingPointType::OutdoorControlUnit,
|
||||
MountingPointType::OutdoorIPS,
|
||||
MountingPointType::AnnouncementUnit,
|
||||
#endif
|
||||
RowData(MountingPointType::IndoorCamera),
|
||||
RowData(MountingPointType::IndoorIPS)}; //TODO: for Guez add OutdoorIPS, for non-Guez show separate!
|
||||
|
||||
m_refMap[MountingPointType_def::BuildingSensorModule] = 0;
|
||||
m_refMap[MountingPointType_def::EffectGenerationControlUnit] = 1;
|
||||
m_refMap[MountingPointType_def::IndoorCamera] = 2;
|
||||
m_refMap[MountingPointType_def::IndoorIPS] = 3;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
QVariant OverviewDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return {};
|
||||
|
||||
const auto &rowData = m_vecData.at(index.row());
|
||||
// If we want to display OutdoorIPS (as IndoorIPS) (later), we need to remove this and chnage mpt to IndoorIPS...
|
||||
if (rowData.mpt == MountingPointType::OutdoorIPS)
|
||||
return {};
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case TYPE:
|
||||
return toString(rowData.mpt);
|
||||
case BASEPLAN_DEMAND:
|
||||
return rowData.basePlanDemand;
|
||||
case COMPARED_DEMAND:
|
||||
return rowData.comparePlanDemand;
|
||||
case TOTAL_DEMAND:
|
||||
return rowData.totalDemand;
|
||||
case ASSETS_OWNED:
|
||||
return rowData.assetCount;
|
||||
case ASSETS_FREE:
|
||||
return rowData.assetsFree;
|
||||
case ASSETS_AVAILABLE:
|
||||
return rowData.assetsAvailable;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
else if (role == Qt::DecorationRole)
|
||||
{
|
||||
static const QIcon green(QLatin1String("icon:green_light.svg"));
|
||||
static const QIcon red(QLatin1String("icon:red_light.svg"));
|
||||
static const QIcon yellow(QLatin1String("icon:yellow_light.svg"));
|
||||
switch (index.column())
|
||||
{
|
||||
case ASSETS_AVAILABLE:
|
||||
{
|
||||
if (rowData.assetsAvailable == 0)
|
||||
return yellow;
|
||||
else
|
||||
return rowData.assetsAvailable < 0 ? red : green;
|
||||
}
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool OverviewDialogModel::initModel(int32_t mainScheduleId,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
int32_t comparedScheduleId, int32_t basePlanId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_dtc = dtc;
|
||||
m_loadedScheduleId = mainScheduleId;
|
||||
m_comparedScheduleId = comparedScheduleId;
|
||||
m_basePlanId = basePlanId;
|
||||
|
||||
m_mountingPointAssets = m_dtc->mountingPointAssets();
|
||||
|
||||
if (!m_dtc->mainSchedules().contains(m_loadedScheduleId))
|
||||
{
|
||||
m_loadedScheduleId = -1;
|
||||
ERROR_LOG(m_logger) << "Invalid scheduleId = " << mainScheduleId;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "[INITIAL] loaded: "<<m_loadedScheduleId<<" cmp: "<<m_comparedScheduleId<<" sim: "<<m_basePlanId;
|
||||
|
||||
if (!initData())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init data";
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "initModel successful";
|
||||
|
||||
// initModel will be executed later -> Qt::UniqueConnection
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainStructureElementChanged,
|
||||
this, &OverviewDialogModel::initData, Qt::UniqueConnection);
|
||||
connect(m_dtc.get(), &Interface::Dtc::mainScheduleChanged,
|
||||
this, &OverviewDialogModel::initData, Qt::UniqueConnection);
|
||||
connect(m_dtc.get(), &Interface::Dtc::instrumentationAssetChanged,
|
||||
this, &OverviewDialogModel::initData, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OverviewDialogModel::initData()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
#ifdef BENCHMARK
|
||||
QElapsedTimer elapsedTimer1;
|
||||
elapsedTimer1.start();
|
||||
#endif // BENCHMARK
|
||||
|
||||
beginResetModel();
|
||||
// m_neededPerType.clear();
|
||||
endResetModel();
|
||||
|
||||
|
||||
m_conflictedStructureElementIds.clear();
|
||||
|
||||
// if (m_basePlanId != 0)
|
||||
// setOverviewSimulatedData();
|
||||
// else
|
||||
// setOverviewData();
|
||||
setNewData();
|
||||
|
||||
for ( int mppId : qAsConst(m_conflictedStructureElementIds))
|
||||
DEBUG_LOG(m_logger) << "Conflicted structure element id = " << mppId;
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
MountingPointType OverviewDialogModel::getMountingPointTypeId(int structureElementId)
|
||||
{
|
||||
if (m_availableMountingPointTypes.contains(structureElementId))
|
||||
return m_availableMountingPointTypes[structureElementId];
|
||||
|
||||
StructureElement se;
|
||||
if (!m_dtc->getStructureElementById(structureElementId, se))
|
||||
return MountingPointType_def::get_default();
|
||||
|
||||
//OutdoorIPS will be considered as IndoorIPS
|
||||
const MountingPointType mpType = (se.mountingPointTypeId() == MountingPointType_def::OutdoorIPS) ? MountingPointType_def::IndoorIPS : se.mountingPointTypeId();
|
||||
m_availableMountingPointTypes.insert(structureElementId, mpType);
|
||||
return mpType;
|
||||
}
|
||||
|
||||
bool OverviewDialogModel::hasMountedAsset(int seId)
|
||||
{
|
||||
for (const InfrastructureManagement::MountingPointAsset &asset : qAsConst(m_mountingPointAssets))
|
||||
{
|
||||
if (asset.structureElementId() == seId)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OverviewDialogModel::hasConflictedMountingPoints()
|
||||
{
|
||||
return !m_conflictedStructureElementIds.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OverviewDialogModel::mergePlans
|
||||
* @param currPlanId : loaded schedule id
|
||||
* @param currPlan : current active mounting points
|
||||
* @param cmpPlanId: plan == 0: no compare plan | plan > 0: plan to compare with
|
||||
* @return
|
||||
*/
|
||||
QHash<int/*sructElId*/, MountingPointPlan> OverviewDialogModel::mergePlans(const QHash<int/*sructElId*/, MountingPointPlan> &currPlan, const int cmpPlanId)
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<"[MERGE PLANs] currPlanId: "<<m_loadedScheduleId<<" ; cmpPlanId: "<<cmpPlanId;
|
||||
QHash<int/*sructElId*/, MountingPointPlan> mergedPlan = currPlan;
|
||||
// iterate over all active plan
|
||||
const auto msConst = m_dtc->mainSchedules();
|
||||
for (const auto &schedule : msConst)
|
||||
{
|
||||
if (cmpPlanId == 0 && schedule.statusId() != ScheduleStatus_def::Active)
|
||||
continue;
|
||||
if (cmpPlanId != 0 && cmpPlanId != schedule.id())
|
||||
continue;
|
||||
|
||||
for (const MountingPointPlan ¤tMpp : schedule.elements())
|
||||
{
|
||||
if (m_conflictedStructureElementIds.contains(currentMpp.structureElementId()))
|
||||
continue;
|
||||
|
||||
const MountingPointType mpType = getMountingPointTypeId(currentMpp.structureElementId());
|
||||
|
||||
if (!m_refMap.contains(mpType))
|
||||
continue;
|
||||
|
||||
if (currPlan.contains(currentMpp.structureElementId()))
|
||||
{
|
||||
const MountingPointPlan &basePlanMpp = currPlan[currentMpp.structureElementId()];
|
||||
|
||||
/// 1. conflicted when 1&2: equipped | empty.
|
||||
/// 2. state of merge is idle when on conflict
|
||||
if ((basePlanMpp.mountingPointState() == MountingPointState::Equipped && currentMpp.mountingPointState() == MountingPointState::Empty) ||
|
||||
(basePlanMpp.mountingPointState() == MountingPointState::Empty && currentMpp.mountingPointState() == MountingPointState::Equipped))
|
||||
{
|
||||
DEBUG_LOG(m_logger)<<" conflicted name: "<<currentMpp.structureElementId();
|
||||
mergedPlan[currentMpp.structureElementId()].mountingPointState(MountingPointState::Idle);
|
||||
m_conflictedStructureElementIds.insert(basePlanMpp.structureElementId());
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(basePlanMpp.mountingPointState().underlying())
|
||||
{
|
||||
case MountingPointState_def::Empty:
|
||||
mergedPlan[currentMpp.structureElementId()].mountingPointState(MountingPointState::Empty);
|
||||
break;
|
||||
case MountingPointState_def::Equipped:
|
||||
mergedPlan[currentMpp.structureElementId()].mountingPointState(MountingPointState::Equipped);
|
||||
break;
|
||||
case MountingPointState_def::Idle:
|
||||
mergedPlan[currentMpp.structureElementId()].mountingPointState(currentMpp.mountingPointState());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mergedPlan[currentMpp.structureElementId()] = currentMpp;
|
||||
}
|
||||
}//end for-loop over mountingPointPlans
|
||||
}// end for-loop over schedules
|
||||
return mergedPlan;
|
||||
}
|
||||
|
||||
void OverviewDialogModel::setNewData()
|
||||
{
|
||||
QHash<int /*<structureElementId>*/, MountingPointPlan> baseMountingPointPlans;
|
||||
|
||||
// If basePlanId == 0 -> current actual status is used.
|
||||
DEBUG_LOG(m_logger) << "We compare plan " << m_basePlanId << " with " << m_comparedScheduleId;
|
||||
|
||||
baseMountingPointPlans.clear();
|
||||
m_conflictedStructureElementIds.clear();
|
||||
|
||||
// ...on InstrumentationAssetsChanged(); || BasePlanChanged and BasePlanId == 0
|
||||
for (int id : qAsConst(m_refMap))
|
||||
{
|
||||
m_vecData[id] = RowData(m_vecData[id].mpt);
|
||||
// val.assetCount = 0;
|
||||
// val.assetsDefect = 0;
|
||||
// val.assetsFree = 0;
|
||||
// val.assetsMounted = 0;
|
||||
// val.basePlanDemand = 0;
|
||||
// val.basePlanUnmount = 0;
|
||||
}
|
||||
const auto iaConst = m_dtc->instrumentationAssets();
|
||||
for (const InstrumentationAsset &asset : iaConst )
|
||||
{
|
||||
//OutdoorIPS will be considered as IndoorIPS
|
||||
const MountingPointType mpType = (asset.mountingPointTypeId() == MountingPointType::OutdoorIPS) ? MountingPointType::IndoorIPS : asset.mountingPointTypeId();
|
||||
if (!m_refMap.contains(mpType))
|
||||
continue;
|
||||
|
||||
++m_vecData[m_refMap[mpType]].assetCount;
|
||||
|
||||
/// Defekte Komponente
|
||||
if (asset.assetStateId() == InstrumentationAssetState_def::Defect)
|
||||
++m_vecData[m_refMap[mpType]].assetsDefect;
|
||||
|
||||
if (asset.assetStateId() == InstrumentationAssetState_def::Unmounted)
|
||||
++m_vecData[m_refMap[mpType]].assetsFree;
|
||||
|
||||
if (asset.assetStateId() == InstrumentationAssetState_def::Mounted)
|
||||
{
|
||||
++m_vecData[m_refMap[mpType]].assetsMounted;
|
||||
if (m_basePlanId == 0)
|
||||
++m_vecData[m_refMap[mpType]].basePlanDemand;
|
||||
}
|
||||
}
|
||||
|
||||
// onMainSchedule[basePlanId]Changed || basePlanId changed
|
||||
|
||||
// for (auto id : m_refMap)
|
||||
// {
|
||||
// auto &val = m_vecData[id];
|
||||
// val.basePlanDemand = 0;
|
||||
// val.basePlanUnmount = 0;
|
||||
// }
|
||||
|
||||
if (m_basePlanId > 0)
|
||||
{
|
||||
MainSchedule baseSchedule = m_dtc->mainSchedules().value(m_basePlanId);
|
||||
|
||||
for (const MountingPointPlan &mpp : baseSchedule.elements())
|
||||
{
|
||||
const MountingPointType mpType = getMountingPointTypeId(mpp.structureElementId());
|
||||
|
||||
if (!m_refMap.contains(mpType))
|
||||
continue;
|
||||
|
||||
baseMountingPointPlans.insert(mpp.structureElementId(), mpp);
|
||||
|
||||
if (mpp.mountingPointState() == MountingPointState::Equipped)
|
||||
++m_vecData[m_refMap[mpType]].basePlanDemand;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Todo: Save this in m_currentMountingPointState and update onMSEChanged(), here: Get a copy into m_mergedMountingPoints
|
||||
const auto msesConst = m_dtc->mainStructureElements();
|
||||
for(const auto &mse : msesConst)
|
||||
for (const auto &se : mse.elements())
|
||||
if (hasMountedAsset(se.id()))
|
||||
baseMountingPointPlans.insert(se.id(), MountingPointPlan(se.id(), MountingPointState_def::Equipped));
|
||||
}
|
||||
|
||||
|
||||
QHash<int/*sructElId*/, MountingPointPlan> comparedMountingPointPlans = mergePlans({}, m_comparedScheduleId);
|
||||
|
||||
QHash<int/*sructElId*/, MountingPointPlan> totalMPPs = comparedMountingPointPlans;
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
|
||||
QHashIterator<int, MountingPointPlan> it(baseMountingPointPlans);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
totalMPPs.insert(it.key(), it.value());
|
||||
}
|
||||
#else
|
||||
totalMPPs.insert(baseMountingPointPlans);
|
||||
#endif //
|
||||
|
||||
|
||||
/// Übergreifender Bedarf
|
||||
for(const auto &bla: totalMPPs)
|
||||
{
|
||||
MountingPointPlan compareMpp = comparedMountingPointPlans.value(bla.structureElementId(), MountingPointPlan(bla.structureElementId(), MountingPointState_def::Idle));
|
||||
MountingPointPlan baseMpp = baseMountingPointPlans.value(bla.structureElementId(), MountingPointPlan(bla.structureElementId(), MountingPointState_def::Idle));
|
||||
|
||||
const MountingPointType mpType = getMountingPointTypeId(bla.structureElementId());
|
||||
if (!m_refMap.contains(mpType))
|
||||
continue;
|
||||
|
||||
|
||||
switch(baseMpp.mountingPointState().underlying())
|
||||
{
|
||||
case MountingPointState_def::Empty:
|
||||
if (compareMpp.mountingPointState() == MountingPointState_def::Equipped)
|
||||
++m_vecData[m_refMap[mpType]].totalDemand;
|
||||
break;
|
||||
case MountingPointState_def::Equipped:
|
||||
if (compareMpp.mountingPointState() != MountingPointState_def::Equipped)
|
||||
--m_vecData[m_refMap[mpType]].totalDemand;
|
||||
break;
|
||||
case MountingPointState_def::Idle:
|
||||
if (compareMpp.mountingPointState() == MountingPointState_def::Equipped)
|
||||
++m_vecData[m_refMap[mpType]].totalDemand;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(compareMpp.mountingPointState().underlying())
|
||||
{
|
||||
case MountingPointState_def::Equipped:
|
||||
++m_vecData[m_refMap[mpType]].comparePlanDemand;
|
||||
break;
|
||||
case MountingPointState_def::Empty:
|
||||
++m_vecData[m_refMap[mpType]].comparePlanUnmount;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Verfügbarer Bestand: ASSETS_OWNED - DEFECT_ASSETS - MERGED_MOUNTED_ASSET - NEED_EQUIPPED + MERGE_TO_UNMOUNT_ASSETS
|
||||
/// Freie Komponente bei simulation: ASSETS_OWNED - MERGED_MOUNTED_ASSET - DEFEKT_ASSETS
|
||||
for (auto id : qAsConst(m_refMap))
|
||||
{
|
||||
auto &rowData = m_vecData[id];
|
||||
|
||||
const int availableAssetCount =
|
||||
rowData.assetCount
|
||||
- rowData.assetsDefect
|
||||
- rowData.assetsMounted
|
||||
- rowData.comparePlanDemand
|
||||
+ rowData.comparePlanUnmount;
|
||||
|
||||
rowData.assetsAvailable = availableAssetCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString RowData::toString() const
|
||||
{
|
||||
return QStringLiteral("MPT ") + InfrastructureManagement::toString(mpt) +
|
||||
QStringLiteral(", bpDem: ") + QString::number(basePlanDemand) +
|
||||
QStringLiteral(", pbDiff: ") + QString::number(basePlanDifference) +
|
||||
QStringLiteral(", cpDem: ") + QString::number(comparePlanDemand) +
|
||||
QStringLiteral(", cpUmnt: ") + QString::number(comparePlanUnmount) +
|
||||
QStringLiteral(", toDem: ") + QString::number(totalDemand) +
|
||||
QStringLiteral(", asCnt: ") + QString::number(assetCount) +
|
||||
QStringLiteral(", asFre: ") + QString::number(assetsFree) +
|
||||
QStringLiteral(", AsAv: ") + QString::number(assetsAvailable) +
|
||||
QStringLiteral(", AsMt: ") + QString::number(assetsMounted) +
|
||||
QStringLiteral(", AsDef: ") + QString::number(assetsDefect);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Executable
+108
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The OverviewDialogModel provides data for OverviewDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2016-11-03
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
struct RowData
|
||||
{
|
||||
MountingPointType mpt;
|
||||
int basePlanDemand{0}; // "PlanBedarf" (Basisplan)
|
||||
int basePlanDifference{0}; // Differenzbedarf (zum aktuellen Anbaustatus)
|
||||
|
||||
int comparePlanDemand{0}; // "Planbedarf" (VGL Einrüstplan) (= Differenz zu Basisplan)
|
||||
int comparePlanUnmount{0}; // Im Vergleichsplan zu als demontiert markierte Assets.
|
||||
|
||||
int totalDemand{0}; // "Übergreifender Bedarf"
|
||||
|
||||
int assetCount{0}; // "Komponentenbestand" // All asset states
|
||||
int assetsFree{0}; // "Freie Komponenten" // AssetState: Unmounted
|
||||
int assetsAvailable{0}; // "Verfügbarer Bestand"
|
||||
int assetsMounted{0}; // Aktuell gemountete Assets // AssetState: Mounted
|
||||
int assetsDefect{0}; // Aktuell als defekt deklarierte Assets // AssetState: Defect
|
||||
|
||||
explicit RowData(MountingPointType _mpt)
|
||||
: mpt(_mpt){}
|
||||
QString toString() const;
|
||||
};
|
||||
|
||||
class OverviewDialogModel : public LtsWidgets::LtsAbstractTableModel<RowData>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OverviewDialogModel(QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
bool initModel(int32_t mainScheduleId,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
int32_t comparedScheduleId = 0,
|
||||
int32_t basePlanId = 0);
|
||||
|
||||
bool initData();
|
||||
// void setOverviewData();
|
||||
// void setOverviewSimulatedData();
|
||||
void setNewData();
|
||||
bool hasConflictedMountingPoints();
|
||||
|
||||
QMap<MountingPointType, int> getOtherActiveNeeded(const int &currPlanId);
|
||||
|
||||
private: // methods
|
||||
QHash<int, MountingPointPlan> mergePlans(const QHash<int, MountingPointPlan> &currPlan, const int cmpPlanId);
|
||||
void setTotalCmpActiveNeed(const QMap<int, MountingPointPlan> &mergedPlan);
|
||||
MountingPointType getMountingPointTypeId(int structureElementId);
|
||||
bool hasMountedAsset(int seId);
|
||||
|
||||
private: // other
|
||||
enum Columns
|
||||
{
|
||||
TYPE =0,
|
||||
BASEPLAN_DEMAND , // needed in current plan
|
||||
COMPARED_DEMAND , // needed in compared plan
|
||||
TOTAL_DEMAND , // needed current plan + needed in compared plan
|
||||
ASSETS_OWNED , // TOTAL components in system
|
||||
ASSETS_FREE , // total unmounted assets
|
||||
ASSETS_AVAILABLE , // OWNED - mounted + to_unmount (FREE + assets_to_unmount, maximal TOTAL owned)
|
||||
|
||||
COLUMNs_COUNT // not displayed in view
|
||||
};
|
||||
|
||||
|
||||
private: // attributes
|
||||
|
||||
// QMap<MountingPointType, QVector<int>> m_neededPerType;
|
||||
QHash<int/*seId*/, MountingPointType> m_availableMountingPointTypes;
|
||||
|
||||
int32_t m_loadedScheduleId{-1}; // loaded plan
|
||||
int32_t m_basePlanId{0}; // simulated plan
|
||||
int32_t m_comparedScheduleId{0}; // plan to compare with
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
/**
|
||||
* @brief m_includedMountingPoints
|
||||
* contains all mpt from : loaded plan + (active plan or cmp plan). conflicted mntp are not included
|
||||
*/
|
||||
QSet<int /*<structureElementId>*/> m_conflictedStructureElementIds;
|
||||
|
||||
QMap<qint32, InfrastructureManagement::MountingPointAsset> m_mountingPointAssets;
|
||||
|
||||
QMap<MountingPointType, int> m_refMap;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class OverviewDialogModel
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
+520
@@ -0,0 +1,520 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* tbc
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by
|
||||
*/
|
||||
|
||||
#include "ism_overview_mounting_point_list_dialog.h"
|
||||
#include "ui_ism_overview_mounting_point_list_dialog.h"
|
||||
|
||||
#include <QTreeView>
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <qlabel.h>
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
#include <InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <QMessageBox>
|
||||
#include <QHeaderView>
|
||||
#include <qscrollbar.h>
|
||||
|
||||
using namespace InfrastructureManagement;
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::OverviewMountingPointListDialog
|
||||
* \param menuGroup
|
||||
* \param parent
|
||||
*/
|
||||
OverviewMountingPointListDialog::OverviewMountingPointListDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_ui(new Ui::OverViewMountingPointListDialog)
|
||||
, m_logger(getLogger("OverviewMountingPointListDialog"))
|
||||
, m_actionMenu(new QMenu(this))
|
||||
, m_printMountingAction(new QAction(tr("To Mount"), this))
|
||||
, m_printUnmountingAction(new QAction(tr("To Unmount"), this))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
m_ui->setupUi(this);
|
||||
setOnlineHelpFilename(QStringLiteral("Ressourcen-Completness_Check"));
|
||||
|
||||
m_buttonBox->setButtonVisible(LtsWidgets::DialogButton::Print, true);
|
||||
m_actionMenu->addAction(m_printMountingAction);
|
||||
m_actionMenu->addAction(m_printUnmountingAction);
|
||||
connect(m_actionMenu, &QMenu::triggered, this, &OverviewMountingPointListDialog::onPrint);
|
||||
|
||||
m_buttonBox->setMenu(LtsWidgets::DialogButton::Print, m_actionMenu);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
OverviewMountingPointListDialog::~OverviewMountingPointListDialog()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
delete m_ui;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::init
|
||||
* \param session
|
||||
* \param dtc
|
||||
* \param ftc
|
||||
* \param dataInterface
|
||||
* \return
|
||||
*/
|
||||
bool OverviewMountingPointListDialog::init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface,
|
||||
int32_t scheduleId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, scheduleId=" << scheduleId;
|
||||
m_dtc = dtc;
|
||||
m_dataIfc = dataInterface;
|
||||
m_session = session;
|
||||
m_ftc = ftc;
|
||||
m_scheduleId = scheduleId;
|
||||
|
||||
// disconnect(m_ui->mountingPointListView);
|
||||
// disconnect(this);
|
||||
if (!m_ftc->enableInstrumentationAssetModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT InstrumentationAssetModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_ftc->enableMountingPointPlanModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable FT enableMountingPointPlansModify of ISM";
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " new ViewMountingPointListModel...";
|
||||
delete m_sourceModel;
|
||||
m_sourceModel = new ViewMountingPointListModel(this);
|
||||
|
||||
if (!m_sourceModel->initModel(m_dtc, m_dataIfc, m_scheduleId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
delete m_sourceModel;
|
||||
m_sourceModel = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// current state is equipped -> to unmount
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " new m_mountedPointSortProxyModel ...";
|
||||
delete m_mountedPointSortProxyModel;
|
||||
m_mountedPointSortProxyModel = new ViewMountingPointListSortModel(this);
|
||||
m_mountedPointSortProxyModel->setVisibleState(MountingPointState::Equipped);
|
||||
m_mountedPointSortProxyModel->setSourceModel(m_sourceModel);
|
||||
m_mountedPointSortProxyModel->sort(0, Qt::AscendingOrder);
|
||||
connect(m_sourceModel, &ViewMountingPointListModel::dataChanged, m_mountedPointSortProxyModel, &ViewMountingPointListSortModel::invalidateFilter);
|
||||
|
||||
m_ui->mountingPointListView->setModel(m_mountedPointSortProxyModel);
|
||||
m_ui->mountingPointListView->setSortingEnabled(true);
|
||||
|
||||
/// current state is empty -> to mount
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " new m_unmountedPointSortProxyModel ...";
|
||||
delete m_unmountedPointSortProxyModel;
|
||||
m_unmountedPointSortProxyModel = new ViewMountingPointListSortModel(this);
|
||||
m_unmountedPointSortProxyModel->setVisibleState(MountingPointState::Empty);
|
||||
m_unmountedPointSortProxyModel->setSourceModel(m_sourceModel);
|
||||
m_unmountedPointSortProxyModel->sort(0, Qt::AscendingOrder);
|
||||
connect(m_sourceModel, &ViewMountingPointListModel::dataChanged, m_unmountedPointSortProxyModel, &ViewMountingPointListSortModel::invalidateFilter);
|
||||
|
||||
m_ui->unmountingPointListView->setModel(m_unmountedPointSortProxyModel);
|
||||
m_ui->unmountingPointListView->setSortingEnabled(true);
|
||||
|
||||
m_ui->mountingPointListView->treeView()->setColumnWidth(0, 315);
|
||||
m_ui->mountingPointListView->treeView()->setColumnWidth(1, 160);
|
||||
// m_ui->mountingPointListView->treeView()->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
// m_ui->mountingPointListView->treeView()->header()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
m_ui->mountingPointListView->searchView()->setColumnWidth(0, 315);
|
||||
m_ui->mountingPointListView->searchView()->setColumnWidth(1, 160);
|
||||
// m_ui->mountingPointListView->searchView()->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
// m_ui->mountingPointListView->searchView()->header()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
|
||||
m_ui->unmountingPointListView->treeView()->setColumnWidth(0, 315);
|
||||
m_ui->unmountingPointListView->treeView()->setColumnWidth(1, 160);
|
||||
// m_ui->unmountingPointListView->treeView()->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
// m_ui->unmountingPointListView->treeView()->header()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
m_ui->unmountingPointListView->searchView()->setColumnWidth(0, 315);
|
||||
m_ui->unmountingPointListView->searchView()->setColumnWidth(1, 160);
|
||||
// m_ui->unmountingPointListView->searchView()->header()->setSectionResizeMode(1, QHeaderView::Fixed);
|
||||
// m_ui->unmountingPointListView->searchView()->header()->setSectionResizeMode(0, QHeaderView::Fixed);
|
||||
|
||||
//------------- Filter ----------------
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " filter... ...";
|
||||
const auto filters = { MountingPointType::BuildingSensorModule,
|
||||
// MountingPointType::OutdoorCamera,
|
||||
// MountingPointType::BuildingControlUnit,
|
||||
MountingPointType::IndoorCamera,
|
||||
//MountingPointType::OutdoorIPS, //TODO: Remove OutdoorIPS from Enum in EnterpriseArchitect
|
||||
MountingPointType::IndoorIPS,
|
||||
// MountingPointType::AnnouncementUnit,
|
||||
MountingPointType::EffectGenerationControlUnit
|
||||
// MountingPointType::BuildingNetworkSwitch
|
||||
};
|
||||
|
||||
m_ui->lwMountingPointType->setSelectionMode(QAbstractItemView::SelectionMode::MultiSelection);
|
||||
connect(m_ui->lwMountingPointType, &QListWidget::itemSelectionChanged,
|
||||
this, [this]()
|
||||
{
|
||||
QVector<MountingPointType> types;
|
||||
types << MountingPointType::Unknown;
|
||||
for (const QListWidgetItem *lwi : m_ui->lwMountingPointType->findItems(QLatin1String(""), Qt::MatchContains))
|
||||
{
|
||||
MountingPointType mpt = static_cast<MountingPointType::inner_enum>(lwi->data(Qt::UserRole).toInt());
|
||||
if (lwi->isSelected())
|
||||
types << mpt;
|
||||
m_mountedPointSortProxyModel->addToTypeFilter(mpt, lwi->isSelected());
|
||||
m_unmountedPointSortProxyModel->addToTypeFilter(mpt, lwi->isSelected());
|
||||
|
||||
m_ui->mountingPointListView->treeView()->expandAll();
|
||||
m_ui->unmountingPointListView->treeView()->expandAll();
|
||||
}
|
||||
});
|
||||
|
||||
for (const MountingPointType currentFilter : filters)
|
||||
addMountingPointTypeFilter(currentFilter);
|
||||
|
||||
// connect is used to to enable Accept/Ok Buttons
|
||||
connect(m_sourceModel, &ViewMountingPointListModel::dataChanged, this, &OverviewMountingPointListDialog::onDataChanged);
|
||||
|
||||
|
||||
// mounted view
|
||||
connect(m_ui->mountingPointListView->searchView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(m_ui->mountingPointListView->treeView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
// unmounted view
|
||||
connect(m_ui->unmountingPointListView->searchView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->unmountingPointListView->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(m_ui->unmountingPointListView->treeView()->horizontalScrollBar(), &QScrollBar::rangeChanged,
|
||||
this, [this]()
|
||||
{
|
||||
m_ui->unmountingPointListView->slotSetHorizontalRange(0,0);
|
||||
}, Qt::QueuedConnection);
|
||||
|
||||
connect(m_dataIfc.get(), &ForeignDataInterface::scheduleIdChanged,
|
||||
this, &OverviewMountingPointListDialog::onScheduleIdChanged);
|
||||
|
||||
|
||||
m_ui->mountingPointListView->treeView()->expandAll();
|
||||
m_ui->unmountingPointListView->treeView()->expandAll();
|
||||
|
||||
// context menu expand / collapse treeview
|
||||
m_ui->mountingPointListView->setContextMenuPolicyPerView(LtsDataView::LtsDataView::Page::TABLE, Qt::CustomContextMenu);
|
||||
connect(m_ui->mountingPointListView->treeView(), &QTreeView::customContextMenuRequested,
|
||||
this, &OverviewMountingPointListDialog::onMountedCustomContextMenu);
|
||||
m_ui->unmountingPointListView->setContextMenuPolicyPerView(LtsDataView::LtsDataView::Page::TABLE, Qt::CustomContextMenu);
|
||||
connect(m_ui->unmountingPointListView->treeView(), &QTreeView::customContextMenuRequested,
|
||||
this, &OverviewMountingPointListDialog::onUnMountedCustomContextMenu);
|
||||
|
||||
// update title:
|
||||
retranslate();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::retranslate
|
||||
*/
|
||||
void OverviewMountingPointListDialog::retranslate()
|
||||
{
|
||||
if (m_dtc)
|
||||
{
|
||||
MainSchedule ms = m_dtc->mainSchedule(m_scheduleId);
|
||||
const QString msName = QString::fromStdString(ms.name());
|
||||
translate(m_ui, tr("Completeness Check '%1'").arg(msName));
|
||||
}
|
||||
else
|
||||
translate(m_ui, tr("Completeness Check"));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::addMountingPointTypeFilter
|
||||
* \param mpt
|
||||
*/
|
||||
void OverviewMountingPointListDialog::addMountingPointTypeFilter(MountingPointType mpt)
|
||||
{
|
||||
QListWidgetItem *lwi = new QListWidgetItem(m_ui->lwMountingPointType);
|
||||
bool isInitChecked = true;
|
||||
|
||||
m_mountedPointSortProxyModel->addToTypeFilter(mpt, isInitChecked);
|
||||
m_unmountedPointSortProxyModel->addToTypeFilter(mpt, isInitChecked);
|
||||
lwi->setData(Qt::UserRole, mpt.underlying());
|
||||
const QString text = toString(mpt);
|
||||
lwi->setText(text);
|
||||
lwi->setSelected(isInitChecked);
|
||||
}
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::onDataChanged
|
||||
* \param topLeft
|
||||
* \param bottomRight
|
||||
* \param roles
|
||||
*/
|
||||
void OverviewMountingPointListDialog::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
{
|
||||
Q_UNUSED(topLeft);
|
||||
Q_UNUSED(bottomRight);
|
||||
Q_UNUSED(roles);
|
||||
slotChangesMade();
|
||||
m_ui->mountingPointListView->treeView()->expandAll();
|
||||
m_ui->unmountingPointListView->treeView()->expandAll();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::onPrint
|
||||
* \param action
|
||||
*/
|
||||
void OverviewMountingPointListDialog::onPrint(QAction *action)
|
||||
{
|
||||
MainSchedule ms = m_dtc->mainSchedule(m_dataIfc->scheduleId());
|
||||
QString header;
|
||||
header += QStringLiteral("<p>");
|
||||
header += tr("Instrumentation Plan: %1").arg(QString::fromStdString(ms.name()));
|
||||
header += QStringLiteral("<br/>");
|
||||
header += tr("Created: %1").arg(DTG::toStringMSec(ms.timeCreated()));
|
||||
header += QStringLiteral("<br/>");
|
||||
if (ms.timeStart().is_set())
|
||||
header += tr("START: %1").arg(DTG::toStringMSec(ms.timeStart().get()));
|
||||
else
|
||||
header += tr("START: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral(" - ");
|
||||
if (ms.timeEnd().is_set())
|
||||
header += tr("END: %1").arg(DTG::toStringMSec(ms.timeEnd().get()));
|
||||
else
|
||||
header += tr("END: %1").arg(tr("[N/A]"));
|
||||
header += QStringLiteral("<br/>");
|
||||
|
||||
QString filterTypes;
|
||||
if(!getUsedFilterTypes().isEmpty())
|
||||
{
|
||||
QStringList filterList = getUsedFilterTypes();
|
||||
header += QStringLiteral("<br/>");
|
||||
filterTypes = tr("<b>Active filter:</b>");
|
||||
filterTypes += QStringLiteral("<ul>");
|
||||
for (int i=0; i<filterList.count(); i++ ) {
|
||||
filterTypes += QStringLiteral("<li>%1</li>").arg(filterList.at(i));
|
||||
}
|
||||
filterTypes += QStringLiteral("</ul><br/>");
|
||||
header += filterTypes;
|
||||
}
|
||||
if (action->text() == m_printMountingAction->text())
|
||||
{
|
||||
//
|
||||
header += tr("The following items have to be mounted:");
|
||||
header += QStringLiteral("<br/>");
|
||||
header += QStringLiteral("</p>");
|
||||
|
||||
m_ui->mountingPointListView->expandAll();
|
||||
if(itemsHaveNoChildren(m_ui->mountingPointListView->treeView()) == false)
|
||||
LtsPrinting::printView(m_session, this, m_ui->mountingPointListView->treeView(), header );
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("Completeness Check"), tr("There is No Entry to Print"), QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
else if (action->text() == m_printUnmountingAction->text())
|
||||
{
|
||||
header += tr("The following items have to be unmounted:");
|
||||
header += QStringLiteral("<br/>");
|
||||
header += QStringLiteral("</p>");
|
||||
m_ui->unmountingPointListView->expandAll();
|
||||
if(itemsHaveNoChildren(m_ui->unmountingPointListView->treeView()) == false)
|
||||
LtsPrinting::printView(m_session, this, m_ui->unmountingPointListView->treeView(), header );
|
||||
else
|
||||
{
|
||||
QMessageBox::warning(this, tr("Completeness Check"), tr("There is No Entry to Print"), QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::itemsHaveNoChildren
|
||||
* \param view
|
||||
* \return
|
||||
*/
|
||||
bool OverviewMountingPointListDialog::itemsHaveNoChildren(const QTreeView *view)
|
||||
{
|
||||
const QAbstractItemModel *itemModel = view->model();
|
||||
int rowCount = itemModel->rowCount();
|
||||
for (int row = 0; row < rowCount; ++row)
|
||||
{
|
||||
if (itemModel->hasChildren(itemModel->index(row, 0)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void OverviewMountingPointListDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->mountingPointListView->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::getUsedFilterTypes
|
||||
* get the list of the selected filter
|
||||
* \return QStringList
|
||||
*/
|
||||
QStringList OverviewMountingPointListDialog::getUsedFilterTypes()
|
||||
{
|
||||
QStringList filterList;
|
||||
for (const QListWidgetItem *lwi : m_ui->lwMountingPointType->findItems(QLatin1String(""), Qt::MatchContains))
|
||||
{
|
||||
MountingPointType mpt = static_cast<MountingPointType::inner_enum>(lwi->data(Qt::UserRole).toInt());
|
||||
if (lwi->isSelected())
|
||||
filterList<<toString(mpt);
|
||||
}
|
||||
return filterList;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::onScheduleIdChanged
|
||||
* \param scheduleId
|
||||
*/
|
||||
void OverviewMountingPointListDialog::onScheduleIdChanged(int32_t scheduleId)
|
||||
{
|
||||
if (scheduleId == m_scheduleId)
|
||||
return;
|
||||
// scheduleId changed, data is maybe invalid -> close dialog:
|
||||
this->close(); // Since Qt::WA_DeleteOnClose the dtor will be called :-)
|
||||
}
|
||||
|
||||
void OverviewMountingPointListDialog::onMountedCustomContextMenu(QPoint pos)
|
||||
{
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
contextMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->expandAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->mountingPointListView->collapseAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->addSeparator();
|
||||
QModelIndex index = m_ui->mountingPointListView->treeView()->indexAt(pos);
|
||||
bool hasChildren = m_ui->mountingPointListView->treeView()->model()->rowCount(index) > 0;
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,13,0)
|
||||
m_ui->dvConflicts->treeView()->expand(index);
|
||||
#else
|
||||
m_ui->mountingPointListView->treeView()->expandRecursively(index);
|
||||
#endif
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
m_ui->mountingPointListView->treeView()->collapse(index);
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->popup(m_ui->mountingPointListView->treeView()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void OverviewMountingPointListDialog::onUnMountedCustomContextMenu(QPoint pos)
|
||||
{
|
||||
QMenu *contextMenu = new QMenu(this);
|
||||
contextMenu->setAttribute(Qt::WA_DeleteOnClose);
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->unmountingPointListView->expandAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse All"), this);
|
||||
action->setEnabled(true);
|
||||
connect(action, &QAction::triggered, this, [this]()
|
||||
{
|
||||
m_ui->unmountingPointListView->collapseAll();
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->addSeparator();
|
||||
QModelIndex index = m_ui->unmountingPointListView->treeView()->indexAt(pos);
|
||||
bool hasChildren = m_ui->unmountingPointListView->treeView()->model()->rowCount(index) > 0;
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Expand"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,13,0)
|
||||
m_ui->dvConflicts->treeView()->expand(index);
|
||||
#else
|
||||
m_ui->unmountingPointListView->treeView()->expandRecursively(index);
|
||||
#endif
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
{
|
||||
QAction *action = new QAction(tr("Collapse"), this);
|
||||
action->setEnabled(hasChildren);
|
||||
connect(action, &QAction::triggered, this, [this, index]()
|
||||
{
|
||||
m_ui->unmountingPointListView->treeView()->collapse(index);
|
||||
});
|
||||
contextMenu->addAction(action);
|
||||
}
|
||||
|
||||
contextMenu->popup(m_ui->unmountingPointListView->treeView()->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief OverviewMountingPointListDialog::apply
|
||||
* \return
|
||||
*/
|
||||
bool OverviewMountingPointListDialog::apply()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* tbc
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_resource_management_gui_plugin_interface.h>
|
||||
|
||||
#include <LtsDataView/check_state_proxy_model.h>
|
||||
|
||||
#include <InfrastructureManagement/Gui/ResourceManagement/MountingPointMapSelection/ism_dds_selector.h>
|
||||
#include <InfrastructureManagement/Gui/ResourceManagement/MountingPointMapSelection/ism_selector.h>
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/ism_ftc.h>
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
#include <qtreeview.h>
|
||||
|
||||
#include "ism_overview_mounting_point_list_model.h"
|
||||
|
||||
namespace Ui {
|
||||
class OverViewMountingPointListDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
class ViewMountingPointListModel;
|
||||
class ViewMountingPointListSortModel;
|
||||
class OverviewMountingPointListDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public: explicit OverviewMountingPointListDialog(const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~OverviewMountingPointListDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<Interface::Ftc> &ftc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface,
|
||||
int32_t scheduleId);
|
||||
|
||||
void onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) ;
|
||||
|
||||
private slots:
|
||||
void onPrint(QAction *action);
|
||||
void onScheduleIdChanged(int32_t scheduleId);
|
||||
void onMountedCustomContextMenu(QPoint pos);
|
||||
void onUnMountedCustomContextMenu(QPoint pos);
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
void addMountingPointTypeFilter(MountingPointType mpt);
|
||||
void addFloorFilter(int floor);
|
||||
bool apply() override final;
|
||||
bool isIncludedId(int32_t mountingPointId) const;
|
||||
bool itemsHaveNoChildren(const QTreeView *view);
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
QStringList getUsedFilterTypes();
|
||||
|
||||
private:
|
||||
QString m_menuGroup;
|
||||
Ui::OverViewMountingPointListDialog *m_ui;
|
||||
|
||||
int32_t m_scheduleId;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<Interface::Ftc> m_ftc;
|
||||
std::shared_ptr<ForeignDataInterface> m_dataIfc;
|
||||
ViewMountingPointListModel *m_sourceModel{nullptr};
|
||||
ViewMountingPointListSortModel *m_mountedPointSortProxyModel{nullptr};
|
||||
|
||||
ViewMountingPointListSortModel *m_unmountedPointSortProxyModel{nullptr};
|
||||
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
LOGGER_T m_logger;
|
||||
QMenu *m_actionMenu;
|
||||
QAction *m_printMountingAction;
|
||||
QAction *m_printUnmountingAction;
|
||||
|
||||
}; // class OverViewMountingPointListDialog
|
||||
} // namespace InfrastructureManagement
|
||||
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OverViewMountingPointListDialog</class>
|
||||
<widget class="QWidget" name="OverViewMountingPointListDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>868</width>
|
||||
<height>490</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="grpTypeFilters">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>221</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Type filter</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QListWidget" name="lwMountingPointType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="umntLbl">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>To Unmount</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="LtsDataView::LtsDataView" name="mountingPointListView" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="rootIsDecorated" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mntLbl">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>To Mount</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="LtsDataView::LtsDataView" name="unmountingPointListView" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="rootIsDecorated" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="showColumnCount" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonsVisible" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>566</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+542
@@ -0,0 +1,542 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* tbc
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by
|
||||
*/
|
||||
|
||||
#include "ism_overview_mounting_point_list_model.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_translation.h>
|
||||
|
||||
#include <Plugins/InfrastructureManagement/Shared/ism_mounting_point.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
// #define BENCHMARK
|
||||
|
||||
#ifdef BENCHMARK
|
||||
# include <QElapsedTimer>
|
||||
# include <QDebug>
|
||||
#endif
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
|
||||
static const int maxIntValue = std::numeric_limits<int>::max();
|
||||
ViewMountingPointListModel::ViewMountingPointListModel(QObject *parent)
|
||||
: NGLTreeModel(parent, new NGLTreeItem(QVariant()), { tr("Name"), tr("Type"), tr("Aim State") })
|
||||
, m_visRoot(new NGLTreeItem(tr("Mounting Points")))
|
||||
, m_dtc(nullptr)
|
||||
, m_logger(getLogger("ViewMountingPointListModel"))
|
||||
, m_dataChangedTimer(new QTimer(this))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_dataChangedTimer->setSingleShot(true);
|
||||
m_dataChangedTimer->setInterval(100);
|
||||
connect(m_dataChangedTimer, &QTimer::timeout, this, &ViewMountingPointListModel::emitDataChanged);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
QVariant ViewMountingPointListModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!(index.isValid() && (role == Qt::DisplayRole || role == Qt::UserRole || role == (Qt::UserRole + 1) || role == Qt::CheckStateRole)))
|
||||
return QVariant();
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
if (index.column() != NAME && !item->data().canConvert<OverviewSimpleMountingPointData>())
|
||||
return QVariant();
|
||||
|
||||
const OverviewSimpleMountingPointData itemData = item->data().value<OverviewSimpleMountingPointData>();
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
if (item->data().canConvert<OverviewSimpleMountingPointData>())
|
||||
return item->data().value<OverviewSimpleMountingPointData>().name;
|
||||
if (item->data().canConvert<OverviewSimpleStructureElementData>())
|
||||
return item->data().value<OverviewSimpleStructureElementData>().name;
|
||||
if (item->data().canConvert<OverviewSimpleBuildingGroupData>())
|
||||
return item->data().value<OverviewSimpleBuildingGroupData>().name;
|
||||
return tr("all");
|
||||
case STATE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
return toString(itemData.aimState);
|
||||
break;
|
||||
case TYPE:
|
||||
if (itemData.seType == StructureElementType::MountingPoint)
|
||||
{
|
||||
const MountingPointType mpType = (itemData.mpType == MountingPointType_def::OutdoorIPS) ? MountingPointType_def::IndoorIPS : itemData.mpType;
|
||||
return toString(mpType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
// else if (role == Qt::CheckStateRole)
|
||||
// {
|
||||
// if (index.column() != NAME)
|
||||
// return QVariant();
|
||||
|
||||
// bool isLeaf = item->data().canConvert<OverviewSimpleMountingPointData>();
|
||||
// if (isLeaf)
|
||||
// {
|
||||
// auto cs = item->data().value<OverviewSimpleMountingPointData>().aimState.underlying();
|
||||
// switch (cs)
|
||||
// {
|
||||
// case MountingPointState::Equipped:
|
||||
// return Qt::Checked;
|
||||
// case MountingPointState::Idle:
|
||||
// return Qt::PartiallyChecked;
|
||||
// case MountingPointState::Empty:
|
||||
// return Qt::Unchecked;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
else if (role == Qt::UserRole && item->data().canConvert<OverviewSimpleMountingPointData>())
|
||||
return item->data().value<OverviewSimpleMountingPointData>().id;
|
||||
else if (role == (Qt::UserRole + 1) && item->data().canConvert<OverviewSimpleMountingPointData>())
|
||||
return item->data().value<OverviewSimpleMountingPointData>().aimState.underlying();
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool ViewMountingPointListModel::initModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface,
|
||||
int32_t requestedScheduleId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, scheduleId=" << requestedScheduleId;
|
||||
|
||||
if (m_dtc == dtc)
|
||||
return true;
|
||||
|
||||
if (!(dtc->enableMainStructureElement() &&
|
||||
dtc->enableMountingPointAsset()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable Datatopics";
|
||||
return false;
|
||||
}
|
||||
m_dtc = dtc;
|
||||
|
||||
m_dataInterface = dataInterface;
|
||||
m_scheduleId = requestedScheduleId;
|
||||
|
||||
// !!! Maybe this is critical !!!
|
||||
// !!! Maybe this is critical !!!
|
||||
// !!! Maybe this is critical !!!
|
||||
// m_dataInterface::setScheduleId will update the MountingPoints (aimState) according schedule!!!
|
||||
// // m_dataInterface->setScheduleId(m_scheduleId);
|
||||
|
||||
// connect(m_dataInterface.get(), &ForeignDataInterface::scheduleIdChanged,
|
||||
// this, &MountingPointListDialogModel::onScheduleIdChanged);
|
||||
connect(m_dataInterface.get(), &ForeignDataInterface::mountingPointChanged,
|
||||
this, &ViewMountingPointListModel::onMountingPointChanged);
|
||||
|
||||
DEBUG_LOG(m_logger) << "initModel successful";
|
||||
|
||||
initData();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QModelIndex ViewMountingPointListModel::getIndexOfVisableRootItem() const
|
||||
{
|
||||
return indexFromItem(m_visRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief setBuildingGroup: create fake structure element of building group
|
||||
* @param groupId
|
||||
* @return
|
||||
*/
|
||||
inline StructureElement setBuildingGroup(int groupId)
|
||||
{
|
||||
StructureElement se;
|
||||
InfrastructureManagement::BuildingGroup_def::type buildingGroup = static_cast<InfrastructureManagement::BuildingGroup_def::type>(groupId);
|
||||
if(buildingGroup == 0)
|
||||
{
|
||||
buildingGroup = InfrastructureManagement::BuildingGroup_def::UnknownGroup;
|
||||
}
|
||||
|
||||
se.id() = maxIntValue - static_cast<int>(buildingGroup);
|
||||
se.name() = InfrastructureManagement::toString(buildingGroup).toStdString();
|
||||
se.displayName() = InfrastructureManagement::toString(buildingGroup).toStdString();
|
||||
se.structureElementTypeId() = InfrastructureManagement::StructureElementType::Section;
|
||||
return se;
|
||||
}
|
||||
/**
|
||||
* @brief getFakeBuildingGroupId: idi will only be use for treeview
|
||||
* @param seId
|
||||
* @return
|
||||
*/
|
||||
inline int getFakeBuildingGroupId(int seId)
|
||||
{
|
||||
InfrastructureManagement::BuildingGroup_def::type buildingGroup = static_cast<InfrastructureManagement::BuildingGroup_def::type>(seId);
|
||||
if(buildingGroup == 0)
|
||||
{
|
||||
buildingGroup = InfrastructureManagement::BuildingGroup_def::UnknownGroup;
|
||||
}
|
||||
return (maxIntValue - static_cast<int>(buildingGroup));
|
||||
}
|
||||
|
||||
void ViewMountingPointListModel::initData()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, m_scheduleId=" << m_scheduleId;
|
||||
|
||||
// #define BENCHMARK
|
||||
#ifdef BENCHMARK
|
||||
QElapsedTimer elapsedTimer1;
|
||||
elapsedTimer1.start();
|
||||
#endif // BENCHMARK
|
||||
|
||||
const int32_t loadedScheduleId = m_dataInterface->scheduleId();
|
||||
m_bIsRequestedScheduleId_EqualTo_LoadedScheduleId = (m_scheduleId == loadedScheduleId);
|
||||
|
||||
// scenario: load plan 1, open checkDialog (OverviewMountingPointListDialog)
|
||||
// (m_bIsRequestedScheduleId_EqualTo_LoadedScheduleId==true)
|
||||
// load another plan.... --> dialog should be closed
|
||||
|
||||
NGLTreeModel::resetModel();
|
||||
|
||||
m_rootItem->appendChild(m_visRoot);
|
||||
|
||||
const QMap<int, InfrastructureManagement::MainStructureElement> &mainStructEles = m_dtc->mainStructureElements();
|
||||
|
||||
// how do we get the aimState?
|
||||
// via m_dataInterface->mountingPoint() (loaded schedule)
|
||||
// or via schedule?
|
||||
QHash<int32_t, MountingPointPlan> mountingPointPlanCont;
|
||||
if (!m_bIsRequestedScheduleId_EqualTo_LoadedScheduleId)
|
||||
{
|
||||
// prepare MountingPointPlan of schedule to speed up access:
|
||||
const InfrastructureManagement::MainSchedule ¤tSchedule = m_dtc->mainSchedule(m_scheduleId);
|
||||
for (const MountingPointPlan &mpp : qAsConst(currentSchedule.elements()))
|
||||
mountingPointPlanCont.insert(mpp.structureElementId(), mpp);
|
||||
}
|
||||
|
||||
|
||||
// QSet<int> includedMountingPointIds;
|
||||
// includedMountingPointIds.reserve(currentSchedule.elements().size());
|
||||
// for (const InfrastructureManagement::MountingPointPlan ¤tPlan : currentSchedule.elements())
|
||||
// includedMountingPointIds.insert(currentPlan.structureElementId());
|
||||
// qCritical() << " includedMountingPointIds " << includedMountingPointIds.size();
|
||||
|
||||
// cfroebel 2018-11-07:
|
||||
// The algorithm of building the tree structure assumes that
|
||||
// the StructureElements are hierarchically ordered, i.e. that the
|
||||
// MountingPoint comes after its Room, Level and Building.
|
||||
// Is that guaranteed by the service?
|
||||
for (const MainStructureElement &mse : mainStructEles)
|
||||
{
|
||||
// only consider buildings
|
||||
if (mse.structureElementTypeId() != StructureElementType::Building)
|
||||
continue;
|
||||
|
||||
|
||||
// 1- if a buildingGroup modelIndex for current building dosen't exist
|
||||
// a new one will be first added and used as parentIndex for the blg_Index.
|
||||
QModelIndex groupIndex;
|
||||
const StructureElement bse= setBuildingGroup(mse.groupId());
|
||||
if (m_availableBuildingGroups.contains(bse.id()) == false)
|
||||
{
|
||||
OverviewSimpleBuildingGroupData buildingGroup;
|
||||
buildingGroup.name = QString::fromStdString(bse.displayName());
|
||||
buildingGroup.id = bse.id();
|
||||
NGLTreeItem *groupItem = new NGLTreeItem(QVariant::fromValue(buildingGroup));
|
||||
QModelIndex groupParentIndex;
|
||||
groupParentIndex = indexFromItem(m_visRoot);
|
||||
insertRow(rowCount(groupParentIndex), groupParentIndex, groupItem);
|
||||
groupIndex = index(groupItem->row(), 0, groupParentIndex);
|
||||
m_mountingPointIndexes.insert(bse.id(), groupIndex);
|
||||
m_availableBuildingGroups.insert(bse.id());
|
||||
}
|
||||
else
|
||||
{
|
||||
groupIndex = m_mountingPointIndexes.value(bse.id(), indexFromItem(m_visRoot));
|
||||
}
|
||||
|
||||
for (const StructureElement ¤tElement : mse.elements())
|
||||
{
|
||||
NGLTreeItem *item = nullptr;
|
||||
|
||||
if (currentElement.structureElementTypeId() == StructureElementType::MountingPoint)
|
||||
{
|
||||
MountingPoint mountingPoint = m_dataInterface->mountingPoint(currentElement.id());
|
||||
|
||||
if (!mountingPoint.isValid())
|
||||
continue;
|
||||
|
||||
if (mountingPoint.type() == MountingPointType::Unknown ||
|
||||
mountingPoint.type() == MountingPointType::BuildingControlUnit ||
|
||||
mountingPoint.type() == MountingPointType::VirtualIPS ||
|
||||
mountingPoint.type() == MountingPointType::MeteoDataUnit)
|
||||
continue;
|
||||
|
||||
OverviewSimpleMountingPointData mpData;
|
||||
mpData.seType = currentElement.structureElementTypeId();
|
||||
mpData.id = mountingPoint.id();
|
||||
mpData.name = mountingPoint.name();
|
||||
mpData.mpType = mountingPoint.type();
|
||||
mpData.hasAsset = mountingPoint.hasAssociatedAsset();
|
||||
|
||||
if (m_bIsRequestedScheduleId_EqualTo_LoadedScheduleId)
|
||||
{
|
||||
mpData.aimState = mountingPoint.aimState(); // mountingPoint.aimState was set according the loaded schedule!!!
|
||||
} else {
|
||||
// neu:
|
||||
const int32_t mpId_StructEleId = mountingPoint.id();
|
||||
if (mountingPointPlanCont.contains(mpId_StructEleId))
|
||||
{
|
||||
const MountingPointPlan &mpp = mountingPointPlanCont.value(mpId_StructEleId);
|
||||
mpData.aimState = mpp.mountingPointState();
|
||||
} else {
|
||||
mpData.aimState = MountingPointState_def::Idle;
|
||||
}
|
||||
}
|
||||
|
||||
item = new NGLTreeItem(QVariant::fromValue(mpData));
|
||||
}
|
||||
else
|
||||
{
|
||||
OverviewSimpleStructureElementData ssed;
|
||||
if (currentElement.structureElementTypeId() == StructureElementType::Floor)
|
||||
ssed.floor = QString::fromStdString(currentElement.name()).split(QLatin1Literal("_")).value(1, QLatin1String("-10")).toInt();
|
||||
else
|
||||
ssed.floor = -20;
|
||||
ssed.name = currentElement.displayName().empty() ? QString::fromStdString(currentElement.name()) : QString::fromStdString(currentElement.displayName());
|
||||
item = new NGLTreeItem(QVariant::fromValue(ssed));
|
||||
}
|
||||
|
||||
const auto &path = currentElement.path();
|
||||
|
||||
QModelIndex parentIndex;
|
||||
if (path.size() > 1)
|
||||
{
|
||||
parentIndex = m_mountingPointIndexes.value(path.at(path.size() - 2), indexFromItem(m_visRoot)); //default sollte nie erreicht werden
|
||||
if (!parentIndex.isValid())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Did not find parent for structure element with id " << currentElement.id() << " mseid: " << mse.id();
|
||||
for (const StructureElement &se : mse.elements())
|
||||
ERROR_LOG(m_logger) << " se: " << se.id() << ", " << se.displayName() << ", " << se.name();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (groupIndex.isValid())
|
||||
{
|
||||
parentIndex = groupIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
parentIndex = indexFromItem(m_visRoot);
|
||||
}
|
||||
}
|
||||
|
||||
insertRow(rowCount(parentIndex), parentIndex, item);
|
||||
|
||||
m_mountingPointIndexes.insert(currentElement.id(), index(item->row(), 0, parentIndex));
|
||||
}
|
||||
}
|
||||
|
||||
m_availableFloors << -10;
|
||||
|
||||
#ifdef BENCHMARK
|
||||
const InfrastructureManagement::MainSchedule ¤tSchedule = m_dtc->mainSchedule(m_scheduleId);
|
||||
qCritical() << " ViewMountingPointListModel::initData-BENCHMARK: m_scheduleId=" << currentSchedule.id();
|
||||
qCritical() << " ViewMountingPointListModel::initData-BENCHMARK: m_scheduleId=" << currentSchedule.name().c_str();
|
||||
|
||||
|
||||
qCritical() << " ViewMountingPointListModel::initData-BENCHMARK: m_scheduleId=" << m_scheduleId << " took " << elapsedTimer1.elapsed() << " [ms]";
|
||||
#endif // BENCHMARK
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool ViewMountingPointListModel::mountingPointHasAssetMounted(int32_t mountingPointId, const QMap<qint32, MountingPointAsset> &mountingPointAssetMap)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
for (const MountingPointAsset &mpa : mountingPointAssetMap)
|
||||
{
|
||||
if (mpa.structureElementId() == mountingPointId)
|
||||
return true;
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return false;
|
||||
}
|
||||
|
||||
Qt::ItemFlags ViewMountingPointListModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags fl = NGLTreeModel::flags(index);
|
||||
if (!index.isValid())
|
||||
return fl;
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
bool isLeaf = item->data().canConvert<OverviewSimpleMountingPointData>();
|
||||
if (isLeaf && index.column() == Columns::NAME)
|
||||
return fl | Qt::ItemIsUserCheckable | Qt::ItemIsUserTristate;
|
||||
return fl;
|
||||
}
|
||||
|
||||
void ViewMountingPointListModel::onMountingPointChanged(const MountingPoint &mountingPoint, DataModification modType)
|
||||
{
|
||||
if (modType != DataModification::eModified)
|
||||
return;
|
||||
|
||||
QModelIndex index = m_mountingPointIndexes.value(mountingPoint.id());
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
NGLTreeItem *item = privateData(index);
|
||||
|
||||
if (!(item && item->data().canConvert<OverviewSimpleMountingPointData>()))
|
||||
return;
|
||||
|
||||
OverviewSimpleMountingPointData mpData = item->data().value<OverviewSimpleMountingPointData>();
|
||||
|
||||
mpData.name = mountingPoint.name();
|
||||
|
||||
if (m_bIsRequestedScheduleId_EqualTo_LoadedScheduleId)
|
||||
mpData.aimState = mountingPoint.aimState();
|
||||
|
||||
item->setData(QVariant::fromValue(mpData));
|
||||
m_dataChangedTimer->start();
|
||||
}
|
||||
|
||||
void ViewMountingPointListModel::emitDataChanged()
|
||||
{
|
||||
QModelIndex vri = getIndexOfVisableRootItem();
|
||||
emit dataChanged(vri, index(rowCount(vri) -1, Columns::STATE, vri), {Qt::DisplayRole, Qt::CheckStateRole});
|
||||
}
|
||||
|
||||
|
||||
void ViewMountingPointListSortModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<ViewMountingPointListModel*>(sourceModel);
|
||||
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
void ViewMountingPointListSortModel::setTypeFilter(const QSet<MountingPointType> &visibleTypes)
|
||||
{
|
||||
if (m_visibleTypes == visibleTypes)
|
||||
return;
|
||||
m_visibleTypes = visibleTypes;
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void ViewMountingPointListSortModel::addToTypeFilter(MountingPointType mpt, bool bAdd)
|
||||
{
|
||||
auto visibleTypes = m_visibleTypes;
|
||||
if (bAdd)
|
||||
{
|
||||
// TODO: outdoor / indoor ips should be unified
|
||||
if(mpt == MountingPointType::IndoorIPS)
|
||||
{
|
||||
visibleTypes.insert(MountingPointType::OutdoorIPS);
|
||||
}
|
||||
visibleTypes.insert(mpt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mpt == MountingPointType::IndoorIPS)
|
||||
{
|
||||
visibleTypes.remove(MountingPointType::OutdoorIPS);
|
||||
}
|
||||
visibleTypes.remove(mpt);
|
||||
}
|
||||
setTypeFilter(visibleTypes);
|
||||
}
|
||||
|
||||
|
||||
bool ViewMountingPointListSortModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (!m_sourceModel)
|
||||
return true;
|
||||
|
||||
bool isRootItem = !source_parent.isValid();
|
||||
if (isRootItem)
|
||||
{
|
||||
Q_ASSERT(source_row == 0);
|
||||
return true; // root item shall always be visible
|
||||
}
|
||||
|
||||
const QModelIndex childIdx = m_sourceModel->index(source_row, 0, source_parent);
|
||||
const NGLTreeItem *itemChild = m_sourceModel->privateData(childIdx);
|
||||
Q_ASSERT(itemChild);
|
||||
|
||||
bool isLeaf = itemChild->data().canConvert<OverviewSimpleMountingPointData>();
|
||||
if (isLeaf)
|
||||
{
|
||||
const OverviewSimpleMountingPointData data = itemChild->data().value<OverviewSimpleMountingPointData>();
|
||||
Q_ASSERT(data.isMountingPoint());
|
||||
|
||||
bool visible = false;
|
||||
if (data.aimState == m_mnpState && m_mnpState == MountingPointState::Equipped)
|
||||
{
|
||||
if (!data.hasAsset)
|
||||
visible = true;
|
||||
}
|
||||
else if (data.aimState == m_mnpState && m_mnpState == MountingPointState::Empty)
|
||||
{
|
||||
if (data.hasAsset)
|
||||
visible = true;
|
||||
}
|
||||
return m_visibleTypes.contains(data.mpType) && visible;//(data.aimState == m_mnpState);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!itemChild->data().canConvert<OverviewSimpleStructureElementData>() &&
|
||||
!itemChild->data().canConvert<OverviewSimpleBuildingGroupData>())
|
||||
return true;
|
||||
}
|
||||
|
||||
// Qt5.11: setRecursiveFilteringEnabled(true);
|
||||
for (int i = 0; i < itemChild->childCount(); ++i)
|
||||
{
|
||||
if (filterAcceptsRow(i, childIdx))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ViewMountingPointListSortModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
if (!m_sourceModel || source_left.column() != source_right.column())
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
|
||||
const NGLTreeItem *itemLeft = m_sourceModel->privateData(source_left);
|
||||
const NGLTreeItem *itemRight = m_sourceModel->privateData(source_right);
|
||||
if (!itemLeft || !itemRight)
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
|
||||
if (itemLeft->data().canConvert<OverviewSimpleBuildingGroupData>())
|
||||
{
|
||||
const OverviewSimpleBuildingGroupData left = itemLeft->data().value<OverviewSimpleBuildingGroupData>();
|
||||
const OverviewSimpleBuildingGroupData right = itemRight->data().value<OverviewSimpleBuildingGroupData>();
|
||||
if (left.name != right.name)
|
||||
return left.name < right.name;
|
||||
}
|
||||
else if (itemLeft->data().canConvert<OverviewSimpleStructureElementData>())
|
||||
{
|
||||
const OverviewSimpleStructureElementData left = itemLeft->data().value<OverviewSimpleStructureElementData>();
|
||||
const OverviewSimpleStructureElementData right = itemRight->data().value<OverviewSimpleStructureElementData>();
|
||||
if (left.name != right.name)
|
||||
return left.name < right.name;
|
||||
}
|
||||
|
||||
const OverviewSimpleMountingPointData left = itemLeft->data().value<OverviewSimpleMountingPointData>();
|
||||
const OverviewSimpleMountingPointData right = itemRight->data().value<OverviewSimpleMountingPointData>();
|
||||
if (left.name != right.name)
|
||||
return left.name < right.name;
|
||||
return left.id < right.id;
|
||||
}
|
||||
|
||||
|
||||
}// namespace InfrastructureManagement
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* tbc
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <InfrastructureManagement/logger.h>
|
||||
|
||||
#include <QSet>
|
||||
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
#include <LtsDataView/check_state_proxy_model.h>
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
struct OverviewSimpleMountingPointData
|
||||
{
|
||||
QString name;
|
||||
int32_t id = 0; // StructureElementId
|
||||
StructureElementType seType;
|
||||
MountingPointType mpType;
|
||||
MountingPointState aimState;
|
||||
bool hasAsset = false;
|
||||
|
||||
bool isMountingPoint() const { return seType == StructureElementType::MountingPoint; }
|
||||
};
|
||||
|
||||
struct OverviewSimpleBuildingGroupData
|
||||
{
|
||||
QString name;
|
||||
int id;
|
||||
};
|
||||
struct OverviewSimpleStructureElementData
|
||||
{
|
||||
QString name;
|
||||
int floor;
|
||||
};
|
||||
|
||||
class ViewMountingPointListModel final : public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
NAME,
|
||||
TYPE,
|
||||
STATE
|
||||
};
|
||||
|
||||
explicit ViewMountingPointListModel(QObject *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Handles the representation of data.
|
||||
* In case of CheckStateRole only leafs will be handled.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
* @param[in] role role to which the data relates
|
||||
*
|
||||
*/
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
bool initModel(const std::shared_ptr<Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<ForeignDataInterface> &dataInterface,
|
||||
int32_t requestedScheduleId);
|
||||
|
||||
QModelIndex getIndexOfVisableRootItem() const;
|
||||
|
||||
/**
|
||||
* Sets only the leafs of the tree view to Qt::ItemIsUserCheckable.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
*
|
||||
*/
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override final;
|
||||
|
||||
/**
|
||||
* Sets the check state data according to their check box in the internal model.
|
||||
* CheckState data can be set for leafs only.
|
||||
* Nodes are handled in the upstream CheckStateProxyModel class.
|
||||
* @param[in] index item index to be handled
|
||||
* @param[in] value value to be set
|
||||
* @param[in] role role to which the data relates (here especially Qt::CheckStateRole)
|
||||
*
|
||||
*/
|
||||
//bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
|
||||
bool mountingPointHasAssetMounted(int32_t mountingPointId, const QMap<qint32, MountingPointAsset> &mountingPointAssetMap);
|
||||
static const int maxIntValue = std::numeric_limits<int>::max();
|
||||
|
||||
public Q_SLOTS:
|
||||
void onMountingPointChanged(const MountingPoint &mountingPoint, DataModification modType);
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
// void onScheduleIdChanged(int32_t scheduleId);
|
||||
void emitDataChanged();
|
||||
|
||||
private:
|
||||
void initData();
|
||||
void initMountedData();
|
||||
void initUnmountedData();
|
||||
friend class ViewMountingPointListSortModel;
|
||||
|
||||
QSet<int> m_availableBuildingGroups;
|
||||
NGLTreeItem *m_visRoot;
|
||||
NGLTreeItem *m_mountedParent;
|
||||
NGLTreeItem *m_unmountedParent;
|
||||
std::shared_ptr<Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignDataInterface> m_dataInterface;
|
||||
int32_t m_scheduleId{-1};
|
||||
bool m_bIsRequestedScheduleId_EqualTo_LoadedScheduleId{false};
|
||||
QHash<int, QModelIndex> m_mountingPointIndexes;
|
||||
QHash<int, QModelIndex> m_mountedPointIndexes;
|
||||
QHash<int, QModelIndex> m_unmountedPointIndexes;
|
||||
QHash<int32_t, bool> m_mountingPointHasAssetMounted;
|
||||
|
||||
QSet<int> m_availableFloors;
|
||||
LOGGER_T m_logger;
|
||||
QTimer *m_dataChangedTimer{nullptr};
|
||||
|
||||
}; // class OverViewDialogMountingPointListModel
|
||||
|
||||
//class ViewMountingPointListCheckStateModel final : public LtsDataView::CheckStateProxyModel
|
||||
//{
|
||||
// Q_OBJECT
|
||||
|
||||
//public:
|
||||
// bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
//};
|
||||
|
||||
class ViewMountingPointListSortModel final : public LtsWidgets::LtsColumnFilterProxyModel
|
||||
{
|
||||
using BaseClass = LtsWidgets::LtsColumnFilterProxyModel;
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
||||
|
||||
void setSourceModel(QAbstractItemModel *sourceModel ) override;
|
||||
|
||||
void setTypeFilter(const QSet<MountingPointType> &visibleTypes);
|
||||
void addToTypeFilter(MountingPointType mpt, bool bAdd);
|
||||
|
||||
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::invalidateFilter;
|
||||
|
||||
void setVisibleState(MountingPointState visibleState){m_mnpState = visibleState;}
|
||||
|
||||
private:
|
||||
ViewMountingPointListModel *m_sourceModel = nullptr;
|
||||
QSet<MountingPointType> m_visibleTypes;
|
||||
QSet<int> m_visibleFloors;
|
||||
MountingPointState m_mnpState;
|
||||
};
|
||||
|
||||
} // namespace InfrastructureManagement
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::OverviewSimpleMountingPointData)
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::OverviewSimpleStructureElementData)
|
||||
Q_DECLARE_METATYPE(InfrastructureManagement::OverviewSimpleBuildingGroupData)
|
||||
|
||||
|
||||
|
||||
|
||||
Loaded 100 of 16245 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user