Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+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
|
||||
Reference in new issue
Block a user