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