Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

@@ -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
@@ -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
@@ -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 &currentStructureElement : 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
@@ -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
@@ -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>
@@ -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 &currentElement : 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
@@ -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)
@@ -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();
}
}
@@ -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