/** * @RDE_HEADER@ * ParticipantManagement - ParticipantTargetConfigurationDialog (L400) * $Id$ * $HeadURL$ * $Author$ * Created by Norbert Thoden, SLSE, 2022-05-10 */ #include "participant_target_config_dialog.h" #include "ui_participant_target_config_dialog.h" #include #include #include // Translations //#include #include #include const double s_minPoints = 3; const double s_maxPoints = 4; namespace ParticipantManagement { Core::GeoPosition2D convert(const QPointF &coord) { return Core::GeoPosition2D(coord.x(), coord.y()); // lon/lat } QPointF convert(const Core::GeoPosition2D &geoPos) { return QPointF(geoPos.lon(), geoPos.lat()); } ParticipantTargetConfigurationDialog::ParticipantTargetConfigurationDialog(QWidget *parent) : LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel) , m_requestHelper(new LtsUtils::RequestHelper(this)) , m_ui(new Ui::ParticipantTargetConfigurationDialog) , m_logger(getLogger("ParticipantTargetConfigurationDialog")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; m_ui->setupUi(this); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } ParticipantTargetConfigurationDialog::~ParticipantTargetConfigurationDialog() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; delete m_ui; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::retranslate() { const dds::core::optional eqId = m_dtc->participant(m_participantId).equipmentNumber(); const QString id = (eqId.is_set() ? QString::number(eqId.get()) : QString()); translate(m_ui, id, false, tr("Target Configuration")); } bool ParticipantTargetConfigurationDialog::apply() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; ModifyTargetInformationRequest req; req.targetInfo(m_targetInformation); // participantId is set at init() DEBUG_LOG(m_logger) << LOGFUNCTION << " update m_targetInformation: " << m_targetInformation; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return m_requestHelper->startSingleRequest([req, this]() { return m_ftc->modifyTargetInformationRequest(req, this); }); } bool ParticipantTargetConfigurationDialog::init(int participantId, const std::shared_ptr &dtc, const std::shared_ptr &ftc, const std::shared_ptr &sitMapGuiIfc) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; m_participantId = participantId; if (m_participantId <= 0) { ERROR_LOG(m_logger) << LOGFUNCTION << " participant invalid, participantId = " << m_participantId; return false; } m_dtc = dtc; m_ftc = ftc; m_sitMapGuiIfc = sitMapGuiIfc; // maybe optional? if (!m_dtc || !m_ftc) return false; m_dtc->enableParticipant(true); m_dtc->enableDynamicParticipantData(true); m_dtc->waitForHistoricalDataDynamicParticipantData(2000); m_dtc->enableTargetInformation(true); m_dtc->waitForHistoricalDataTargetInformation(2000); fillStatusComboBox(); fillPrewarningEffectComboBox(); fillTakeDownEffectComboBox(); m_ui->sb_prewarningInterval->setMinimum(0); m_ui->sb_prewarningInterval->setMinimum(10); m_ui->sb_takeDownInterval->setMinimum(0); m_ui->sb_takeDownInterval->setMinimum(20); // ListView // m_ui->lv_areas->setAlternatingRowColors(true); // m_ui->lv_areas->setDragEnabled(false); // m_ui->lv_areas->setFlow(QListView::Flow::TopToBottom); // m_ui->lv_areas->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection); // m_ui->lv_areas->setSelectionBehavior(QAbstractItemView::SelectionBehavior::SelectRows); // LtsDataView // // DynamicParticipantData // ParticipantManagement::DynamicParticipantData pdd = m_dtc->dynamicParticipantData(m_participantId); // no ppd seems to be valid too: // if (pdd.participantId() != m_participantId) // { // ERROR_LOG(m_logger) << LOGFUNCTION << " participant not found, participantId = " << m_participantId; // return false; // } pdd.participantId(m_participantId); connect(m_dtc.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged, this, &ParticipantTargetConfigurationDialog::onDynamicParticipantDataChanged); onDynamicParticipantDataChanged(pdd, DataModification::eAdded); // update status comboBox // // TargetInformation // connect(m_dtc.get(), &ParticipantManagement::Interface::Dtc::targetInformationChanged, this, &ParticipantTargetConfigurationDialog::onTargetInformationChanged); const std::function cb = [this](const TargetInformation & data) -> bool { if (data.participantId() == m_participantId) { m_targetInformation = data; return true; // break loop } return false; }; m_dtc->targetInformations(cb); if (m_targetInformation.participantId() > 0) { onTargetInformationChanged(m_targetInformation, DataModification::eAdded); // update status comboBox } else { DEBUG_LOG(m_logger) << LOGFUNCTION << " targetInformation not found for participantId = " << m_participantId << " - use default."; m_targetInformation.participantId(m_participantId); // bootstrap } setupConnections(); m_ui->ltsDataView->setModel(&m_areaModel); m_ui->ltsDataView->treeView()->setItemDelegate(new EditNameDelegate(this)); m_ui->cb_showOnMap->setChecked(true); // at beginning all areas -> previewObjects TRACE_LOG(m_logger) << LOGFUNCTION << " END"; return true; } void ParticipantTargetConfigurationDialog::onDynamicParticipantDataChanged(const DynamicParticipantData &dynData, DataModification modType) { if (m_participantId != dynData.participantId()) return; switch (modType) { case DataModification::eRemoved: m_ui->cb_status->setCurrentIndex(-1); // invalid break; case DataModification::eAdded: case DataModification::eModified: { const ParticipantManagement::StateInformation &lastState = m_dtc->youngestStateInformation(dynData.stateHistory()); const ProjectDataManagement::VulnerabilityState &vulState = lastState.vulnerabilityState(); const ProjectDataManagement::VulnerabilityState_def::type vulStateType = vulState.underlying(); int idx = m_ui->cb_status->findData(vulStateType); DEBUG_LOG(m_logger) << LOGFUNCTION << " cb_status: vulState=" << vulState; DEBUG_LOG(m_logger) << LOGFUNCTION << " cb_status: setCurrentIndex idx=" << idx; m_ui->cb_status->setCurrentIndex(idx); m_ui->cb_status->setEnabled(true); } break; } // switch } void ParticipantTargetConfigurationDialog::onTargetInformationChanged(const TargetInformation &data, DataModification modType) { if (m_participantId != data.participantId()) return; switch (modType) { case DataModification::eRemoved: m_targetInformation = TargetInformation(); m_ui->cb_status->setCurrentIndex(-1); // invalid break; case DataModification::eAdded: case DataModification::eModified: { DEBUG_LOG(m_logger) << LOGFUNCTION << " got new targetInformation from dds: " << data; m_targetInformation = data; } break; } // switch onDataChanged(); } void ParticipantTargetConfigurationDialog::onStatusChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; m_ui->cb_status->setEnabled(false); // will be enabled by request const ProjectDataManagement::VulnerabilityState newParticipantState = static_cast(m_ui->cb_status->currentData().toInt()); if (newParticipantState == ProjectDataManagement::VulnerabilityState::CombatReady) { InitParticipantRequest req; req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId()); req.restockCharges(true); req.resetManipulation(true); req.resetVulnerabilityState(true); req.participantIds({m_participantId}); m_requestHelper->addRequest([req, this]() { return m_ftc->initParticipantRequest(req, this); }); } else { ModifyStateRequest req; req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId()); req.vulnerabilityState(newParticipantState); // req.vulnerabilityKind(); ToDo: check req.participantIds({m_participantId}); m_requestHelper->addRequest([req, this]() { return m_ftc->modifyStateRequest(req, this); }); } // const ProjectDataManagement::VulnerabilityState state = static_cast(m_ui->cbStatus->currentData().toInt()); // if (m_ui->cbStatus->currentIndex() == 1 || // m_ui->cbResetGearCharge->isChecked() || // m_ui->cbResetMedSupplies->isChecked() || // m_ui->cbResetManipulation->isChecked()) // (1) Ready for action or button checked -> init // { // InitParticipantRequest req; // req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId()); // req.restockCharges(m_ui->cbResetGearCharge->isChecked()); // req.resetManipulation(m_ui->cbResetManipulation->isChecked()); // req.resetVulnerabilityState(state == ProjectDataManagement::VulnerabilityState::CombatReady); // req.restockSanitationMaterial(m_ui->cbResetMedSupplies->isChecked()); // req.participantIds(participantIds); // m_requestHelper->addRequest([req, this]() // { // return m_ftc->initParticipantRequest(req, this); // }); // } // else //set new State // { // // Invalid enum value -1 // if (m_ui->cbStatus->currentData().toInt() != -1 || m_ui->cbVitality->currentData().toInt() != 0) // { // ModifyStateRequest req; // req.workstationId(LtsSessionData::LtsSessionData::getInstance()->getWorkstationId()); // req.vulnerabilityState(state == ProjectDataManagement::VulnerabilityState::NoChange ? ProjectDataManagement::VulnerabilityState::CombatReady : state); // req.participantIds(participantIds); // req.vitality(m_ui->cbVitality->currentData().toInt()); // if(req.vitality() > 0) //if we set the vitality directly send base kind for pvSan // req.vulnerabilityKind(2048); // m_requestHelper->addRequest([req, this]() // { // return m_ftc->modifyStateRequest(req, this); // }); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::fillStatusComboBox() { std::list cont; cont = { ProjectDataManagement::VulnerabilityState_def::NoChange, // ToDo ProjectDataManagement::VulnerabilityState_def::CombatReady, ProjectDataManagement::VulnerabilityState_def::CatastrophicKill }; m_ui->cb_status->clear(); for (auto item : qAsConst(cont)) { ProjectDataManagement::VulnerabilityState st = item; QString str = ProjectDataManagement::toString(st, ProjectDataManagement::VulnerabilityClass_def::VehicleDamages); m_ui->cb_status->addItem(str, static_cast(item)); } // m_ui->cb_status->setCurrentIndex(1); } void ParticipantTargetConfigurationDialog::fillPrewarningEffectComboBox() { std::list cont; cont = { ProjectDataManagement::VulnerabilityState_def::NoChange, // ToDo ProjectDataManagement::VulnerabilityState_def::MobilityKill, ProjectDataManagement::VulnerabilityState_def::NearMiss, ProjectDataManagement::VulnerabilityState_def::CatastrophicKill }; m_ui->cb_prewarningEffect->clear(); for (auto item : qAsConst(cont)) { ProjectDataManagement::VulnerabilityState st = item; QString str = ProjectDataManagement::toString(st, ProjectDataManagement::VulnerabilityClass_def::VehicleDamages); m_ui->cb_prewarningEffect->addItem(str, static_cast(item)); } m_ui->cb_prewarningEffect->setCurrentIndex(1); } void ParticipantTargetConfigurationDialog::fillTakeDownEffectComboBox() { std::list cont; cont = { ProjectDataManagement::VulnerabilityState_def::MobilityKill, // ToDo ProjectDataManagement::VulnerabilityState_def::CatastrophicKill }; m_ui->cb_takeDownEffect->clear(); for (auto item : qAsConst(cont)) { ProjectDataManagement::VulnerabilityState st = item; QString str = ProjectDataManagement::toString(st, ProjectDataManagement::VulnerabilityClass_def::VehicleDamages); m_ui->cb_takeDownEffect->addItem(str, static_cast(item)); } m_ui->cb_takeDownEffect->setCurrentIndex(1); } void ParticipantTargetConfigurationDialog::setupConnections() { connect(m_ui->cb_status, QOverload::of(&LtsWidgets::LtsComboBox::currentIndexChanged), this, &ParticipantTargetConfigurationDialog::onStatusChanged); connect(m_ui->cb_silhouette, QOverload::of(&LtsWidgets::LtsComboBox::currentIndexChanged), this, &ParticipantTargetConfigurationDialog::onGuiChanged); connect(m_ui->sb_prewarningInterval, QOverload::of(&QSpinBox::valueChanged), this, &ParticipantTargetConfigurationDialog::onGuiChanged); connect(m_ui->cb_prewarningEffect, QOverload::of(&LtsWidgets::LtsComboBox::currentIndexChanged), this, &ParticipantTargetConfigurationDialog::onGuiChanged); connect(m_ui->sb_takeDownInterval, QOverload::of(&QSpinBox::valueChanged), this, &ParticipantTargetConfigurationDialog::onGuiChanged); connect(m_ui->cb_takeDownEffect, QOverload::of(&LtsWidgets::LtsComboBox::currentIndexChanged), this, &ParticipantTargetConfigurationDialog::onGuiChanged); // LtsDataView: connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::signalSelectionChanged, this, &ParticipantTargetConfigurationDialog::onSelectionChanged); // add, edit, remove, showOnMap connect(m_ui->pb_add, &QPushButton::clicked, this, &ParticipantTargetConfigurationDialog::onAddBtnClicked); connect(m_ui->pb_edit, &QPushButton::clicked, this, &ParticipantTargetConfigurationDialog::onEditBtnClicked); connect(m_ui->pb_remove, &QPushButton::clicked, this, &ParticipantTargetConfigurationDialog::onRemoveBtnClicked); connect(m_ui->cb_showOnMap, &QCheckBox::stateChanged, this, &ParticipantTargetConfigurationDialog::onShowOnMapChanged); } bool updateValue(int& oldValueRef, int newValue) { bool hasChanged = oldValueRef != newValue; oldValueRef = newValue; return hasChanged; } bool updateValue(ProjectDataManagement::VulnerabilityState& oldValueRef, ProjectDataManagement::VulnerabilityState_def::type newValue) { bool hasChanged = oldValueRef != newValue; oldValueRef = newValue; return hasChanged; } void ParticipantTargetConfigurationDialog::onGuiChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; // try to recognize, if something really changed: bool hasChanged = false; // // State: // hasChanged |= updateValue(m_targetInformation.status(), static_cast(m_ui->cb_status->currentData().toInt()) ); // ToDo: Check Silhouette hasChanged |= updateValue(m_targetInformation.silhouette(), m_ui->cb_silhouette->currentData().toInt()); // Mode: hasChanged |= updateValue(m_targetInformation.prewarningEffect(), static_cast(m_ui->cb_prewarningEffect->currentData().toInt()) ); hasChanged |= updateValue(m_targetInformation.prewarningInterval(), m_ui->sb_prewarningInterval->value()); hasChanged |= updateValue(m_targetInformation.takedownEffect(), static_cast(m_ui->cb_takeDownEffect->currentData().toInt()) ); hasChanged |= updateValue(m_targetInformation.takedownInterval(), m_ui->sb_takeDownInterval->value()); DEBUG_LOG(m_logger) << LOGFUNCTION << " hasChanged=" << hasChanged; // Areas const std::vector &modelAreasStdVec = m_areaModel.getDataStdVector(); if (modelAreasStdVec != m_targetInformation.shootbackAreas()) { DEBUG_LOG(m_logger) << LOGFUNCTION << " hasChanged=" << hasChanged; hasChanged = true; m_targetInformation.shootbackAreas(modelAreasStdVec); } DEBUG_LOG(m_logger) << LOGFUNCTION << " slotChangesMade sChanged=" << hasChanged; this->slotChangesMade(); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::onDataChanged() { TRACE_LOG(m_logger) << LOGFUNCTION << " START, m_targetInformation=" << m_targetInformation; int idx; // // State: // idx = m_ui->cb_status->findData(QVariant(m_targetInformation.status().underlying())); // m_ui->cb_status->setCurrentIndex(idx); idx = m_ui->cb_silhouette->findData(QVariant(m_targetInformation.silhouette())); m_ui->cb_silhouette->setCurrentIndex(idx); // Mode: m_ui->sb_prewarningInterval->setValue(m_targetInformation.prewarningInterval()); idx = m_ui->cb_prewarningEffect->findData(QVariant(m_targetInformation.prewarningEffect().underlying())); m_ui->cb_prewarningEffect->setCurrentIndex(idx); m_ui->sb_takeDownInterval->setValue(m_targetInformation.takedownInterval()); idx = m_ui->cb_takeDownEffect->findData(QVariant(m_targetInformation.takedownEffect().underlying())); m_ui->cb_takeDownEffect->setCurrentIndex(idx); // areas: const std::vector& areas = m_targetInformation.shootbackAreas(); QVector qVec = QVector(areas.begin(), areas.end()); m_areaModel.setData(qVec); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::onAddBtnClicked() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!m_sitMapGuiIfc) return; m_rubberbandEditMode = false; m_sitMapGuiIfc->getPolygon(this, SLOT(onPolygonData(QPolygonF)), nullptr, s_minPoints, s_maxPoints); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QPolygonF areaToPolygon(const ShootbackArea &area) { QPolygonF coordinates; QPointF point; point = convert(area.coord1()); if (!point.isNull()) coordinates.append(point); point = convert(area.coord2()); if (!point.isNull()) coordinates.append(point); point = convert(area.coord3()); if (!point.isNull()) coordinates.append(point); point = convert(area.coord4()); if (!point.isNull()) coordinates.append(point); return coordinates; } void ParticipantTargetConfigurationDialog::onEditBtnClicked() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!m_sitMapGuiIfc) return; const QModelIndex curIdx = m_ui->ltsDataView->currentIndex(); if (!curIdx.isValid()) return; INFO_LOG(m_logger) << " edit..."; const ShootbackArea &area = m_areaModel.getRowData(curIdx.row()); QPolygonF coordinates = areaToPolygon(area); if (coordinates.size() < 3) return; m_rubberbandEditMode = true; m_sitMapGuiIfc->getPolygon(this, SLOT(onPolygonData(QPolygonF)), nullptr, s_minPoints, s_maxPoints, -1, -1, coordinates); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::onRemoveBtnClicked() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; const QModelIndex curIdx = m_ui->ltsDataView->currentIndex(); if (!curIdx.isValid()) return; INFO_LOG(m_logger) << " remove..."; m_areaModel.removeRow(curIdx.row()); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::onShowOnMapChanged(int) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!m_sitMapGuiIfc) return; const bool bShow = m_ui->cb_showOnMap->isChecked(); if (bShow) { QVector polyVec; const int rowCount = m_areaModel.rowCount(); for (int row = 0; row < rowCount; ++row) { const ShootbackArea ¤tArea = m_areaModel.getRowData(row); INFO_LOG(m_logger) << " row=" << row << " ; currentArea " << currentArea; const QPolygonF &poly = areaToPolygon(currentArea); polyVec.append(poly); } // for if (!polyVec.isEmpty()) m_sitMapGuiIfc->displayPreviewObjects(this, polyVec, true); } else { m_sitMapGuiIfc->removePreviewObject(); } TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } void ParticipantTargetConfigurationDialog::onSelectionChanged() { m_ui->cb_showOnMap->setChecked(false); QModelIndexList selectedRows = m_ui->ltsDataView->selectedRows(); const int cntSelectedRows = selectedRows.size(); m_ui->pb_add->setEnabled(true); m_ui->pb_edit->setEnabled(cntSelectedRows == 1); m_ui->pb_remove->setEnabled(cntSelectedRows == 1); // display current area on map: const QModelIndex curIdx = m_ui->ltsDataView->currentIndex(); if (!curIdx.isValid()) return; int row = curIdx.row(); // qCritical() << " row "<< row; ShootbackArea currentArea = m_areaModel.getRowData(row); INFO_LOG(m_logger) << " currentArea "<< currentArea; m_previewPolygon = areaToPolygon(currentArea); // qCritical() << " m_previewPolygon "<< m_previewPolygon; showPreviewObject(); } void ParticipantTargetConfigurationDialog::onPolygonData(const QPolygonF &poly) { INFO_LOG(m_logger) << LOGFUNCTION << " START"; if (poly.size() < 3) { ERROR_LOG(m_logger) << LOGFUNCTION << " polygon insufficiant, size=" << poly.size(); return; } ShootbackArea newArea; // QPointF coord; // coord = poly.at(0); newArea.coord1( convert(poly.at(0)) ); newArea.coord2( convert(poly.at(1)) ); if (poly.size() > 2) newArea.coord3( convert(poly.at(2)) ); if (poly.size() > 3) newArea.coord4( convert(poly.at(3)) ); if (m_rubberbandEditMode) { const QModelIndex curIdx = m_ui->ltsDataView->currentIndex(); if (!curIdx.isValid()) return; ShootbackArea temp = m_areaModel.getRowData(curIdx.row()); newArea.identifier(temp.identifier()); DEBUG_LOG(m_logger) << LOGFUNCTION << "updating newArea = " << newArea; m_areaModel.setRowData(curIdx.row(), newArea); } else { // ADD to overview: int size = m_areaModel.rowCount(); newArea.identifier(QString(QStringLiteral("Area_%1")).arg(size).toStdString()); DEBUG_LOG(m_logger) << LOGFUNCTION << " adding tempArea = " << newArea; m_areaModel.insertRow(newArea); QModelIndex mi = m_areaModel.index(size, 0); //qCritical() << LOGFUNCTION << " mi = " << mi; m_ui->ltsDataView->selectRow(mi); m_ui->ltsDataView->scrollTo(mi); m_ui->ltsDataView->setCurrentIndex(mi); } onSelectionChanged(); // which in turn updates previewObject onGuiChanged(); } void ParticipantTargetConfigurationDialog::showPreviewObject() { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; if (!m_sitMapGuiIfc || m_previewPolygon.isEmpty()) return; m_sitMapGuiIfc->displayPreviewObject(this, m_previewPolygon, true); TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } //----------------------------------------------- // Class EditNameDelegate //----------------------------------------------- EditNameDelegate::EditNameDelegate(QWidget *parent) : QItemDelegate(parent) , m_logger(getLogger("EditNameDelegate")) { TRACE_LOG(m_logger) << LOGFUNCTION << " START"; TRACE_LOG(m_logger) << LOGFUNCTION << " END"; } QWidget *EditNameDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { FATAL_LOG(m_logger) << LOGFUNCTION << " rox/column: " << index.row() << "/" << index.column() ; Q_UNUSED(option) Q_UNUSED(index) QLineEdit *le = new QLineEdit(parent); le->setMaxLength(10); return le; } void EditNameDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { FATAL_LOG(m_logger) << LOGFUNCTION << " XXXXXXXXXXXXX"; QLineEdit *le = qobject_cast(editor); if (!le) return; QVariant v = index.data(Qt::EditRole); le->setText(v.toString()); DEBUG_LOG(m_logger) << LOGFUNCTION << " rox/column: " << index.row() << "/" << index.column() << " Input: " << v.toString(); } void EditNameDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QLineEdit *le = qobject_cast(editor); if (!le) return; DEBUG_LOG(m_logger) << LOGFUNCTION << " rox/column: " << index.row() << "/" << index.column() << " setData... Input: " << le->text(); model->setData(index, le->text(), Qt::EditRole); } // end of setModelData() } // namespace ParticipantManagement