Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+430
@@ -0,0 +1,430 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningDialog allows to edit Frequency related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_edit_frequency_planning_dialog.h"
|
||||
#include "ui_avm_edit_frequency_planning_dialog.h"
|
||||
#include "avm_edit_frequency_planning_frequency_data_model.h"
|
||||
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <AudioVideoManagement/avm_ftc.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <ExerciseManagement/exm_dtc.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <LtsDataView/lts_data_view.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include "avm_load_frequency_planning_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QTreeView>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
bool isActive(ExerciseManagement::ExerciseState state)
|
||||
{
|
||||
return (state == ExerciseManagement::ExerciseState::Started ||
|
||||
state == ExerciseManagement::ExerciseState::Paused);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
EditFrequencyPlanningDialog::EditFrequencyPlanningDialog(LtsSession::LtsSession *session,
|
||||
const QString &menuGroup,
|
||||
const QString &freqPlanningDialogIdentifier,
|
||||
const FrequencyPlanning &planning,
|
||||
const bool copy,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<Interface::Ftc> &avmFtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
ExerciseManagement::Interface::Dtc *exmDtc,
|
||||
QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_session(session)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_freqPlanningDialogIdentifier(freqPlanningDialogIdentifier)
|
||||
, m_ui(new Ui::EditFrequencyPlanningDialog)
|
||||
, m_planning(planning)
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_avmFtc(avmFtc)
|
||||
, m_ppmDtc(ppmDtc)
|
||||
, m_ismDtc(ismDtc)
|
||||
, m_exmDtc(exmDtc)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_frequencyDataModel(new EditFrequencyPlanningFrequencyDataModel(planning, m_session->exerciseId(), avmDtc, ismDtc, ppmDtc, this))
|
||||
, m_frequencyPlanningId(copy ? 0 : planning.id())
|
||||
, m_exerciseId(session->exerciseId())
|
||||
, m_isEdit(EditFrequencyPlanningSetResourceDialog::DialogMode::Assign)
|
||||
, m_activeFrequencyPlanningStatus(0)
|
||||
, m_logger(getLogger("EditFrequencyPlanningDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->leName->setText(QString::fromStdString(m_planning.name()));
|
||||
m_ui->lbDate->setText(DTG::toStringMSec(m_planning.date()));
|
||||
|
||||
// FreqPlanName muss gesetzt sein (Pruefung erfolgt intern in apply()
|
||||
m_uiRequirements->addRequirement( { m_ui->label, [this]() { return !m_ui->leName->text().isEmpty(); } });
|
||||
|
||||
FPFDelegate *treeDelegate = new FPFDelegate(m_frequencyDataModel);
|
||||
m_ui->dvFrequencyData->treeView()->setItemDelegateForColumn(EditFrequencyPlanningFrequencyDataModel::Columns::PROPERTIES, treeDelegate);
|
||||
|
||||
m_ui->dvFrequencyData->setModel(m_frequencyDataModel);
|
||||
m_ui->dvFrequencyData->expandAll();
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::RADIO_CIRCUIT_ID);
|
||||
//m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::FREQ_SET_DATA_ID);
|
||||
#endif
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::AKW_BUNDLE);
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::AKW_RADIO_CIRCUIT);
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::FSB_BUNDLE);
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::COMSEC);
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::DEVICE);
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningFrequencyDataModel::Columns::PILOTTON);
|
||||
|
||||
// connects
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &EditFrequencyPlanningDialog::onAddClicked);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &EditFrequencyPlanningDialog::onRemoveClicked);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &EditFrequencyPlanningDialog::onPrint);
|
||||
|
||||
connect(m_ui->dvFrequencyData, &LtsDataView::LtsDataView::signalSelectionChanged,
|
||||
this, &EditFrequencyPlanningDialog::enableSelectedUnassignButton);
|
||||
|
||||
connect(m_ui->dvFrequencyData, &LtsDataView::LtsDataView::signalDoubleClicked,
|
||||
this, &EditFrequencyPlanningDialog::onAddClicked);
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, false); // Assign button
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, false); // Unassign button
|
||||
|
||||
if (m_frequencyPlanningId == 0) // new?
|
||||
slotChangesMade();
|
||||
|
||||
// Beschriftung der Button der Funktionalitaet anpassen......
|
||||
m_buttonBox->setText(LtsWidgets::DialogButton::Add, tr("Assign"));
|
||||
m_buttonBox->setText(LtsWidgets::DialogButton::Remove, tr("Unassign"));
|
||||
|
||||
// Save/Load from Library Button
|
||||
m_buttonBox->connectLibraryButton(this,
|
||||
&EditFrequencyPlanningDialog::onImportButtonClicked,
|
||||
&EditFrequencyPlanningDialog::onExportButtonClicked);
|
||||
|
||||
if (!session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Library, false);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Frequency_Planning"));
|
||||
}
|
||||
|
||||
EditFrequencyPlanningDialog::~EditFrequencyPlanningDialog()
|
||||
|
||||
{
|
||||
emit aboutToCloseMe(m_frequencyPlanningId);
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::retranslate()
|
||||
{
|
||||
translate(m_ui.get(), m_avmDtc->frequencyPlanning(m_frequencyPlanningId), tr("Frequency Planning"));
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onRemoveFrequencyPlanningReply(const Core::FunctionReplyObject &reply)
|
||||
{
|
||||
if (reply.error())
|
||||
ERROR_LOG(m_logger) << reply.str();
|
||||
m_requestHelper->requestReply(reply);
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onModifyFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
if (!replyObject.error())
|
||||
m_frequencyDataModel->setFrequencePlanningId(replyObject.id());
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
|
||||
bool EditFrequencyPlanningDialog::apply()
|
||||
{
|
||||
if (!m_frequencyDataModel->checkResourceAssignments())
|
||||
{
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Multiple assignments with the same resource are not possible. Please correct the selected entries."));
|
||||
return false;
|
||||
}
|
||||
ModifyFrequencyPlanningRequest request = m_frequencyDataModel->modifyFrequencyPlanningRequest();
|
||||
|
||||
request.date(m_session->partitionTime());
|
||||
m_ui->lbDate->setText(DTG::toStringMSec(request.date()));
|
||||
m_planning.date() = request.date();
|
||||
request.id(m_frequencyPlanningId);
|
||||
request.name(m_ui->leName->text().toStdString());
|
||||
|
||||
return m_requestHelper->startSingleRequest([this, request]()
|
||||
{
|
||||
return m_avmFtc->modifyFrequencyPlanningRequest(request, this);
|
||||
});
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onAddClicked() // Assign
|
||||
{
|
||||
// Daten der selektierten Zeile zusammensuchen
|
||||
|
||||
QModelIndex idx = m_ui->dvFrequencyData->currentIndex();
|
||||
int row = idx.row();
|
||||
if (row < 0)
|
||||
return;
|
||||
|
||||
CnrConfig cnrConfigRow = m_frequencyDataModel->itemData(idx).cnrConfig;
|
||||
int cnrConfigId = cnrConfigRow.id();
|
||||
if (cnrConfigId <= 0)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << "---RessourceDialog aufrufen...."
|
||||
<< " cnrConfigId: " << cnrConfigId
|
||||
<< " radioCircuit: " << cnrConfigRow.radioCircuit()
|
||||
<< " FrequencySetId: " << m_frequencyDataModel->getFrequencySetId();
|
||||
|
||||
FrequencyPlanningData fpd = m_frequencyDataModel->getfrequencyPlanningData(cnrConfigId);
|
||||
if (!fpd.cnrConfigId())
|
||||
{
|
||||
fpd.cnrConfigId(cnrConfigId);
|
||||
}
|
||||
// true: Bereits zugewiesener Sprechkreis wird editiert. Dabei ist jedoch keine Aenderung des FreqSets mehr moeglich!
|
||||
// false: Einem noch nicht zugeordneten Sprechkreis koennen die noch zur Verfuegung stehenden Ressourcen zugewiesen werden.
|
||||
EditFrequencyPlanningResourceDialog *frequencyPlanningResourceDialog
|
||||
= new EditFrequencyPlanningResourceDialog(m_frequencyDataModel->getFrequencySetId(),
|
||||
m_isEdit,
|
||||
this );
|
||||
|
||||
frequencyPlanningResourceDialog->init(m_session, fpd, m_frequencyDataModel->getAllocatedFrequencyPlanningSetIds());
|
||||
// Schliesst den Resource Dialog wenn der 'vorgeschaltete' Edit Dialog geschlossen wird
|
||||
connect(this, &QObject::destroyed,
|
||||
frequencyPlanningResourceDialog, &QObject::deleteLater);
|
||||
|
||||
addDialog(frequencyPlanningResourceDialog, m_menuGroup, QLatin1String("avmFrequencyPlanning") + QString::number(cnrConfigId), LtsWidgets::LayoutArea::eDialogTab);
|
||||
|
||||
connect(frequencyPlanningResourceDialog, &EditFrequencyPlanningResourceDialog::signalAssignRadioCircuit,
|
||||
this, &EditFrequencyPlanningDialog::onAssignRadioCircuit);
|
||||
m_ui->dvFrequencyData->expandAll();
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onRemoveClicked() // Unassign
|
||||
{
|
||||
QModelIndex idx = m_ui->dvFrequencyData->currentIndex();
|
||||
int row = idx.row();
|
||||
if (row < 0)
|
||||
return;
|
||||
|
||||
CnrConfig cnrConfigRow = m_frequencyDataModel->itemData(idx).cnrConfig;
|
||||
int cnrConfigId = cnrConfigRow.id();
|
||||
if (cnrConfigId <= 0)
|
||||
return;
|
||||
unassignRadioCircuit(cnrConfigId);
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::enableSelectedUnassignButton()
|
||||
{
|
||||
QModelIndex idx = m_ui->dvFrequencyData->currentIndex();
|
||||
int row = idx.row();
|
||||
if (row < 0)
|
||||
return;
|
||||
|
||||
auto itemData = m_frequencyDataModel->itemData(idx);
|
||||
CnrConfig cnrConfigRow = itemData.cnrConfig;
|
||||
int cnrConfigId = cnrConfigRow.id();
|
||||
if (cnrConfigId <= 0)
|
||||
return;
|
||||
|
||||
// Pruefen ob der selektierte Sprechkreis bereits zugewiesen ist...
|
||||
FrequencyPlanningData fpd = m_frequencyDataModel->getfrequencyPlanningData(cnrConfigId);
|
||||
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, true);
|
||||
|
||||
if( (!cnrConfigRow.exerciseId().is_set()
|
||||
&& m_planning.exerciseId().is_set())
|
||||
||
|
||||
itemData.readOnly
|
||||
)
|
||||
{
|
||||
m_buttonBox->setText(LtsWidgets::DialogButton::Add, tr("Show"));
|
||||
m_isEdit = EditFrequencyPlanningSetResourceDialog::DialogMode::Show;
|
||||
if (circuits.size() == 0)
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, false);
|
||||
}
|
||||
else if (circuits.size() > 0)
|
||||
{
|
||||
m_isEdit = EditFrequencyPlanningSetResourceDialog::DialogMode::Edit;
|
||||
m_buttonBox->setText(LtsWidgets::DialogButton::Add, tr("Edit"));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_isEdit = EditFrequencyPlanningSetResourceDialog::DialogMode::Assign;
|
||||
m_buttonBox->setText(LtsWidgets::DialogButton::Add, tr("Assign"));
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "---enableAssignUnassignButtons()...."
|
||||
<< " cnrConfigId: " << cnrConfigId
|
||||
<< " radioCircuitId: " << cnrConfigRow.radioCircuit();
|
||||
|
||||
// En-/dis-able Unassign Button
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, !itemData.readOnly && m_isEdit == EditFrequencyPlanningSetResourceDialog::DialogMode::Edit);
|
||||
|
||||
qDeleteAll(circuits);
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onAssignRadioCircuit(const FrequencyPlanningData &fpd)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "---onAssignRadioCircuit()...."
|
||||
<< "CnrConfigId: " << fpd.cnrConfigId();
|
||||
|
||||
m_frequencyDataModel->setFrequencyPlanningData(fpd);
|
||||
// pruefen ob doppelte Ressourcen verwendet werden
|
||||
if (!m_frequencyDataModel->checkResourceAssignments())
|
||||
{
|
||||
// auf den Tab der Frequenzplanung wechseln
|
||||
focusDialog(m_menuGroup, m_freqPlanningDialogIdentifier, LtsWidgets::LayoutArea::eDialogTab);
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Multiple assignments with the same resource are not possible. Please correct the selected entries."));
|
||||
return;
|
||||
}
|
||||
enableSelectedUnassignButton();
|
||||
slotChangesMade();
|
||||
m_ui->dvFrequencyData->repaint();
|
||||
m_ui->dvFrequencyData->expandAll();
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->dvFrequencyData->treeView() );
|
||||
}
|
||||
|
||||
int32_t EditFrequencyPlanningDialog::currentFrequencySetId() const
|
||||
{
|
||||
QModelIndex currentFrequencySetDataIndex = m_ui->dvFrequencyData->currentIndex();
|
||||
|
||||
if (!currentFrequencySetDataIndex.isValid())
|
||||
return -1;
|
||||
|
||||
return m_frequencyDataModel->data(currentFrequencySetDataIndex, Qt::UserRole).toInt();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return all active exercises except the current one.
|
||||
*/
|
||||
QVector<int> EditFrequencyPlanningDialog::otherActiveExercises() const
|
||||
{
|
||||
const auto allExercises_ = m_exmDtc->exercises();
|
||||
|
||||
Q_ASSERT(::isActive(allExercises_[m_exerciseId].state()));
|
||||
|
||||
|
||||
auto allExercises = allExercises_.values();
|
||||
auto newEnd = std::remove_if(allExercises.begin(), allExercises.end(), [] (const ExerciseManagement::Exercise &ex) { return ex.isDeleted(); }); // remove deleted exercises
|
||||
allExercises.erase(newEnd, allExercises.end());
|
||||
|
||||
QVector<int> toBeConsidered;
|
||||
for (const auto &exercise : qAsConst(allExercises))
|
||||
{
|
||||
if (exercise.id() == m_exerciseId)
|
||||
continue;
|
||||
|
||||
if (::isActive(exercise.state()))
|
||||
toBeConsidered.append(exercise.id());
|
||||
}
|
||||
return toBeConsidered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the active FrequencyPlannings of other active Exercises.
|
||||
*/
|
||||
QVector<int> EditFrequencyPlanningDialog::otherActivePlans() const
|
||||
{
|
||||
QVector<int> result;
|
||||
QVector<int> exercises = otherActiveExercises();
|
||||
|
||||
const auto activePlans = m_avmDtc->activeFrequencyPlannings();
|
||||
for (const auto &activePlan : activePlans)
|
||||
{
|
||||
if (exercises.contains(activePlan.exerciseId()))
|
||||
result.append(activePlan.frequencyPlanningId());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::unassignRadioCircuit(int32_t cnrConfigId)
|
||||
{
|
||||
m_frequencyDataModel->unassignRadioCircuit(cnrConfigId);
|
||||
enableSelectedUnassignButton();
|
||||
slotChangesMade();
|
||||
m_ui->dvFrequencyData->expandAll();
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onExportButtonClicked()
|
||||
{
|
||||
QByteArray byteArray = m_frequencyDataModel->uiToJson();
|
||||
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), byteArray);
|
||||
if (fileId > 0)
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningDialog::onImportButtonClicked()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "--- onImportButtonClicked() ";
|
||||
|
||||
QByteArray content;
|
||||
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::AVMEditFrequencyPlanning));
|
||||
if (fileId > 0)
|
||||
{
|
||||
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::AVMEditFrequencyPlanning)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadFrequencyPlanningDialog loadingDialog(content, m_frequencyDataModel->toFrequencyPlanning(), m_avmDtc, m_ismDtc) ;
|
||||
loadingDialog.exec();
|
||||
|
||||
if (loadingDialog.isApplied())
|
||||
{
|
||||
const QVector<int> unassignments = loadingDialog.unassignments();
|
||||
|
||||
for (int idToUnassign : unassignments)
|
||||
m_frequencyDataModel->unassignRadioCircuit(idToUnassign);
|
||||
|
||||
const QVector<FrequencyPlanningData> planningData = loadingDialog.newPlanningData();
|
||||
|
||||
for (const FrequencyPlanningData ¤tData : planningData)
|
||||
m_frequencyDataModel->setFrequencyPlanningData(currentData);
|
||||
|
||||
slotChangesMade();
|
||||
m_ui->dvFrequencyData->expandAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningDialog allows to edit Frequency related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <AudioVideoManagement/avm_ftc.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include "avm_edit_frequency_planning_resource_dialog.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EditFrequencyPlanningDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class EditFrequencyPlanningFrequencyDataModel;
|
||||
class EditFrequencyPlanningResourceDialog;
|
||||
|
||||
class EditFrequencyPlanningDialog : public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::RemoveFrequencyPlanningReplyHandler
|
||||
, protected Interface::Ftc::ModifyFrequencyPlanningReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit EditFrequencyPlanningDialog(LtsSession::LtsSession *session,
|
||||
const QString &menuGroup,
|
||||
const QString &freqPlanningDialogIdentifier,
|
||||
const FrequencyPlanning &planning,
|
||||
const bool copy,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<Interface::Ftc> &avmFtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
ExerciseManagement::Interface::Dtc *exmDtc,
|
||||
QWidget *parent);
|
||||
|
||||
~EditFrequencyPlanningDialog();
|
||||
void retranslate() override;
|
||||
void onExportButtonClicked();
|
||||
void onImportButtonClicked();
|
||||
|
||||
protected:
|
||||
void onRemoveFrequencyPlanningReply(const Core::FunctionReplyObject &reply) override final;
|
||||
void onModifyFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
bool apply() override;
|
||||
|
||||
private slots:
|
||||
void onAddClicked();
|
||||
void onRemoveClicked();
|
||||
void enableSelectedUnassignButton();
|
||||
void onPrint();
|
||||
void onAssignRadioCircuit(const FrequencyPlanningData &fpd);
|
||||
|
||||
signals:
|
||||
void aboutToCloseMe(int);
|
||||
|
||||
private:
|
||||
int32_t currentFrequencySetId() const; // -1 = invalid
|
||||
|
||||
QVector<int> otherActiveExercises() const;
|
||||
QVector<int> otherActivePlans() const;
|
||||
|
||||
void unassignRadioCircuit(int32_t cnrConfigId);
|
||||
bool isCriteriumEditDialog(const QByteArray &content);
|
||||
|
||||
LtsSession::LtsSession *m_session;
|
||||
QString m_menuGroup;
|
||||
QString m_freqPlanningDialogIdentifier;
|
||||
std::unique_ptr<Ui::EditFrequencyPlanningDialog> m_ui;
|
||||
FrequencyPlanning m_planning;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
std::shared_ptr<Interface::Ftc> m_avmFtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
ExerciseManagement::Interface::Dtc *m_exmDtc;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
|
||||
std::unique_ptr<LtsUtils::RequestHelper> m_requestHelper;
|
||||
EditFrequencyPlanningFrequencyDataModel *m_frequencyDataModel;
|
||||
int m_frequencyPlanningId;
|
||||
int m_exerciseId;
|
||||
EditFrequencyPlanningSetResourceDialog::DialogMode m_isEdit;
|
||||
int m_activeFrequencyPlanningStatus;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class EditFrequencyPlanningDialog
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditFrequencyPlanningDialog</class>
|
||||
<widget class="QWidget" name="EditFrequencyPlanningDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>655</width>
|
||||
<height>528</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Asset Stocks</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="1" colspan="3">
|
||||
<widget class="QLabel" name="lbDate">
|
||||
<property name="text">
|
||||
<string notr="true"><DATE></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leName">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Date:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>264</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="Line" name="line_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="LtsDataView::LtsDataView" name="dvFrequencyData">
|
||||
<property name="rootIsDecorated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+964
@@ -0,0 +1,964 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningDataModel class offers FrequencyPlanning related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_edit_frequency_planning_frequency_data_model.h"
|
||||
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <LtsUtilsCore/json_object.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
void EditFrequencyPlanningFrequencyDataModel::onFrequencyPlanningChanged(const FrequencyPlanning &planning, DataModification dm)
|
||||
{
|
||||
// Nicht meine Planning ID, aber auch nicht die globale Frequenzplanung:
|
||||
if (planning.id() != m_initPlan.id() && planning.exerciseId().is_set())
|
||||
return;
|
||||
|
||||
// Die Frequenzplanung wurde einfach mal so gelöscht...
|
||||
if (dm == DataModification::eRemoved)
|
||||
{
|
||||
beginResetModel();
|
||||
// Also hauenb wir die RadioCircuits wech...
|
||||
for (NGLTreeItem* item : m_rootItem->constChildren())
|
||||
{
|
||||
if (!item->data().canConvert<ItemData>())
|
||||
continue;
|
||||
|
||||
ItemData data = item->data().value<ItemData>();
|
||||
delete data.radioCircuit;
|
||||
data.radioCircuit = nullptr;
|
||||
item->setData(QVariant::fromValue(data));
|
||||
}
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
QHash<int, FrequencyPlanningData> fpdMap;
|
||||
for(const auto &elem : planning.data())
|
||||
fpdMap.insert(elem.cnrConfigId(), elem);
|
||||
for (NGLTreeItem* item : m_rootItem->constChildren())
|
||||
{
|
||||
if (!item->data().canConvert<ItemData>())
|
||||
continue;
|
||||
|
||||
ItemData itemData = item->data().value<ItemData>();
|
||||
if (itemData.cnrConfig.exerciseId().is_set() && itemData.cnrConfig.exerciseId().get() != m_exerciseId)
|
||||
continue;
|
||||
|
||||
if (!itemData.cnrConfig.exerciseId().is_set() && 0 != m_exerciseId)
|
||||
continue;
|
||||
|
||||
if (fpdMap.contains(itemData.cnrConfig.id()))
|
||||
{
|
||||
// We have a row with (possibly) altered data.
|
||||
const FrequencyPlanningData &fpd = fpdMap[itemData.cnrConfig.id()];
|
||||
|
||||
if (item->childCount())
|
||||
{
|
||||
beginRemoveRows(indexFromItem(item),0,item->childCount()-1);
|
||||
item->removeAllChildren();
|
||||
endRemoveRows();
|
||||
}
|
||||
|
||||
delete itemData.radioCircuit;
|
||||
itemData.radioCircuit = nullptr;
|
||||
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
if (circuits.size() > 1)
|
||||
{
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
itemData.radioCircuit = circuit;
|
||||
ConfigTreeItem *childItem = new ConfigTreeItem(QVariant::fromValue(itemData));
|
||||
insertRow(item->childCount(), indexFromItem(item), childItem);
|
||||
}
|
||||
}
|
||||
else if (circuits.size() == 1)
|
||||
{
|
||||
itemData.radioCircuit = circuits[0];
|
||||
item->setData(QVariant::fromValue(itemData));
|
||||
}
|
||||
m_frequencyPlanningData[fpd.cnrConfigId()] = fpd;
|
||||
fpdMap.remove(itemData.cnrConfig.id());
|
||||
}
|
||||
else
|
||||
{
|
||||
// No frequency Planning Data for this item any more...
|
||||
if (item->childCount())
|
||||
{
|
||||
beginRemoveRows(indexFromItem(item),0,item->childCount()-1);
|
||||
item->removeAllChildren();
|
||||
endRemoveRows();
|
||||
}
|
||||
delete itemData.radioCircuit;
|
||||
itemData.radioCircuit = nullptr;
|
||||
item->setData(QVariant::fromValue(itemData));
|
||||
m_frequencyPlanningData.remove(itemData.cnrConfig.id());
|
||||
}
|
||||
}
|
||||
// Some elements in fpdMap, that are new?
|
||||
for (const FrequencyPlanningData &item : qAsConst(fpdMap))
|
||||
{
|
||||
setFrequencyPlanningData(item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EditFrequencyPlanningFrequencyDataModel::EditFrequencyPlanningFrequencyDataModel(const FrequencyPlanning &initPlanning,
|
||||
int exerciseId,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
QObject *parent)
|
||||
: NGLTreeModel(parent, new ConfigTreeItem(QVariant()),
|
||||
{
|
||||
tr("Channel Number"),
|
||||
tr("RC id"),
|
||||
tr("Radio Circuit"),
|
||||
tr("Party"),
|
||||
tr("Unit"),
|
||||
tr("Radio Station"),
|
||||
tr("Frequency"),
|
||||
tr("Function"),
|
||||
tr("Device"),
|
||||
tr("AKW Bundle"),
|
||||
tr("FSB Bundle"),
|
||||
tr("AKW Radio Circuit"),
|
||||
tr("COMSEC"),
|
||||
tr("Pilotton"),
|
||||
tr("Operating Mode"),
|
||||
tr("Properties"),
|
||||
tr("Channel Spacing"),
|
||||
tr("Squelch"),
|
||||
tr("Global"),
|
||||
})
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_ismDtc(ismDtc)
|
||||
, m_ppmDtc(ppmDtc)
|
||||
, m_initPlan(initPlanning)
|
||||
, m_logger(getLogger("EditFrequencyPlanningDataModel"))
|
||||
{
|
||||
Q_ASSERT(avmDtc);
|
||||
Q_ASSERT(ppmDtc);
|
||||
DEBUG_LOG(m_logger) << "---EditFrequencyPlanningDataMod m_frequencyPlanningData[c.id()];el() ";
|
||||
|
||||
int frequencySetId = initPlanning.frequencySetId();
|
||||
std::vector<FrequencySetDataWithId> fsdVec = m_avmDtc->frequencySet(frequencySetId).data();
|
||||
for(FrequencySetDataWithId fsd : fsdVec)
|
||||
m_freqSetData.insert(fsd.id(), fsd);
|
||||
|
||||
m_units = m_ppmDtc->units();
|
||||
|
||||
QVector<CnrConfig> dataVec;
|
||||
const auto &cnrConfigs = m_avmDtc->cnrConfigs();
|
||||
for (const CnrConfig &cnrConfig : cnrConfigs)
|
||||
{
|
||||
// Lokale Sprechkreise anderer Exercises ausblenden
|
||||
if (cnrConfig.exerciseId().is_set() && cnrConfig.exerciseId().get() != m_exerciseId)
|
||||
continue;
|
||||
dataVec.append(cnrConfig);
|
||||
}
|
||||
setCnrConfigs(dataVec);
|
||||
m_avmDtc->activeFrequencyPlannings([this](const ActiveFrequencyPlanning &afp)
|
||||
{
|
||||
if (afp.exerciseId() <= 0)
|
||||
{
|
||||
onFrequencyPlanningChanged(m_avmDtc->frequencyPlanning(afp.frequencyPlanningId()), DataModification::eAdded);
|
||||
}
|
||||
});
|
||||
onFrequencyPlanningChanged(initPlanning, DataModification::eAdded);
|
||||
|
||||
connect(m_avmDtc.get(), &Interface::Dtc::cnrConfigChanged, this, &EditFrequencyPlanningFrequencyDataModel::onCnrConfigChanged);
|
||||
connect(m_avmDtc.get(), &Interface::Dtc::frequencyPlanningChanged, this, &EditFrequencyPlanningFrequencyDataModel::onFrequencyPlanningChanged);
|
||||
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningFrequencyDataModel::setCnrConfigs(const QVector<CnrConfig> &dataVec)
|
||||
{
|
||||
m_cnrConfigs.clear();
|
||||
for(const CnrConfig &c : dataVec)
|
||||
{
|
||||
m_cnrConfigs.insert(c.id(), c);
|
||||
ItemData id(c);
|
||||
if (m_frequencyPlanningData.contains(c.id()))
|
||||
{
|
||||
FrequencyPlanningData fpd = m_frequencyPlanningData[c.id()];
|
||||
id.readOnly = isReadOnly(fpd.properties());
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
if (circuits.size() > 1)
|
||||
{
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
id.radioCircuit = circuit;
|
||||
ConfigTreeItem *childItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
insertRow(configItem->childCount(), indexFromItem(configItem), childItem);
|
||||
}
|
||||
}
|
||||
else if (circuits.size() == 1)
|
||||
{
|
||||
id.radioCircuit = circuits[0];
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EditFrequencyPlanningFrequencyDataModel::ItemData EditFrequencyPlanningFrequencyDataModel::itemData(const QModelIndex &index)
|
||||
{
|
||||
NGLTreeItem *item = privateData(index);
|
||||
if (!item->data().canConvert<ItemData>())
|
||||
return {};
|
||||
|
||||
return item->data().value<ItemData>();
|
||||
}
|
||||
|
||||
QVariant EditFrequencyPlanningFrequencyDataModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole && role != Qt::ToolTipRole && role != Qt::UserRole && role != Qt::TextColorRole && role != Qt::BackgroundRole) || !index.isValid())
|
||||
return NGLTreeModel::data(index, role);
|
||||
ConfigTreeItem *item = static_cast<ConfigTreeItem *>(privateData(index));
|
||||
|
||||
if (!item->data().canConvert<ItemData>())
|
||||
return NGLTreeModel::data(index, role);
|
||||
|
||||
ItemData id = item->data().value<ItemData>();
|
||||
|
||||
const CnrConfig &setData = id.cnrConfig;
|
||||
RadioCircuit *rc = id.radioCircuit;
|
||||
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (index.column() != PROPERTIES)
|
||||
return {};
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (rcVhf && !isAkwMode(rcVhf->operatingMode))
|
||||
return tr("Pilot Tone: %1")
|
||||
.arg(rcVhf->pilotTone ? tr("On") : tr("Off"));
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
if (rcUhf)
|
||||
return tr("Clipper: %1, AGC: %2, Modulation Type: %3")
|
||||
.arg(rcUhf->clipper ? tr("On") : tr("Off"),
|
||||
rcUhf->agc ? tr("On") : tr("Off"),
|
||||
toString(rcUhf->modulationType));
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (rcHf)
|
||||
return tr("Channel Spacing: %1, Squelch: %2")
|
||||
.arg(toString(rcHf->channelSpacing),
|
||||
rcHf->squelch > 0 ? QString::number(rcHf->squelch) : tr("Off"));
|
||||
}
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
// FrequenySetDaten fuer den aktuellen Sprechkreis (cnrConfigId) ermitteln/anzeigen
|
||||
case RADIO_CIRCUIT_ID:
|
||||
return setData.id();
|
||||
case FUNCTION:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
return QString::fromStdString(m_freqSetData[rc->frequencySetDataId()].function());
|
||||
}
|
||||
case DEVICE:
|
||||
{
|
||||
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!rcVhf)
|
||||
return QStringLiteral("-");
|
||||
return toString(m_freqSetData[rc->frequencySetDataId()].frequencyBand().underlying());
|
||||
}
|
||||
case FREQUENCY:
|
||||
{
|
||||
QLocale locale(QLocale::German);
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() > 0)
|
||||
{
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (rcVhf && isAkwMode(rcVhf->operatingMode))
|
||||
return QStringLiteral("-");
|
||||
return tr("%1 MHz").arg(locale.toString(m_freqSetData[rc->frequencySetDataId()].frequency() / 1000., 'f', 3));
|
||||
}
|
||||
else
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
|
||||
if (rcUhf)
|
||||
return tr("%1 MHz").arg(locale.toString(rcUhf->frequency / 1000000., 'f', 3));
|
||||
if (rcHf)
|
||||
return tr("%1 MHz").arg(locale.toString(rcHf->frequency / 1000000., 'f', 3));
|
||||
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
case AKW_BUNDLE:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].akwBundle().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].akwBundle().get();
|
||||
}
|
||||
case FSB_BUNDLE:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].fsbBundle().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].fsbBundle().get();
|
||||
}
|
||||
case AKW_RADIO_CIRCUIT:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].akwRadioCircuit().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].akwRadioCircuit().get();
|
||||
}
|
||||
case COMSEC:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].comsec().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].comsec().get();
|
||||
}
|
||||
// cnrConfig Daten...
|
||||
case RADIO_CIRCUIT:
|
||||
{
|
||||
if (!rc)
|
||||
return QString::fromStdString(setData.radioCircuit());
|
||||
|
||||
return id.name();
|
||||
}
|
||||
case PARTY:
|
||||
{
|
||||
ParticipantManagement::Party party = m_ppmDtc->party(setData.partyId());
|
||||
|
||||
return ParticipantManagement::trPartyName(party.name());
|
||||
}
|
||||
case UNIT:
|
||||
{
|
||||
if (!setData.unitId().is_set())
|
||||
return {};
|
||||
const int unitId = setData.unitId().get();
|
||||
if (!m_units.contains(unitId))
|
||||
return QStringLiteral("-");
|
||||
const auto unit = m_units[unitId];
|
||||
|
||||
INFO_LOG(m_logger) << " config.unitId()=" << unitId
|
||||
<< " Str=" << unit.name();
|
||||
|
||||
QString unitStr;
|
||||
if (unit.designator().size() > 0)
|
||||
unitStr = QString::fromStdString(unit.designator()) + QLatin1Char('/');
|
||||
unitStr.append(QString::fromStdString(unit.tacticalIdentifier()));
|
||||
INFO_LOG(m_logger) << "unitStr = " << unitStr;
|
||||
|
||||
return unitStr;
|
||||
}
|
||||
case RADIO_STATION:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
|
||||
if (rc->radioStationId == 0)
|
||||
return tr("Automatic");
|
||||
else
|
||||
return QString::fromStdString(m_ismDtc->mainStructureElement(rc->radioStationId).name());
|
||||
}
|
||||
case PILOTTON:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!rcVhf)
|
||||
return QStringLiteral("-");
|
||||
|
||||
return rcVhf->pilotTone ? tr("On") : tr("Off");
|
||||
}
|
||||
case OPERATING_MODE:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!rcVhf)
|
||||
return QStringLiteral("-");
|
||||
|
||||
return toString(rcVhf->operatingMode);
|
||||
}
|
||||
case CHANNEL:
|
||||
{
|
||||
CnrChannel channel = m_avmDtc->cnrChannel(setData.cnrChannelId());
|
||||
return QString::fromStdString(channel.name());
|
||||
}
|
||||
case GLOBAL:
|
||||
{
|
||||
return setData.exerciseId().is_set() ? tr("No") : tr("Yes");
|
||||
}
|
||||
case PROPERTIES:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
else
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
QStringList sl;
|
||||
if (rcUhf)
|
||||
{
|
||||
sl << createIcon(ICON_CLIPPER, rcUhf->clipper );
|
||||
sl << createIcon(ICON_AGC, rcUhf->agc );
|
||||
sl << createIcon(ICON_MODULATION_TYPE, 0, rcUhf->modulationType);
|
||||
return sl.join(QStringLiteral(" "));
|
||||
}
|
||||
if (rcVhf && !isAkwMode(rcVhf->operatingMode))
|
||||
{
|
||||
sl << createIcon(ICON_PILOTTON, rcVhf->pilotTone > 0);
|
||||
return sl.join(QStringLiteral(" "));
|
||||
}
|
||||
if (rcHf)
|
||||
{
|
||||
return sl.join(QStringLiteral(" "));
|
||||
}
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
case CHANNEL_SPACING:
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (rcUhf)
|
||||
return toString(rcUhf->channelSpacing);
|
||||
if (rcHf)
|
||||
return toString(rcHf->channelSpacing);
|
||||
return {};
|
||||
}
|
||||
case SQUELCH:
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (rcUhf)
|
||||
return rcUhf->squelchDB > 0 ? tr("%1 dB").arg(rcUhf->squelchDB) : QVariant();
|
||||
if (rcHf)
|
||||
return rcHf->squelch > 0 ? QString::number(rcHf->squelch) : QVariant();
|
||||
return {};
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
|
||||
if (role == Qt::UserRole)
|
||||
return setData.id();
|
||||
|
||||
if (role == Qt::TextColorRole)
|
||||
{
|
||||
// Zeilen der doppelt vergebenen Resourcen markieren
|
||||
for (int id : m_multipleAssignedCnrIds)
|
||||
{
|
||||
if (id == setData.id())
|
||||
return QColor(Qt::red);
|
||||
}
|
||||
}
|
||||
if (role == Qt::BackgroundRole)
|
||||
{
|
||||
if (setData.exerciseId().is_set() && setData.exerciseId().get() == m_exerciseId)
|
||||
return NGLTreeModel::data(index, role);
|
||||
if (!setData.exerciseId().is_set() && m_exerciseId <= 0)
|
||||
return NGLTreeModel::data(index, role);
|
||||
return QColor(Qt::gray);
|
||||
}
|
||||
|
||||
return NGLTreeModel::data(index, role);
|
||||
}
|
||||
|
||||
QString EditFrequencyPlanningFrequencyDataModel::createIcon(PropertyData propertyDataType, bool on, ModulationType type) const
|
||||
{
|
||||
QString imgHeader = QStringLiteral("<img src=\"%1\" height=\"32\" title=\"%2\" image-rendering=\"optimizeQuality\">");
|
||||
|
||||
switch(propertyDataType)
|
||||
{
|
||||
case ICON_PILOTTON:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/pilotton-on.svg")
|
||||
: QStringLiteral(":/style/pilotton-off.svg"),
|
||||
on ?
|
||||
tr("Pilot Tone: On")
|
||||
: tr("Pilot Tone: Off"));
|
||||
case ICON_MODULATION_TYPE:
|
||||
return imgHeader
|
||||
.arg(type == ModulationType::AM ?
|
||||
QStringLiteral(":/style/AM.svg")
|
||||
: QStringLiteral(":/style/FM.svg"),
|
||||
on ?
|
||||
tr("Modulation Type: AM")
|
||||
: tr("Modulation Type: FM"));
|
||||
case ICON_SQUELCH:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/squelch-on.svg")
|
||||
: QStringLiteral(":/style/squelch-off.svg"),
|
||||
on ?
|
||||
tr("Squelch: On")
|
||||
: tr("Squelch: Off"));
|
||||
case ICON_CLIPPER:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/clipper-on.svg")
|
||||
: QStringLiteral(":/style/clipper-off.svg"),
|
||||
on ?
|
||||
tr("Clipper: On")
|
||||
: tr("Clipper: Off"));
|
||||
case ICON_AGC:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/agc-on.svg")
|
||||
: QStringLiteral(":/style/agc-off.svg"),
|
||||
on ?
|
||||
tr("Automatic Gain Control (AGC): On")
|
||||
: tr("Automatic Gain Control (AGC): Off"));
|
||||
case ICON_CHANNEL_SPACING:
|
||||
return imgHeader
|
||||
.arg(QStringLiteral(":/style/channel-spacing-on.svg"),
|
||||
tr("Channel Spacing"));
|
||||
case ICON_SPACER:
|
||||
return imgHeader
|
||||
.arg(QStringLiteral(":/style/line_style_solid_v.svg"),
|
||||
tr("Channel Spacing"));
|
||||
default:
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
|
||||
bool EditFrequencyPlanningFrequencyDataModel::unassignRadioCircuit(int32_t cnrConfigId)
|
||||
{
|
||||
if (cnrConfigId < 0)
|
||||
return false;
|
||||
|
||||
// ggf. markierte Zeile zuruecksetzen
|
||||
m_multipleAssignedCnrIds.erase(
|
||||
std::remove(m_multipleAssignedCnrIds.begin(), m_multipleAssignedCnrIds.end(), cnrConfigId),
|
||||
m_multipleAssignedCnrIds.end());
|
||||
|
||||
beginResetModel();
|
||||
m_frequencyPlanningData.remove(cnrConfigId);
|
||||
ConfigTreeItem* item = searchCnrConfig(m_rootItem, cnrConfigId);
|
||||
if(!item)
|
||||
return false;
|
||||
ItemData id = item->data().value<ItemData>();
|
||||
id.clearRadioCircuit();
|
||||
item->setData(QVariant::fromValue(id));
|
||||
item->removeAllChildren();
|
||||
endResetModel();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Setzt die id nach erfolgreichem ModifyRequest (Create)
|
||||
void EditFrequencyPlanningFrequencyDataModel::setFrequencePlanningId(int id)
|
||||
{
|
||||
if (m_initPlan.id() == id)
|
||||
return;
|
||||
if (m_initPlan.id() <= 0)
|
||||
{
|
||||
m_initPlan.id(id);
|
||||
return;
|
||||
}
|
||||
WARNING_LOG(m_logger) << "Trying to set a new frequency planning id but there is alreay an id set ("
|
||||
<< m_initPlan.id() << " - " << id << ")";
|
||||
}
|
||||
|
||||
ModifyFrequencyPlanningRequest EditFrequencyPlanningFrequencyDataModel::modifyFrequencyPlanningRequest() const
|
||||
{
|
||||
std::vector<FrequencyPlanningData> planningDataVec;
|
||||
planningDataVec.reserve(m_frequencyPlanningData.size());
|
||||
|
||||
for (const auto &keyValue : overKeyValue(m_frequencyPlanningData))
|
||||
{
|
||||
Q_ASSERT(keyValue.first > 0);
|
||||
CnrConfig config = m_avmDtc->cnrConfig(keyValue.second.cnrConfigId());
|
||||
if(( config.exerciseId().is_set() && config.exerciseId().get() == m_exerciseId) ||
|
||||
(!config.exerciseId().is_set() && m_exerciseId == 0))
|
||||
{
|
||||
FrequencyPlanningData fpd = keyValue.second;
|
||||
fpd.frequencyPlanningId() = m_initPlan.id();
|
||||
planningDataVec.push_back(fpd);
|
||||
}
|
||||
}
|
||||
|
||||
return { m_initPlan.id(),
|
||||
m_initPlan.exerciseId().is_set() ? m_initPlan.exerciseId().get() : 0,
|
||||
m_initPlan.name(),
|
||||
m_initPlan.date(),
|
||||
m_initPlan.frequencySetId(),
|
||||
planningDataVec};
|
||||
}
|
||||
|
||||
FrequencyPlanning EditFrequencyPlanningFrequencyDataModel::toFrequencyPlanning() const
|
||||
{
|
||||
std::vector<FrequencyPlanningData> planningDataVec;
|
||||
planningDataVec.reserve(m_frequencyPlanningData.size());
|
||||
|
||||
for (const auto &keyValue : overKeyValue(m_frequencyPlanningData))
|
||||
{
|
||||
Q_ASSERT(keyValue.first > 0);
|
||||
CnrConfig config = m_avmDtc->cnrConfig(keyValue.second.cnrConfigId());
|
||||
if(( config.exerciseId().is_set() && config.exerciseId().get() == m_exerciseId) ||
|
||||
(!config.exerciseId().is_set() && m_exerciseId == 0))
|
||||
{
|
||||
FrequencyPlanningData fpd = keyValue.second;
|
||||
fpd.frequencyPlanningId() = m_initPlan.id();
|
||||
planningDataVec.push_back(fpd);
|
||||
}
|
||||
}
|
||||
|
||||
FrequencyPlanning frequencyPlanning = m_initPlan;
|
||||
frequencyPlanning.data(planningDataVec);
|
||||
|
||||
return frequencyPlanning;
|
||||
}
|
||||
|
||||
int EditFrequencyPlanningFrequencyDataModel::findCnrConfigByName(const QString &name) const
|
||||
{
|
||||
int id = -1;
|
||||
std::function<bool(const CnrConfig &)> findByNameInExercise = [this, &name, &id] (const CnrConfig &cnrConfig)
|
||||
{
|
||||
if (cnrConfig.exerciseId().is_set() && cnrConfig.exerciseId() != m_initPlan.exerciseId())
|
||||
return false;
|
||||
if (QString::fromStdString(cnrConfig.radioCircuit()) != name)
|
||||
return false;
|
||||
|
||||
id = cnrConfig.id();
|
||||
return true;
|
||||
};
|
||||
|
||||
m_avmDtc->cnrConfigs(findByNameInExercise);
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* In order to save the FrequencyPlanning in the library we need to store the associations
|
||||
* of CnrConfig + Params (FrequencyPlanningData) with an entry of the FrequencySet.
|
||||
* FrequencySets and their entries are constant and thus not specific to an Exercise
|
||||
* so that we can simply store their Ids.
|
||||
* But the CnrConfigs are Exercise-specific. Thus we cannot store their Id in the library.
|
||||
* Instead we store the name of the CnrConfig. When loading the stored FrequencyPlanning in
|
||||
* another Exercise we try to find a CnrConfig with that name in that Exercise.
|
||||
*/
|
||||
QByteArray EditFrequencyPlanningFrequencyDataModel::uiToJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
obj[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::AVMEditFrequencyPlanning);
|
||||
obj[QStringLiteral("frequencySetId")] = m_initPlan.frequencySetId();
|
||||
|
||||
QJsonArray arr;
|
||||
for (const auto &keyValue : overKeyValue(m_frequencyPlanningData))
|
||||
{
|
||||
QJsonObject inner;
|
||||
const FrequencyPlanningData &info = keyValue.second;
|
||||
|
||||
inner[QStringLiteral("cnrChannelId")] = m_avmDtc->cnrConfig(info.cnrConfigId()).cnrChannelId();
|
||||
inner[QStringLiteral("properties")] = QString::fromStdString(info.properties());
|
||||
|
||||
arr.append(inner);
|
||||
}
|
||||
|
||||
obj[QStringLiteral("planningInfos")] = arr;
|
||||
|
||||
QJsonDocument doc(obj);
|
||||
|
||||
return doc.toJson(QJsonDocument::Compact);
|
||||
}
|
||||
|
||||
// Assign FrequencyPlanningData to RadioCircuit
|
||||
void EditFrequencyPlanningFrequencyDataModel::setFrequencyPlanningData(const FrequencyPlanningData &fpd)
|
||||
{
|
||||
ConfigTreeItem* item = searchCnrConfig(m_rootItem, fpd.cnrConfigId());
|
||||
if(!item)
|
||||
{
|
||||
if (!m_cnrConfigs.contains(fpd.cnrConfigId()))
|
||||
return;
|
||||
beginResetModel();
|
||||
ItemData data(m_cnrConfigs[fpd.cnrConfigId()]);
|
||||
data.readOnly = isReadOnly(fpd.properties());
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
if (circuits.size() > 1)
|
||||
{
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(data));
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
data.radioCircuit = circuit;
|
||||
ConfigTreeItem *childItem = new ConfigTreeItem(QVariant::fromValue(data));
|
||||
insertRow(configItem->childCount(), indexFromItem(configItem), childItem);
|
||||
}
|
||||
}
|
||||
else if (circuits.size() == 1)
|
||||
{
|
||||
data.radioCircuit = circuits[0];
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(data));
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
}
|
||||
m_frequencyPlanningData[fpd.cnrConfigId()] = fpd;
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
ItemData data = item->data().value<ItemData>();
|
||||
item->removeAllChildren();
|
||||
|
||||
if (circuits.size() == 1)
|
||||
{
|
||||
data.radioCircuit = circuits[0];
|
||||
item->setData(QVariant::fromValue(data));
|
||||
m_frequencyPlanningData.insert(fpd.cnrConfigId(), fpd);
|
||||
}
|
||||
if (circuits.size() <= 1)
|
||||
return;
|
||||
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
data.radioCircuit = circuit;
|
||||
ConfigTreeItem *childItem = new ConfigTreeItem(QVariant::fromValue(data));
|
||||
insertRow(item->childCount(), indexFromItem(item), childItem);
|
||||
}
|
||||
m_frequencyPlanningData.insert(fpd.cnrConfigId(), fpd);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
bool EditFrequencyPlanningFrequencyDataModel::checkResourceAssignments()
|
||||
{
|
||||
bool bOk = true;
|
||||
|
||||
m_multipleAssignedCnrIds.clear();
|
||||
for (auto it = m_frequencyPlanningData.constBegin(); it != m_frequencyPlanningData.constEnd();)
|
||||
{
|
||||
const FrequencyPlanningData &p = it.value();
|
||||
// Rest der Liste durchsuchen
|
||||
QSet<int> fsdIdsOuter = frequencySetDataIds(p.properties());
|
||||
|
||||
for (auto startSearchIt = ++it; startSearchIt != m_frequencyPlanningData.constEnd();++startSearchIt)
|
||||
{
|
||||
const FrequencyPlanningData &pI= startSearchIt.value();
|
||||
QSet<int> fsdIdsInner = frequencySetDataIds(pI.properties());
|
||||
for (int inner : qAsConst(fsdIdsInner))
|
||||
{
|
||||
for (int outer : qAsConst(fsdIdsOuter))
|
||||
{
|
||||
if (inner != outer)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "---ist ungleich cnrConfigId(A): " << p.cnrConfigId()
|
||||
<< " (B): " << pI.cnrConfigId();
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "---ist gleich cnrConfigId(A): " << p.cnrConfigId()
|
||||
<< " (B): " << pI.cnrConfigId();
|
||||
if (!m_multipleAssignedCnrIds.contains(p.cnrConfigId()) )
|
||||
m_multipleAssignedCnrIds.append(p.cnrConfigId());
|
||||
|
||||
if (!m_multipleAssignedCnrIds.contains(pI.cnrConfigId()) )
|
||||
m_multipleAssignedCnrIds.append(pI.cnrConfigId());
|
||||
bOk = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef LTS_DEBUG
|
||||
QString qs;
|
||||
for (int id : qAsConst(m_multipleAssignedCnrIds))
|
||||
{
|
||||
qs.append(QString::number(id));
|
||||
qs.append(QStringLiteral(", "));
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "---Number of multiple assigned frequency set data: " << m_multipleAssignedCnrIds.size()
|
||||
<< " cnrConfigIds: " << qs;
|
||||
#endif
|
||||
return bOk;
|
||||
}
|
||||
|
||||
bool EditFrequencyPlanningFrequencyDataModel::onCnrConfigChanged(const AudioVideoManagement::CnrConfig &data, DataModification modType)
|
||||
{
|
||||
ConfigTreeItem* item = searchCnrConfig(m_rootItem, data.id());
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
// Doesn't affect this model
|
||||
if (!item)
|
||||
return true;
|
||||
m_cnrConfigs.remove(data.id());
|
||||
m_frequencyPlanningData.remove(data.id());
|
||||
return removeRow(item->row());
|
||||
}
|
||||
|
||||
// New CNR Config or CNR Config moved from another exercise to this exercise:
|
||||
if (modType == DataModification::eAdded ||
|
||||
(!item && data.exerciseId().is_set() && m_exerciseId == data.exerciseId().get())
|
||||
)
|
||||
{
|
||||
Q_ASSERT(!item);
|
||||
|
||||
m_cnrConfigs.insert(data.id(), data);
|
||||
ConfigTreeItem *newItem = new ConfigTreeItem(QVariant::fromValue(ItemData(data)));
|
||||
m_rootItem->setModified(true);
|
||||
insertRow(0, indexFromItem(m_rootItem), newItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
// CNR Config moved to another exercise and thus is no longer part of this exercise
|
||||
if (item && data.exerciseId().is_set() && m_exerciseId != data.exerciseId().get())
|
||||
return removeRow(item->row());
|
||||
|
||||
// CNR config smply changed
|
||||
if(item)
|
||||
{
|
||||
ItemData id = item->data().value<ItemData>();
|
||||
id.cnrConfig = data;
|
||||
item->setData(QVariant::fromValue(id));
|
||||
|
||||
//maybe radioCircuit name in cnrConfig changed
|
||||
if(id.radioCircuit)
|
||||
id.radioCircuit->name = QString::fromStdString(data.radioCircuit());
|
||||
|
||||
item->setModified(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
EditFrequencyPlanningFrequencyDataModel::ConfigTreeItem* EditFrequencyPlanningFrequencyDataModel::searchCnrConfig(const NGLTreeItem *parentItem, int cnrConfigId) const
|
||||
{
|
||||
const int rowCount = parentItem->childCount();
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
{
|
||||
ConfigTreeItem *child = static_cast<ConfigTreeItem *>(parentItem->child(r));
|
||||
if (child->data().value<ItemData>().cnrConfig.id() == cnrConfigId)
|
||||
return child;
|
||||
child = searchCnrConfig(child, cnrConfigId);
|
||||
if (child)
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QSet<int> EditFrequencyPlanningFrequencyDataModel::getAllocatedFrequencyPlanningSetIds()
|
||||
{
|
||||
QSet<int> result;
|
||||
for (const auto &fpd : qAsConst(m_frequencyPlanningData))
|
||||
{
|
||||
result += AudioVideoManagement::frequencySetDataIds(fpd.properties());
|
||||
}
|
||||
|
||||
if(m_exerciseId == 0)
|
||||
{
|
||||
QMap<qint32,AudioVideoManagement::FrequencyPlanning> frequencyPlannings = m_avmDtc->frequencyPlannings();
|
||||
for(const auto &frequencyPlanning : qAsConst(frequencyPlannings))
|
||||
{
|
||||
if(!frequencyPlanning.exerciseId().is_set())
|
||||
continue;
|
||||
|
||||
for(const auto &frequencyPlanningData : frequencyPlanning.data())
|
||||
{
|
||||
result += AudioVideoManagement::frequencySetDataIds(frequencyPlanningData.properties());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//=============================================================================================================================
|
||||
// FPFDelegate
|
||||
//=============================================================================================================================
|
||||
FPFDelegate::FPFDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
void FPFDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == EditFrequencyPlanningFrequencyDataModel::Columns::PROPERTIES)
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
painter->save();
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(options.text);
|
||||
|
||||
options.text = QString();
|
||||
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
|
||||
|
||||
painter->translate(options.rect.left(), options.rect.top());
|
||||
QRect clip(0, 0, options.rect.width(), options.rect.height());
|
||||
doc.drawContents(painter, clip);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
else
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
|
||||
QSize FPFDelegate::sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(options.text);
|
||||
doc.setTextWidth(options.rect.width());
|
||||
return QSize(doc.idealWidth(), doc.size().height());
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningFrequencyDataModel class offers FrequencyPlanning related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include "avm_frequency_planning_helper.h"
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
|
||||
class CnrConfig;
|
||||
|
||||
class FPFDelegate
|
||||
: public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FPFDelegate(QObject *parent = nullptr);
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QSize sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||
|
||||
}; // FPFDelegate
|
||||
|
||||
class EditFrequencyPlanningFrequencyDataModel
|
||||
: public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
CHANNEL,
|
||||
RADIO_CIRCUIT_ID,
|
||||
RADIO_CIRCUIT,
|
||||
PARTY,
|
||||
UNIT,
|
||||
RADIO_STATION,
|
||||
FREQUENCY,
|
||||
FUNCTION,
|
||||
DEVICE,
|
||||
AKW_BUNDLE,
|
||||
FSB_BUNDLE,
|
||||
AKW_RADIO_CIRCUIT,
|
||||
COMSEC,
|
||||
PILOTTON,
|
||||
OPERATING_MODE,
|
||||
PROPERTIES,
|
||||
CHANNEL_SPACING,
|
||||
SQUELCH,
|
||||
GLOBAL,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
enum PropertyData
|
||||
{
|
||||
ICON_PILOTTON,
|
||||
ICON_MODULATION_TYPE,
|
||||
ICON_SQUELCH,
|
||||
ICON_CLIPPER,
|
||||
ICON_AGC,
|
||||
ICON_CHANNEL_SPACING,
|
||||
ICON_SPACER,
|
||||
ICON_COUNT,
|
||||
};
|
||||
|
||||
struct ItemData
|
||||
{
|
||||
CnrConfig cnrConfig;
|
||||
RadioCircuit* radioCircuit = nullptr;
|
||||
QString _name; // eigtl. Private...
|
||||
bool readOnly = false;
|
||||
|
||||
ItemData() = default;
|
||||
ItemData(const CnrConfig &_cnrConfig, const QString &itemName = {}, RadioCircuit* _rc = nullptr)
|
||||
: cnrConfig(_cnrConfig)
|
||||
, radioCircuit(_rc)
|
||||
, _name(itemName)
|
||||
{}
|
||||
|
||||
QString name() const { return radioCircuit ? radioCircuit->name : _name; }
|
||||
void setName(const QString &itemName) { _name = itemName; }
|
||||
void setName(const std::string &itemName) { setName(QString::fromStdString(itemName)); }
|
||||
void clearRadioCircuit() { delete radioCircuit; radioCircuit = nullptr; }
|
||||
};
|
||||
|
||||
class ConfigTreeItem final : public NGLTreeItem
|
||||
{
|
||||
public:
|
||||
using NGLTreeItem::NGLTreeItem;
|
||||
};
|
||||
|
||||
explicit EditFrequencyPlanningFrequencyDataModel(const FrequencyPlanning &initPlanning,
|
||||
int exerciseId,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
ItemData itemData(const QModelIndex &index);
|
||||
|
||||
void setFrequencePlanningId(int id);
|
||||
|
||||
bool unassignRadioCircuit(int32_t cnrConfigId);
|
||||
|
||||
int32_t getFrequencySetId() const { return m_initPlan.frequencySetId(); }
|
||||
QSet<int> getAllocatedFrequencyPlanningSetIds();
|
||||
|
||||
ModifyFrequencyPlanningRequest modifyFrequencyPlanningRequest() const;
|
||||
|
||||
FrequencyPlanning toFrequencyPlanning() const;
|
||||
|
||||
QByteArray uiToJson() const;
|
||||
|
||||
FrequencyPlanningData getfrequencyPlanningData(int cnrConfigId) { return m_frequencyPlanningData.value(cnrConfigId); }
|
||||
|
||||
bool checkResourceAssignments(); // return false and marked lines with multiple assignments. Otherwise returns true;
|
||||
void setFrequencyPlanningData(const FrequencyPlanningData &fpd);
|
||||
|
||||
private slots:
|
||||
void onFrequencyPlanningChanged(const FrequencyPlanning &planning, DataModification dm);
|
||||
|
||||
private:
|
||||
void removeCnrId(int32_t cnrId);
|
||||
int findCnrConfigByName(const QString &name) const;
|
||||
void setCnrConfigs(const QVector<CnrConfig> &dataVec);
|
||||
|
||||
bool onCnrConfigChanged(const AudioVideoManagement::CnrConfig &data, DataModification modType);
|
||||
EditFrequencyPlanningFrequencyDataModel::ConfigTreeItem* searchCnrConfig(const NGLTreeItem *parentItem, int cnrConfigId) const;
|
||||
QString createIcon(PropertyData PropertyDataType, bool on = true, ModulationType type = ModulationType::AM) const;
|
||||
|
||||
int m_exerciseId;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
FrequencyPlanning m_initPlan;
|
||||
QMap<int, FrequencySetDataWithId> m_freqSetData; // key = freqSetDataId
|
||||
QMap<int, ParticipantManagement::Participant> m_units;
|
||||
QMap<int, FrequencyPlanningData> m_frequencyPlanningData; // key = cnrConfigId (radioCircuit)
|
||||
QMap<int, CnrConfig> m_cnrConfigs; // key = cnrConfigId (radioCircuit)
|
||||
QVector<int> m_multipleAssignedCnrIds;
|
||||
int32_t m_frequencySetId;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class EditFrequencyPlanningFrequencyDataModelB
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
Q_DECLARE_METATYPE(AudioVideoManagement::EditFrequencyPlanningFrequencyDataModel::ItemData)
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningResourceDataModel class offers FrequencyPlanning related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_edit_frequency_planning_resource_data_model.h"
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
EditFrequencyPlanningResourceDataModel::EditFrequencyPlanningResourceDataModel(const QSet<int> &assignedFrequencySetDataIds,
|
||||
const FrequencyBand frequencyBand,
|
||||
QObject *parent)
|
||||
: LtsAbstractTableModel<FrequencySetDataWithId>(
|
||||
{
|
||||
tr("FSD id"),
|
||||
tr("Function"),
|
||||
tr("Device"),
|
||||
tr("Frequency"),
|
||||
tr("AKW Bundle"),
|
||||
tr("FSB Bundle"),
|
||||
tr("AKW Radio Circuit"),
|
||||
tr("COMSEC"),
|
||||
}, parent)
|
||||
, m_assignedFrequencySetDataIds(assignedFrequencySetDataIds)
|
||||
, m_frequencyBand(frequencyBand)
|
||||
, m_logger(getLogger("EditFrequencyPlanningResourceDataModel"))
|
||||
{
|
||||
}
|
||||
|
||||
QVariant EditFrequencyPlanningResourceDataModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole && role != Qt::UserRole) || !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const FrequencySetDataWithId &setData = m_vecData.at(index.row());
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
QLocale locale(QLocale::German);
|
||||
switch (index.column())
|
||||
{
|
||||
case FREQ_SET_DATA_ID:
|
||||
return setData.id();
|
||||
case FUNCTION:
|
||||
return QString::fromStdString(setData.function());
|
||||
case DEVICE:
|
||||
return toString(setData.frequencyBand());
|
||||
case FREQUENCY:
|
||||
return tr("%1 MHz").arg(locale.toString(setData.frequency() / 1000., 'f', 3));
|
||||
case AKW_BUNDLE:
|
||||
if (setData.akwBundle().is_set())
|
||||
return setData.akwBundle().get();
|
||||
return QStringLiteral("-");
|
||||
case FSB_BUNDLE:
|
||||
if (setData.fsbBundle().is_set())
|
||||
return setData.fsbBundle().get();
|
||||
return QStringLiteral("-");
|
||||
case AKW_RADIO_CIRCUIT:
|
||||
if (setData.akwRadioCircuit())
|
||||
return setData.akwRadioCircuit().get();
|
||||
return QStringLiteral("-");
|
||||
case COMSEC:
|
||||
if (setData.comsec().is_set())
|
||||
return setData.comsec().get();
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
else if (role == Qt::UserRole)
|
||||
return setData.id();
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool EditFrequencyPlanningResourceDataModel::isFiltered(const AudioVideoManagement::FrequencySetDataWithId &data, DataModification modType) const
|
||||
{
|
||||
// Um einen Eintrag nicht darzustellen muss isFiltered() true zurueckgeben.
|
||||
|
||||
// Frequenztyp muss stimmen (ausser bei REL...)
|
||||
if (m_frequencyBand != FrequencyBand_def::REL &&
|
||||
data.frequencyBand() != m_frequencyBand)
|
||||
return true;
|
||||
|
||||
// ...denn da muss es VHF sein.
|
||||
if(m_frequencyBand == FrequencyBand_def::REL &&
|
||||
data.frequencyBand() != FrequencyBand_def::VHF)
|
||||
return true;
|
||||
|
||||
Q_UNUSED(modType);
|
||||
// Bereits in diesem FreqPlan vergebene FreqSetDataIds hier ausblenden
|
||||
if (m_assignedFrequencySetDataIds.contains(data.id()))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "---m_assignments.size(): " << m_assignedFrequencySetDataIds.size()
|
||||
<< " frequencySetDataId: " << data.id() << " ist bereits enthalten";
|
||||
return true; // um den Eintrag nicht darzustellen muss true zurueckgegeben werden
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningResourceDataModel class offers FrequencyPlanning related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class EditFrequencyPlanningResourceDataModel
|
||||
: public LtsWidgets::LtsAbstractTableModel<FrequencySetDataWithId>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
FREQ_SET_DATA_ID,
|
||||
FUNCTION,
|
||||
DEVICE,
|
||||
FREQUENCY,
|
||||
AKW_BUNDLE,
|
||||
FSB_BUNDLE,
|
||||
AKW_RADIO_CIRCUIT,
|
||||
COMSEC,
|
||||
RADIO_CIRCUIT,
|
||||
PARTY,
|
||||
UNIT,
|
||||
RADIO_STATION,
|
||||
PILOTTON,
|
||||
OPERATING_MODE,
|
||||
COUNT
|
||||
};
|
||||
|
||||
explicit EditFrequencyPlanningResourceDataModel(const QSet<int> &assignedFrequencySetDataIds,
|
||||
const FrequencyBand frequencyBand,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
protected:
|
||||
bool isFiltered(const AudioVideoManagement::FrequencySetDataWithId &data, DataModification modType) const override;
|
||||
|
||||
private:
|
||||
QSet<int> m_assignedFrequencySetDataIds;
|
||||
FrequencyBand m_frequencyBand;
|
||||
LOGGER_T m_logger;
|
||||
}; // class EditFrequencyPlanningResourceDataModel
|
||||
} // namespace AudioVideoManagement
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningResourceDialog allows to edit Frequency related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_edit_frequency_planning_frequency_data_model.h"
|
||||
#include "avm_edit_frequency_planning_resource_dialog.h"
|
||||
#include "ui_avm_edit_frequency_planning_resource_dialog.h"
|
||||
#include "avm_frequency_planning_widget.h"
|
||||
#include <LtsWidgets/lts_combo_box.h>
|
||||
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <AudioVideoManagement/avm_ftc.h>
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <LtsDataView/lts_data_view.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include <Plugins/AudioVideoManagement/avm_data_plugin_interface.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <QTreeView>
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
EditFrequencyPlanningResourceDialog::EditFrequencyPlanningResourceDialog(int frequencySetId,
|
||||
const EditFrequencyPlanningSetResourceDialog::DialogMode dialogMode,
|
||||
QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkCancel)
|
||||
, m_ui(new Ui::EditFrequencyPlanningResourceDialog)
|
||||
, m_frequencySetId(frequencySetId)
|
||||
, m_dialogMode(dialogMode)
|
||||
, m_logger(getLogger("EditFrequencyPlanningResourceDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Frequency_Planning"));
|
||||
}
|
||||
|
||||
bool EditFrequencyPlanningResourceDialog::init(LtsSession::LtsSession *session, const FrequencyPlanningData &planningData, const QSet<int> &assignedFrequencySetDataIds)
|
||||
{
|
||||
bool succ = true;
|
||||
m_session = session;
|
||||
m_planningData = planningData;
|
||||
m_assignedFrequencySetDataIds = assignedFrequencySetDataIds;
|
||||
|
||||
succ &= m_session->getDtc<AudioVideoManagement::DataInterface>(m_avmDtc);
|
||||
succ &= m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc);
|
||||
succ &= m_session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc);
|
||||
|
||||
if(!succ)
|
||||
return succ;
|
||||
|
||||
m_units = m_ppmDtc->units();
|
||||
m_config = m_avmDtc->cnrConfig(m_planningData.cnrConfigId());
|
||||
|
||||
// m_config.radioCircuit() == REL
|
||||
// --> 2 Elemente mindestens!
|
||||
|
||||
// Device Type & RadioCircuit Namen ermitteln
|
||||
m_radioCircuitName = QString::fromStdString(m_config.radioCircuit());
|
||||
CnrChannel channel = m_avmDtc->cnrChannel(m_config.cnrChannelId());
|
||||
m_frequencyBand = channel.frequencyBand();
|
||||
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(planningData.properties());
|
||||
bool readOnly = isReadOnly(planningData.properties());
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
addMemberWidget(circuit, readOnly);
|
||||
}
|
||||
if (circuits.count() < 2 && m_frequencyBand == FrequencyBand::REL)
|
||||
addMemberWidget();
|
||||
if (circuits.count() < 1)
|
||||
addMemberWidget();
|
||||
|
||||
|
||||
setLbRadioCiruit(m_config);
|
||||
|
||||
connect(m_avmDtc.get(), &AudioVideoManagement::Interface::Dtc::cnrConfigChanged,
|
||||
this, &EditFrequencyPlanningResourceDialog::onCnrConfigChanged);
|
||||
connect(m_ui->tswFrequencyMember, &LtsWidgets::LtsTabSequenceWidget::addMember,
|
||||
this, &EditFrequencyPlanningResourceDialog::addMemberWidgetEmpty);
|
||||
|
||||
qDeleteAll(circuits);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
EditFrequencyPlanningResourceDialog::~EditFrequencyPlanningResourceDialog() = default;
|
||||
|
||||
void EditFrequencyPlanningResourceDialog::retranslate()
|
||||
{
|
||||
// 'Edit / Assign Radio Circuit: CircuitName' im Tab anzeigen
|
||||
if (m_dialogMode == EditFrequencyPlanningSetResourceDialog::DialogMode::Edit)
|
||||
{
|
||||
translate(m_ui.get(), m_avmDtc->cnrConfig(m_planningData.cnrConfigId()), m_radioCircuitName, tr("Radio Circuit"));
|
||||
}
|
||||
else // Assign Mode
|
||||
{
|
||||
QString qs = tr("Assign Radio Circuit: %1").arg(m_radioCircuitName);
|
||||
translate(m_ui.get(), qs);
|
||||
}
|
||||
}
|
||||
|
||||
bool EditFrequencyPlanningResourceDialog::apply()
|
||||
{
|
||||
QJsonArray array;
|
||||
for(int memberCount = 0; memberCount < m_ui->tswFrequencyMember->getMemberlistSize(); memberCount++)
|
||||
{
|
||||
FrequencyPlanningWidget *planningWidget = qobject_cast<FrequencyPlanningWidget*>(m_ui->tswFrequencyMember->getWidget(memberCount));
|
||||
if(!planningWidget)
|
||||
continue;
|
||||
|
||||
array.append(planningWidget->toJson());
|
||||
}
|
||||
QJsonDocument doc;
|
||||
QJsonObject obj;
|
||||
obj.insert(QStringLiteral("subCircuits"), array);
|
||||
doc.setObject(obj);
|
||||
|
||||
FrequencyPlanningData fpd;
|
||||
fpd.properties(doc.toJson().toStdString());
|
||||
fpd.cnrConfigId() = m_config.id();
|
||||
|
||||
emit signalAssignRadioCircuit(fpd);
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningResourceDialog::onEnableOkButton()
|
||||
{
|
||||
slotChangesMade();
|
||||
}
|
||||
|
||||
// Todo: Take correct name. If not relais: m_radioCircuitName! ALWAYS / Dunno by first subcircuit!
|
||||
void EditFrequencyPlanningResourceDialog::addMemberWidget(RadioCircuit *radioCircuit, bool readOnly)
|
||||
{
|
||||
FrequencyPlanningWidget *widget = new FrequencyPlanningWidget(m_avmDtc, m_assignedFrequencySetDataIds, this);
|
||||
widget->init(m_session,
|
||||
radioCircuit,
|
||||
m_config,
|
||||
m_frequencySetId,
|
||||
m_frequencyBand);
|
||||
connect(widget, &FrequencyPlanningWidget::onNameChanged,
|
||||
this, &EditFrequencyPlanningResourceDialog::onNameChanged);
|
||||
|
||||
widget->setDisabled(readOnly || m_dialogMode == EditFrequencyPlanningSetResourceDialog::DialogMode::Show);
|
||||
// To set Tab name initially.
|
||||
widget->setObjectName((radioCircuit && m_frequencyBand == FrequencyBand::REL) ? radioCircuit->name : m_radioCircuitName);
|
||||
widget->setName( (radioCircuit && m_frequencyBand == FrequencyBand::REL) ? radioCircuit->name : m_radioCircuitName);
|
||||
|
||||
const auto &reqs = widget->requirements();
|
||||
for (const auto &req : reqs)
|
||||
m_uiRequirements->addRequirement({req.first, req.second});
|
||||
|
||||
m_ui->tswFrequencyMember->addWidget(widget, true, false);
|
||||
|
||||
for (int i=0 ; i< m_ui->tswFrequencyMember->getMemberlistSize(); ++i)
|
||||
{
|
||||
FrequencyPlanningWidget *w = qobject_cast<FrequencyPlanningWidget*>(m_ui->tswFrequencyMember->getWidget(i));
|
||||
if (!w)
|
||||
continue;
|
||||
w->setNameDisabled(m_ui->tswFrequencyMember->getMemberlistSize() == 1);
|
||||
w->setRelaisRestrictions(m_ui->tswFrequencyMember->getMemberlistSize() > 1);
|
||||
}
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningResourceDialog::onCnrConfigChanged(const AudioVideoManagement::CnrConfig &config, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
if (m_config.id() == config.id())
|
||||
{
|
||||
setLbRadioCiruit(config);
|
||||
m_radioCircuitName = QString::fromStdString(config.radioCircuit());
|
||||
retranslate();
|
||||
}
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningResourceDialog::setLbRadioCiruit(const AudioVideoManagement::CnrConfig &config)
|
||||
{
|
||||
// RadioCircuit mit zugehoerigen Infos anzeigen
|
||||
ParticipantManagement::Party party = m_ppmDtc->party(config.partyId());
|
||||
QString partyName = ParticipantManagement::trPartyName(party.name());
|
||||
|
||||
QString unitString;
|
||||
if (config.unitId().is_set())
|
||||
{
|
||||
int unitId = config.unitId().get();
|
||||
auto unit = m_units.value(unitId);
|
||||
if (unit.id() == unitId)
|
||||
{
|
||||
if (unit.designator().size() > 0)
|
||||
unitString = QString::fromStdString(unit.designator()) + QLatin1Char('/');
|
||||
unitString.append(QString::fromStdString(unit.tacticalIdentifier()));
|
||||
}
|
||||
}
|
||||
m_ui->lblUnit->setText(unitString);
|
||||
CnrChannel channel = m_avmDtc->cnrChannel(m_config.cnrChannelId());
|
||||
m_ui->lblChannel->setText(QString::fromStdString(channel.name()));
|
||||
m_ui->lblFrequencyBand->setText(toString(m_frequencyBand));
|
||||
m_ui->lblRadioCircuit->setText(m_radioCircuitName);
|
||||
m_ui->lblParty->setText(partyName);
|
||||
}
|
||||
|
||||
void EditFrequencyPlanningResourceDialog::onNameChanged(const QString &name)
|
||||
{
|
||||
m_ui->tswFrequencyMember->changeTabName(name);
|
||||
if (m_ui->tswFrequencyMember->getMemberlistSize() > 1)
|
||||
return;
|
||||
m_radioCircuitName = name;
|
||||
m_ui->lblRadioCircuit->setText(m_radioCircuitName);
|
||||
}
|
||||
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningResourceDialog allows to edit Frequency related data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
|
||||
#include "avm_frequency_planning_helper.h"
|
||||
#include "avm_edit_frequency_planning_set_resource_dialog.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EditFrequencyPlanningResourceDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsComboBox;
|
||||
}
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class EditFrequencyPlanningResourceDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
explicit EditFrequencyPlanningResourceDialog(int frequencySetId,
|
||||
const EditFrequencyPlanningSetResourceDialog::DialogMode dialogMode,
|
||||
QWidget *parent);
|
||||
|
||||
~EditFrequencyPlanningResourceDialog();
|
||||
void retranslate() override;
|
||||
bool init(LtsSession::LtsSession *session, const FrequencyPlanningData &planningData, const QSet<int> &assignedFrequencySetDataIds);
|
||||
|
||||
protected:
|
||||
bool apply() override;
|
||||
|
||||
signals:
|
||||
void signalAssignRadioCircuit(const FrequencyPlanningData &doc);
|
||||
|
||||
private slots:
|
||||
void onEnableOkButton();
|
||||
void onCnrConfigChanged(const AudioVideoManagement::CnrConfig &config, DataModification modType);
|
||||
void setLbRadioCiruit(const CnrConfig &config);
|
||||
void addMemberWidget(RadioCircuit *radioCircuit = nullptr, bool readOnly = false);
|
||||
void addMemberWidgetEmpty() { addMemberWidget(); }
|
||||
void onNameChanged(const QString &name);
|
||||
|
||||
private:
|
||||
QMap<int32_t, ParticipantManagement::Participant> m_units;
|
||||
|
||||
std::unique_ptr<Ui::EditFrequencyPlanningResourceDialog> m_ui;
|
||||
int m_frequencySetId;
|
||||
FrequencyPlanningData m_planningData;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
int m_exerciseId;
|
||||
CnrConfig m_config;
|
||||
EditFrequencyPlanningSetResourceDialog::DialogMode m_dialogMode;
|
||||
FrequencyBand m_frequencyBand;
|
||||
QString m_radioCircuitName;
|
||||
QSet<int> m_assignedFrequencySetDataIds;
|
||||
LtsSession::LtsSession *m_session;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class EditFrequencyPlanningResourceDialog
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditFrequencyPlanningResourceDialog</class>
|
||||
<widget class="QWidget" name="EditFrequencyPlanningResourceDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>542</width>
|
||||
<height>284</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Select Function</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="lblFrequencyBand">
|
||||
<property name="text">
|
||||
<string notr="true"><RadioCircuit></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3" rowspan="6">
|
||||
<widget class="LtsWidgets::LtsTabSequenceWidget" name="tswFrequencyMember"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lbxUnit">
|
||||
<property name="text">
|
||||
<string>Unit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxRadioCircuit">
|
||||
<property name="text">
|
||||
<string>Radio Circuit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblRadioCircuit">
|
||||
<property name="text">
|
||||
<string notr="true"><SET></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxParty">
|
||||
<property name="text">
|
||||
<string>Party:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="lblParty">
|
||||
<property name="text">
|
||||
<string notr="true"><PARTY></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="lblUnit">
|
||||
<property name="text">
|
||||
<string notr="true"><UNIT></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxFrequencyBand">
|
||||
<property name="text">
|
||||
<string>Frequency Band:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>171</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxChannel">
|
||||
<property name="text">
|
||||
<string>Channel:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="lblChannel">
|
||||
<property name="text">
|
||||
<string notr="true"><CHANNEL></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsTabSequenceWidget</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header>LtsWidgets/lts_tab_sequence_widget.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningSetResourceDialog allows to select a Frequency set
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Verena Eberlein, SPMO, 2023-09-21
|
||||
*/
|
||||
|
||||
#include "avm_edit_frequency_planning_frequency_data_model.h"
|
||||
#include "avm_edit_frequency_planning_set_resource_dialog.h"
|
||||
#include "ui_avm_edit_frequency_planning_set_resource_dialog.h"
|
||||
#include "avm_edit_frequency_planning_resource_data_model.h"
|
||||
|
||||
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
#include <LtsDataView/lts_data_view.h>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
EditFrequencyPlanningSetResourceDialog::EditFrequencyPlanningSetResourceDialog(
|
||||
const QSet<int> &assignedFrequencySetDataIds,
|
||||
const RcOperatingMode operatingMode,
|
||||
int32_t frequencySetId,
|
||||
const int &cnrConfigId,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
QWidget *parent)
|
||||
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
|
||||
, m_ui(new Ui::EditFrequencyPlanningSetResourceDialog)
|
||||
, m_frequencySetId(frequencySetId)
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_frequencyResourceDataModel(nullptr)
|
||||
, m_config(m_avmDtc->cnrConfig(cnrConfigId))
|
||||
, m_logger(getLogger("EditFrequencyPlanningSetResourceDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
// Device Type & RadioCircuit Namen ermitteln
|
||||
CnrChannel channel = m_avmDtc->cnrChannel(m_config.cnrChannelId());
|
||||
|
||||
// Normalerweise werden die in m_assignments uebergebenen Eintraege im Model ausgeblendet..
|
||||
// Im EditMode wird diese Funktionalitaet genau invertiert behandelt; Alles bis auf den Eintrag in m_assignments wird ausgeblendet
|
||||
m_frequencyResourceDataModel = new EditFrequencyPlanningResourceDataModel(assignedFrequencySetDataIds, channel.frequencyBand(), this);
|
||||
|
||||
std::vector<FrequencySetDataWithId> dataVec = m_avmDtc->frequencySet(m_frequencySetId).data();
|
||||
|
||||
for (const auto &it : dataVec)
|
||||
{
|
||||
if((operatingMode == RcOperatingMode_def::AkwEncEccm ||
|
||||
operatingMode == RcOperatingMode_def::AkwEncNone)
|
||||
&& it.akwRadioCircuit() == 0) //show only akw bundel
|
||||
continue;
|
||||
if((operatingMode != RcOperatingMode_def::AkwEncEccm &&
|
||||
operatingMode != RcOperatingMode_def::AkwEncNone)
|
||||
&& it.akwRadioCircuit() != 0)
|
||||
continue;
|
||||
m_frequencyResourceDataModel->insertRow(it);
|
||||
}
|
||||
m_ui->dvFrequencyData->setModel(m_frequencyResourceDataModel);
|
||||
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->dvFrequencyData->hideColumn(EditFrequencyPlanningResourceDataModel::Columns::FREQ_SET_DATA_ID);
|
||||
#endif
|
||||
|
||||
// connects
|
||||
connect(m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked,
|
||||
this, &EditFrequencyPlanningSetResourceDialog::accept);
|
||||
connect(m_ui->ltsDialogButtonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked,
|
||||
this, &EditFrequencyPlanningSetResourceDialog::reject);
|
||||
connect(m_ui->dvFrequencyData, &LtsDataView::LtsDataView::doubleClicked,
|
||||
this, &EditFrequencyPlanningSetResourceDialog::accept);
|
||||
|
||||
}
|
||||
|
||||
EditFrequencyPlanningSetResourceDialog::~EditFrequencyPlanningSetResourceDialog() = default;
|
||||
|
||||
void EditFrequencyPlanningSetResourceDialog::accept()
|
||||
{
|
||||
LtsWidgets::LtsFramelessDialog::accept();
|
||||
|
||||
const QModelIndex idx = m_ui->dvFrequencyData->currentIndex();
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
|
||||
emit onSelectedFrequencySet(m_frequencyResourceDataModel->getRowData(idx.row()).id());
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The EditFrequencyPlanningSetResourceDialog allows to select a Frequency set
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Verena Eberlein, SPMO, 2023-09-21
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_enums.hpp>
|
||||
#include <AudioVideoManagement/avm.hpp>
|
||||
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class EditFrequencyPlanningSetResourceDialog;
|
||||
}
|
||||
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class EditFrequencyPlanningResourceDataModel;
|
||||
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
class EditFrequencyPlanningSetResourceDialog : public LtsWidgets::LtsFramelessDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
enum DialogMode
|
||||
{
|
||||
Edit,
|
||||
Assign,
|
||||
Show
|
||||
};
|
||||
|
||||
explicit EditFrequencyPlanningSetResourceDialog(const QSet<int> &assignedFrequencySetDataIds,
|
||||
const RcOperatingMode operatingMode,
|
||||
int32_t frequencySetId,
|
||||
const int &cnrConfigId,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
QWidget *parent);
|
||||
|
||||
|
||||
~EditFrequencyPlanningSetResourceDialog();
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
|
||||
signals:
|
||||
void onSelectedFrequencySet(int frequencySetDataId);
|
||||
private:
|
||||
|
||||
std::unique_ptr<Ui::EditFrequencyPlanningSetResourceDialog> m_ui;
|
||||
int32_t m_frequencySetId;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
EditFrequencyPlanningResourceDataModel *m_frequencyResourceDataModel;
|
||||
CnrConfig m_config;
|
||||
DialogMode m_dialogMode;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class EditFrequencyPlanningSetResourceDialog
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>EditFrequencyPlanningSetResourceDialog</class>
|
||||
<widget class="QWidget" name="EditFrequencyPlanningSetResourceDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>933</width>
|
||||
<height>587</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Asset Stocks</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblDataView">
|
||||
<property name="text">
|
||||
<string>To assign select an entry:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="dvFrequencyData"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsDialogButtonBox" name="ltsDialogButtonBox"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDialogButtonBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_dialog_button_box.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+498
@@ -0,0 +1,498 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The FrequencyPlanningDialog lists all FrequencyPlanning data and offers to set the active Planning for the current exercise
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_frequency_planning_dialog.h"
|
||||
#include "ui_avm_frequency_planning_dialog.h"
|
||||
#include "avm_frequency_planning_dialog_model.h"
|
||||
#include "avm_edit_frequency_planning_dialog.h"
|
||||
#include "avm_init_frequency_planning_dialog.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
|
||||
#include <LtsWidgets/lts_base_layout_widget.h>
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QTreeView>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
FrequencyPlanningDialog::FrequencyPlanningDialog(LtsSession::LtsSession *session, const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
||||
, m_ui(new Ui::FrequencyPlanningDialog)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_copy(false)
|
||||
, m_session(session)
|
||||
, m_model(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_activePlanning( { -1, -1 })
|
||||
, m_avmDtc(nullptr)
|
||||
, m_avmFtc(nullptr)
|
||||
, m_ppmDtc(nullptr)
|
||||
, m_ismDtc(nullptr)
|
||||
, m_flmGui(nullptr)
|
||||
, m_activeFrequencyPlanningStatus(0)
|
||||
, m_logger(getLogger("FrequencyPlanningDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
DEBUG_LOG(m_logger) << "---FrequencyPlanningDialog() ";
|
||||
m_ui->dataView->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
m_ui->dataView->treeView()->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &FrequencyPlanningDialog::onPrint);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Frequency_Planning"));
|
||||
}
|
||||
|
||||
FrequencyPlanningDialog::~FrequencyPlanningDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Frequency Planning"));
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::unsetActiveFrequencyPlanning()
|
||||
{
|
||||
m_ui->lbActiveFrequencyPlanning->setText(tr("No Frequency Planning set"));
|
||||
m_activePlanning = { -1, -1 };
|
||||
m_model->unsetActivePlanning();
|
||||
onSelectionChanged();
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::setActiveFrequencyPlanning(const ActiveFrequencyPlanning &activePlanning)
|
||||
{
|
||||
m_ui->lbActiveFrequencyPlanning->setText(QString::fromStdString(m_avmDtc->frequencyPlanning(activePlanning.frequencyPlanningId()).name()));
|
||||
m_activePlanning = activePlanning;
|
||||
m_model->setActivePlanning(m_activePlanning.frequencyPlanningId());
|
||||
onSelectionChanged();
|
||||
}
|
||||
|
||||
bool FrequencyPlanningDialog::init(const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<Interface::Ftc> &avmFtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
ExerciseManagement::Interface::Dtc *exmDtc)
|
||||
{
|
||||
if (!(ppmDtc->enableParty() &&
|
||||
ppmDtc->enableParticipant() &&
|
||||
ppmDtc->enableType() &&
|
||||
avmDtc->enableCnrConfig() &&
|
||||
avmDtc->enableFrequencyPlanning() &&
|
||||
avmDtc->enableFrequencySet() &&
|
||||
avmDtc->enableActiveFrequencyPlanning() &&
|
||||
ismDtc->enableMainStructureElement()))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not enable topics";
|
||||
return false;
|
||||
}
|
||||
|
||||
delete m_model;
|
||||
m_model = new FrequencyPlanningDialogModel(m_session->exerciseId(), this);
|
||||
|
||||
m_avmDtc = avmDtc;
|
||||
m_avmFtc = avmFtc;
|
||||
m_ppmDtc = ppmDtc;
|
||||
m_ismDtc = ismDtc;
|
||||
m_exmDtc = exmDtc;
|
||||
|
||||
if (!m_model->init(avmDtc))
|
||||
{
|
||||
delete m_model;
|
||||
m_model = nullptr;
|
||||
ERROR_LOG(m_logger) << "Could not init model";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_proxyModel = new FrequencyPlanningDialogProxyModel(this);
|
||||
m_proxyModel->setSourceModel(m_model);
|
||||
m_ui->dataView->setModel(m_proxyModel);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Add, this, &FrequencyPlanningDialog::onAddClicked);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Edit, this, &FrequencyPlanningDialog::onEditClicked);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Remove, this, &FrequencyPlanningDialog::onRemoveClicked);
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Save, this, &FrequencyPlanningDialog::onActivateDeactivatePlanningClicked);
|
||||
|
||||
connect(m_ui->dataView, &LtsDataView::LtsDataView::signalSelectionChanged,
|
||||
this, &FrequencyPlanningDialog::onSelectionChanged);
|
||||
|
||||
unsetActiveFrequencyPlanning();
|
||||
|
||||
|
||||
connect(m_ui->dataView, &LtsDataView::LtsDataView::signalDoubleClicked,
|
||||
this, &FrequencyPlanningDialog::onEditClicked);
|
||||
connect(m_avmDtc.get(), &Interface::Dtc::activeFrequencyPlanningChanged,
|
||||
this, &FrequencyPlanningDialog::onActiveFrequencyPlanningChanged);
|
||||
|
||||
m_ui->dataView->hideColumn(FrequencyPlanningDialogModel::Columns::SET);
|
||||
|
||||
m_avmDtc->activeFrequencyPlannings([this](const ActiveFrequencyPlanning & data)
|
||||
{
|
||||
onActiveFrequencyPlanningChanged(data, DataModification::eAdded);
|
||||
});
|
||||
onSelectionChanged();
|
||||
|
||||
setStatus(tr("No active Radio Controller connected."), {}, time(0) * 1000, TransmissionReason::TR_Unknown, Qt::red);
|
||||
for(auto &elem : m_avmDtc->frequencyPlanningStatuss())
|
||||
{
|
||||
if (!elem.isActive())
|
||||
continue;
|
||||
m_activeFrequencyPlanningStatus = elem.id();
|
||||
onFrequencyPlanningStatusChanged(elem, DataModification::eAdded);
|
||||
}
|
||||
connect(m_avmDtc.get(), &Interface::Dtc::frequencyPlanningStatusChanged, this, &FrequencyPlanningDialog::onFrequencyPlanningStatusChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onFrequencyPlanningStatusChanged(const AudioVideoManagement::FrequencyPlanningStatus &data, DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eModified)
|
||||
{
|
||||
if (data.id() != m_activeFrequencyPlanningStatus)
|
||||
return;
|
||||
}
|
||||
else if (modType == DataModification::eRemoved)
|
||||
{
|
||||
if (data.id() != m_activeFrequencyPlanningStatus)
|
||||
return;
|
||||
|
||||
m_activeFrequencyPlanningStatus = 0;
|
||||
setStatus(tr("No active Radio Controller connected."), {}, time(0) * 1000, TransmissionReason::TR_Unknown, Qt::red);
|
||||
return;
|
||||
}
|
||||
else // added....
|
||||
{
|
||||
if (!data.isActive())
|
||||
return;
|
||||
m_activeFrequencyPlanningStatus = data.id();
|
||||
}
|
||||
|
||||
// Active and data.id == m_active...Status:
|
||||
|
||||
if (data.activated().is_set())
|
||||
{
|
||||
setStatus(tr("Activated"), QString::fromStdString(data.requester()), data.activated().get(), data.reason(), Qt::green);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.received().is_set())
|
||||
{
|
||||
setStatus(tr("In Progress"), QString::fromStdString(data.requester()), data.received().get(), data.reason(), Qt::yellow);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.sent().is_set())
|
||||
{
|
||||
setStatus(tr("Sent"), QString::fromStdString(data.requester()), data.sent().get(), TransmissionReason::TR_Unknown, Qt::yellow);
|
||||
return;
|
||||
}
|
||||
setStatus(tr("Connection established, status unknown."), {}, time(0) * 1000, TransmissionReason::TR_Unknown, Qt::yellow);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::setStatus(const QString &statusText, const QString &requester, qint64 timeStampMsecs, TransmissionReason reason, Qt::GlobalColor color)
|
||||
{
|
||||
m_ui->lblStatus->setText(statusText);
|
||||
m_ui->lblStatusTime->setText(DTG::toStringMSec(timeStampMsecs));
|
||||
m_ui->lblStatus->setToolTip(toString(reason));
|
||||
m_ui->lblStatusTime->setToolTip(requester);
|
||||
setBackgroundColor(m_ui->lblStatus, color, color != Qt::black);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::tableColumnOrganiserSetting()
|
||||
{
|
||||
//LtsColumnOrganiser
|
||||
m_ui->dataView->setColumnsOrganiserEnabled(identifier(), true);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::setBackgroundColor(QWidget *w, Qt::GlobalColor color, bool bSetColor)
|
||||
{
|
||||
if (!w)
|
||||
return;
|
||||
|
||||
if (bSetColor)
|
||||
{
|
||||
QPalette pal = QApplication::palette(w);
|
||||
pal.setColor(QPalette::Window, color);
|
||||
w->setPalette(pal);
|
||||
w->setAutoFillBackground(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// reset to default palette
|
||||
w->setPalette(QApplication::palette(w));
|
||||
w->setAutoFillBackground(false);
|
||||
}
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onModifyFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onRemoveFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onRemoveActiveFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onModifyActiveFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onAddClicked() // TODO: add-button in nav bar ?
|
||||
{
|
||||
const QModelIndexList selectedRows = m_ui->dataView->selectedRows();
|
||||
Q_ASSERT(selectedRows.empty() || selectedRows.size() == 1);
|
||||
QMap<int32_t, FrequencySet> frequencySets = m_avmDtc->frequencySets();
|
||||
if (selectedRows.empty())
|
||||
{
|
||||
if(frequencySets.size() == 1)
|
||||
{
|
||||
FrequencyPlanning planning;
|
||||
|
||||
planning.id(0);
|
||||
if(m_session->exerciseId() != 0)
|
||||
planning.exerciseId(m_session->exerciseId());
|
||||
planning.frequencySetId(frequencySets.first().id());
|
||||
planning.date(m_session->partitionTime());
|
||||
showEditDialog(planning);
|
||||
}
|
||||
else
|
||||
{
|
||||
InitFrequencyPlanningDialog *initDialog = new InitFrequencyPlanningDialog(m_session, m_avmDtc, this);
|
||||
|
||||
connect(initDialog, &InitFrequencyPlanningDialog::newInitFrequencyPlanning,
|
||||
this, &FrequencyPlanningDialog::showEditDialog);
|
||||
|
||||
m_copy = false;
|
||||
addDialog(initDialog, m_menuGroup, QStringLiteral("NewFrequencyPlanning"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_copy = true; // Neuer Plan auf Basis einer Kopie mit alten Daten ... ==> akt. CreationTime eintragen
|
||||
qint64 dateOfCreation = m_session->partitionTime();
|
||||
FrequencyPlanning planning = m_model->data(selectedRows.constFirst(), Qt::UserRole).value<FrequencyPlanning>();
|
||||
planning.date(dateOfCreation);
|
||||
showEditDialog(planning);
|
||||
}
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onEditClicked()
|
||||
{
|
||||
QModelIndex currentIndex = m_ui->dataView->currentIndex();
|
||||
|
||||
if (!currentIndex.isValid())
|
||||
return;
|
||||
|
||||
const FrequencyPlanning &fp = m_model->data(currentIndex, Qt::UserRole).value<FrequencyPlanning>();
|
||||
DEBUG_LOG(m_logger) << "---onEditClicked() FrequencyPlanningId: " << fp.id() << " FrequencySetDataId: " << fp.frequencySetId();
|
||||
|
||||
m_copy = false;
|
||||
showEditDialog(m_model->data(currentIndex, Qt::UserRole).value<FrequencyPlanning>());
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onRemoveClicked()
|
||||
{
|
||||
const QModelIndex currentIndex = m_ui->dataView->currentIndex();
|
||||
|
||||
if (!currentIndex.isValid())
|
||||
return;
|
||||
|
||||
int planningId = m_model->data(currentIndex, Qt::UserRole).value<FrequencyPlanning>().id();
|
||||
// Schliesst ggf. noch offene zugehoerige Edit und Resource Dialoge wenn der Frequenzplan geloescht wird
|
||||
if (m_editDlgMap.contains(planningId))
|
||||
{
|
||||
m_editDlgMap.value(planningId)->deleteLater();
|
||||
m_editDlgMap.remove(planningId);
|
||||
}
|
||||
|
||||
Core::RemoveElementRequest req;
|
||||
|
||||
req.id(planningId);
|
||||
|
||||
m_requestHelper->startSingleRequest([this, req]()
|
||||
{
|
||||
return m_avmFtc->removeFrequencyPlanningRequest(req, this);
|
||||
});
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onSelectionChanged()
|
||||
{
|
||||
const QModelIndexList selectedRows = m_ui->dataView->selectedRows();
|
||||
bool hasSelection = !selectedRows.empty();
|
||||
bool selectedIsActive = false;
|
||||
if (hasSelection)
|
||||
{
|
||||
const QModelIndex currentIndex = selectedRows.constFirst();
|
||||
selectedIsActive = m_model->data(currentIndex, Qt::UserRole).value<FrequencyPlanning>().id() == m_activePlanning.frequencyPlanningId();
|
||||
}
|
||||
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Edit, hasSelection);
|
||||
// Do not allow remove if selected Planing is active
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Remove, hasSelection && !selectedIsActive);
|
||||
// "Save" actually means "active/deactivate planning"
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Save, hasSelection && m_session->exerciseId() && m_session->exerciseState() == LtsWidgets::ExcState::eStarted);
|
||||
|
||||
if (selectedIsActive)
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setText(tr("Deactivate"));
|
||||
else
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Save)->setText(tr("Activate"));
|
||||
|
||||
bool disableGlobalPlanning = m_session->exerciseId() == 0 && m_proxyModel->rowCount() !=0;
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Add, !disableGlobalPlanning);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onActivateDeactivatePlanningClicked()
|
||||
{
|
||||
if (QMessageBox::question(this, tr("Frequency Planning"), tr("Are you sure you want to switch the active frequency planning?"),
|
||||
QMessageBox::StandardButtons(QMessageBox::StandardButton::Yes | QMessageBox::StandardButton::No))
|
||||
== QMessageBox::StandardButton::No)
|
||||
return;
|
||||
|
||||
QModelIndex currentIndex = m_ui->dataView->currentIndex();
|
||||
|
||||
if (!currentIndex.isValid())
|
||||
return;
|
||||
|
||||
int32_t planningId = m_model->data(currentIndex, Qt::UserRole).value<FrequencyPlanning>().id();
|
||||
|
||||
bool isActive = planningId == m_activePlanning.frequencyPlanningId();
|
||||
if (!isActive)
|
||||
{
|
||||
ModifyActiveFrequencyPlanningRequest request(m_session->exerciseId(), planningId);
|
||||
|
||||
m_requestHelper->startSingleRequest([this, request]()
|
||||
{
|
||||
return m_avmFtc->modifyActiveFrequencyPlanningRequest(request, this);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
RemoveActiveFrequencyPlanningRequest request(m_session->exerciseId());
|
||||
|
||||
m_requestHelper->startSingleRequest([this, request]()
|
||||
{
|
||||
return m_avmFtc->removeActiveFrequencyPlanningRequest(request, this);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::showEditDialog(const FrequencyPlanning &planning)
|
||||
{
|
||||
QString widgetIdentifier(QStringLiteral("FrequencyPlanning%1").arg(QString::number(planning.id())));
|
||||
if (m_copy)
|
||||
widgetIdentifier.append(QStringLiteral("Copy"));
|
||||
|
||||
if (baseLayoutWidget()->focusTab(menuGroup(), widgetIdentifier, LtsWidgets::LayoutArea::eDialogTab))
|
||||
return;
|
||||
EditFrequencyPlanningDialog *dlg = new EditFrequencyPlanningDialog(m_session, m_menuGroup, widgetIdentifier, planning, m_copy, m_avmDtc, m_avmFtc, m_ppmDtc, m_ismDtc, m_exmDtc, this);
|
||||
connect(dlg, &EditFrequencyPlanningDialog::aboutToCloseMe, this , [this](int planningId)
|
||||
{
|
||||
if (planningId <= 0 || !m_editDlgMap.contains(planningId))
|
||||
return;
|
||||
m_editDlgMap.remove(planningId);
|
||||
});
|
||||
|
||||
|
||||
addDialog(dlg, m_menuGroup, widgetIdentifier);
|
||||
|
||||
if (!m_copy)
|
||||
{
|
||||
m_editDlgMap.insert(planning.id(), dlg);
|
||||
}
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onActiveFrequencyPlanningChanged(const ActiveFrequencyPlanning &data, DataModification modType)
|
||||
{
|
||||
if (data.exerciseId() != m_session->exerciseId())
|
||||
return;
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
unsetActiveFrequencyPlanning();
|
||||
else
|
||||
setActiveFrequencyPlanning(data);
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_ui->dataView->treeView() );
|
||||
}
|
||||
|
||||
// Library
|
||||
void FrequencyPlanningDialog::onExportButtonClicked()
|
||||
{
|
||||
QByteArray byteArray = m_model->modelToJson();
|
||||
|
||||
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), byteArray);
|
||||
if (fileId > 0)
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialog::onImportButtonClicked()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " onImportButtonClicked() ";
|
||||
if (m_model->rowCount() > 0)
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Only available if the list is empty."),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray content;
|
||||
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::AVMFrequencyPlanning));
|
||||
if (fileId > 0)
|
||||
{
|
||||
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::AVMFrequencyPlanning)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QVector<ModifyFrequencyPlanningRequest> requests = m_model->jsonToFrequencyPlanningVector(content);
|
||||
for (const auto &request : requests)
|
||||
{
|
||||
m_requestHelper->startSingleRequest([this, request]()
|
||||
{
|
||||
return m_avmFtc->modifyFrequencyPlanningRequest(request, this);
|
||||
});
|
||||
}
|
||||
INFO_LOG(m_logger) << "--- onImportButtonClicked() ";
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace AudioVideoManagement
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The FrequencyPlanningDialog lists all FrequencyPlanning data and offers to set the active Planning for the current exercise
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_ftc.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <memory>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FrequencyPlanningDialog;
|
||||
}
|
||||
|
||||
namespace LtsUtils
|
||||
{
|
||||
class RequestHelper;
|
||||
}
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
class FrequencyPlanningDialogModel;
|
||||
class FrequencyPlanningDialogProxyModel;
|
||||
class EditFrequencyPlanningDialog;
|
||||
|
||||
class FrequencyPlanningDialog
|
||||
: public LtsWidgets::LtsDialog
|
||||
, protected Interface::Ftc::ModifyFrequencyPlanningReplyHandler
|
||||
, protected Interface::Ftc::RemoveFrequencyPlanningReplyHandler
|
||||
, protected Interface::Ftc::ModifyActiveFrequencyPlanningReplyHandler
|
||||
, protected Interface::Ftc::RemoveActiveFrequencyPlanningReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FrequencyPlanningDialog(LtsSession::LtsSession *session, const QString &menuGroup, QWidget *parent = nullptr);
|
||||
~FrequencyPlanningDialog();
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<Interface::Ftc> &avmFtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
ExerciseManagement::Interface::Dtc *exmDtc);
|
||||
|
||||
void onModifyFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onRemoveFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onRemoveActiveFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
void onModifyActiveFrequencyPlanningReply(const Core::FunctionReplyObject &replyObject) override final;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAddClicked();
|
||||
void onEditClicked();
|
||||
void onRemoveClicked();
|
||||
void onSelectionChanged();
|
||||
void onActivateDeactivatePlanningClicked();
|
||||
void showEditDialog(const FrequencyPlanning &planning);
|
||||
void onActiveFrequencyPlanningChanged(const ActiveFrequencyPlanning &data, DataModification modType);
|
||||
void onFrequencyPlanningStatusChanged(const FrequencyPlanningStatus &data, DataModification modType);
|
||||
void onPrint();
|
||||
void onExportButtonClicked();
|
||||
void onImportButtonClicked();
|
||||
signals:
|
||||
void aboutToCloseMe(int);
|
||||
|
||||
private: // methods
|
||||
void retranslate() override;
|
||||
void unsetActiveFrequencyPlanning();
|
||||
void setActiveFrequencyPlanning(const ActiveFrequencyPlanning &activePlanning);
|
||||
void setButtonSetActivePlanningEnabled();
|
||||
static void setBackgroundColor(QWidget *w, Qt::GlobalColor color, bool bSetColor);
|
||||
void setStatus(const QString &statusText, const QString &requester, qint64 timeStampMsecs, TransmissionReason reason = TransmissionReason_def::TR_Unknown, Qt::GlobalColor color = Qt::black);
|
||||
void tableColumnOrganiserSetting() override;
|
||||
|
||||
private: // attributes
|
||||
Ui::FrequencyPlanningDialog *m_ui;
|
||||
QString m_menuGroup;
|
||||
bool m_copy;
|
||||
LtsSession::LtsSession *m_session;
|
||||
FrequencyPlanningDialogModel *m_model;
|
||||
FrequencyPlanningDialogProxyModel *m_proxyModel;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
ActiveFrequencyPlanning m_activePlanning;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
std::shared_ptr<Interface::Ftc> m_avmFtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
ExerciseManagement::Interface::Dtc *m_exmDtc;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
|
||||
QMap<int, EditFrequencyPlanningDialog*> m_editDlgMap;
|
||||
int m_activeFrequencyPlanningStatus;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class FrequencyPlanningDialog
|
||||
} // namespace AudioVideoManagement
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FrequencyPlanningDialog</class>
|
||||
<widget class="QWidget" name="FrequencyPlanningDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>692</width>
|
||||
<height>524</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="4">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>321</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxStatus">
|
||||
<property name="text">
|
||||
<string>Status:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxActiveFrequencyPlanning">
|
||||
<property name="text">
|
||||
<string>Active Frequency Planning:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="5">
|
||||
<widget class="LtsDataView::LtsDataView" name="dataView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="5">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="lblStatus">
|
||||
<property name="text">
|
||||
<string notr="true">[STATUS]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="lblStatusTime">
|
||||
<property name="text">
|
||||
<string notr="true">[TIME]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QLabel" name="lbActiveFrequencyPlanning">
|
||||
<property name="text">
|
||||
<string notr="true"><ACTIVE PLANNING></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The FrequencyPlanningDialogModel offers data for the FrequencyPlanningDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_frequency_planning_dialog_model.h"
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
FrequencyPlanningDialogModel::FrequencyPlanningDialogModel(int32_t exerciseId, QObject *parent)
|
||||
: LtsAbstractTableModel<FrequencyPlanning>(
|
||||
{
|
||||
tr("Name"),
|
||||
tr("Date"),
|
||||
tr("Set"),
|
||||
tr("Active")
|
||||
}, parent)
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_logger(getLogger("FrequencyPlanningDialogModel"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "---FrequencyPlanningDialogModel() ";
|
||||
}
|
||||
|
||||
QVariant FrequencyPlanningDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole && role != Qt::UserRole) || !indexIsValid(index))
|
||||
return QVariant();
|
||||
|
||||
const FrequencyPlanning &planning = m_vecData.at(index.row());
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case NAME:
|
||||
return QString::fromStdString(planning.name());
|
||||
case DATE:
|
||||
return QDateTime::fromMSecsSinceEpoch(planning.date());
|
||||
case SET:
|
||||
{
|
||||
const FrequencySet frequencySet = m_avmDtc->frequencySet(planning.frequencySetId());
|
||||
return QString::fromStdString(frequencySet.name());
|
||||
}
|
||||
case ACTIVE:
|
||||
return planning.id() == m_activePlanningId ? tr("Active") : QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
else if (role == Qt::UserRole)
|
||||
return QVariant::fromValue(planning);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool FrequencyPlanningDialogModel::init(const std::shared_ptr<Interface::Dtc> &avmDtc)
|
||||
{
|
||||
m_avmDtc = avmDtc;
|
||||
|
||||
m_frequencySets = m_avmDtc->frequencySets();
|
||||
|
||||
connect(m_avmDtc.get(), &AudioVideoManagement::Interface::Dtc::frequencyPlanningChanged,
|
||||
this, &FrequencyPlanningDialogModel::onFrequencyPlanningChanged);
|
||||
|
||||
m_avmDtc->frequencyPlannings([this](const FrequencyPlanning & p)
|
||||
{
|
||||
if (p.exerciseId().is_set() && p.exerciseId().get() == m_exerciseId)
|
||||
insertRow(p);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FrequencySet FrequencyPlanningDialogModel::frequencySetByIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return FrequencySet();
|
||||
|
||||
return m_frequencySets.value(m_vecData.at(index.row()).frequencySetId());
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialogModel::onFrequencyPlanningChanged(const FrequencyPlanning &data, DataModification modType)
|
||||
{
|
||||
INFO_LOG(m_logger) << "onFrequencyPlanningChanged "
|
||||
<< " data.exerciseId()" << data.exerciseId()
|
||||
<< " m_exerciseId=" << m_exerciseId;
|
||||
if ((data.exerciseId().is_set() && data.exerciseId().get() != m_exerciseId)
|
||||
|| (!data.exerciseId().is_set() && m_exerciseId != 0))
|
||||
return;
|
||||
|
||||
onDataChanged(data, modType);
|
||||
}
|
||||
|
||||
QByteArray FrequencyPlanningDialogModel::modelToJson()
|
||||
{
|
||||
QJsonObject obj;
|
||||
QJsonArray arr;
|
||||
QJsonArray arrData;
|
||||
|
||||
for (int row = 0; row < rowCount(); row++)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "row =" << ": " << row;
|
||||
QJsonObject inner;
|
||||
const FrequencyPlanning &planning = m_vecData.at(row);
|
||||
|
||||
inner[QStringLiteral("id")] = planning.id();
|
||||
inner[QStringLiteral("name")] = QString::fromStdString(planning.name());
|
||||
inner[QStringLiteral("dateOfCreation")] = planning.date();
|
||||
if(planning.exerciseId().is_set())
|
||||
{
|
||||
inner[QStringLiteral("exerciseId")] = planning.exerciseId().get();
|
||||
}
|
||||
inner[QStringLiteral("frequencySetId")] = planning.frequencySetId();
|
||||
|
||||
arrData = {};
|
||||
for (const FrequencyPlanningData &planningData : planning.data())
|
||||
{
|
||||
QJsonObject innerData;
|
||||
innerData[QStringLiteral("cnrConfigId")] = planningData.cnrConfigId();
|
||||
innerData[QStringLiteral("properties")] = QString::fromStdString(planningData.properties());
|
||||
arrData += innerData;
|
||||
}
|
||||
inner[QStringLiteral("data")] = arrData;
|
||||
arr += inner;
|
||||
}
|
||||
|
||||
obj[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::AVMFrequencyPlanning);
|
||||
obj[QStringLiteral("FrequencyPlanning")] = arr;
|
||||
QJsonDocument doc(obj);
|
||||
return doc.toJson(QJsonDocument::Compact);
|
||||
|
||||
}
|
||||
|
||||
QVector<ModifyFrequencyPlanningRequest> FrequencyPlanningDialogModel::jsonToFrequencyPlanningVector(const QByteArray &content)
|
||||
{
|
||||
QVector<ModifyFrequencyPlanningRequest> result;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content));
|
||||
const QJsonObject toplevelObj(doc.object());
|
||||
const QJsonArray arr(toplevelObj.value(QStringLiteral("FrequencyPlanning")).toArray());
|
||||
for (const auto &ele : arr)
|
||||
{
|
||||
const QJsonObject obj(ele.toObject());
|
||||
ModifyFrequencyPlanningRequest frequencyPlanning;
|
||||
frequencyPlanning.date(obj[QStringLiteral("dateOfCreation")].toDouble());
|
||||
frequencyPlanning.exerciseId(m_exerciseId); // Actual exercise
|
||||
frequencyPlanning.frequencySetId(obj[QStringLiteral("frequencySetId")].toInt());
|
||||
frequencyPlanning.id(0); // New entry
|
||||
frequencyPlanning.name(obj[QStringLiteral("name")].toString().toStdString());
|
||||
|
||||
//Start frequencyPlanning.data();
|
||||
const QJsonArray arrData = (obj.value(QStringLiteral("data")).toArray());
|
||||
frequencyPlanning.data().reserve(arrData.size());
|
||||
for (const auto &eleData : arrData)
|
||||
{
|
||||
const QJsonObject objData(eleData.toObject());
|
||||
FrequencyPlanningData frequencyPlanningData;
|
||||
frequencyPlanningData.cnrConfigId(objData[QStringLiteral("cnrConfigId")].toInt());
|
||||
frequencyPlanningData.properties(objData[QStringLiteral("properties")].toString().toStdString());
|
||||
frequencyPlanning.data().push_back(frequencyPlanningData);
|
||||
}
|
||||
//End frequencyPlanning.data();
|
||||
|
||||
result.push_back(std::move(frequencyPlanning));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void FrequencyPlanningDialogProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<FrequencyPlanningDialogModel*>(sourceModel);
|
||||
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
bool FrequencyPlanningDialogProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
if (!m_sourceModel ||
|
||||
source_left.column() != source_right.column() ||
|
||||
!source_left.isValid() ||
|
||||
!source_right.isValid())
|
||||
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
|
||||
const auto &dataLeft = m_sourceModel->m_vecData.at(source_left.row());
|
||||
const auto dataRight = m_sourceModel->m_vecData.at(source_right.row());
|
||||
switch (source_left.column())
|
||||
{
|
||||
case FrequencyPlanningDialogModel::DATE:
|
||||
return dataLeft.date() < dataRight.date();
|
||||
case FrequencyPlanningDialogModel::NAME:
|
||||
case FrequencyPlanningDialogModel::SET:
|
||||
case FrequencyPlanningDialogModel::ACTIVE:
|
||||
case FrequencyPlanningDialogModel::COUNT:
|
||||
break;
|
||||
}
|
||||
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
|
||||
}
|
||||
|
||||
} // namespace FrequencyPlanningDialogModel
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The FrequencyPlanningDialogModel offers data for the FrequencyPlanningDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <boost/optional.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class FrequencyPlanningDialogModel final
|
||||
: public LtsWidgets::LtsAbstractTableModel<FrequencyPlanning>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
NAME,
|
||||
DATE,
|
||||
SET,
|
||||
ACTIVE,
|
||||
COUNT
|
||||
};
|
||||
|
||||
explicit FrequencyPlanningDialogModel(int32_t exerciseId, QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
|
||||
bool init(const std::shared_ptr<Interface::Dtc> &avmDtc);
|
||||
|
||||
void setActivePlanning(int activePlanningId) { m_activePlanningId = activePlanningId; }
|
||||
void unsetActivePlanning() { m_activePlanningId.reset(); }
|
||||
|
||||
FrequencySet frequencySetByIndex(const QModelIndex &index) const;
|
||||
QByteArray modelToJson();
|
||||
QVector<ModifyFrequencyPlanningRequest> jsonToFrequencyPlanningVector(const QByteArray &content);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onFrequencyPlanningChanged(const FrequencyPlanning &data, DataModification modType);
|
||||
|
||||
private:
|
||||
int32_t m_exerciseId;
|
||||
boost::optional<int> m_activePlanningId;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
|
||||
QMap<int32_t, FrequencySet> m_frequencySets;
|
||||
|
||||
friend class FrequencyPlanningDialogProxyModel;
|
||||
LOGGER_T m_logger;
|
||||
}; // class FrequencyPlanningDialogModel
|
||||
|
||||
class FrequencyPlanningDialogProxyModel final : public LtsWidgets::LtsColumnFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
private:
|
||||
FrequencyPlanningDialogModel *m_sourceModel = nullptr;
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Q_DECLARE_METATYPE(AudioVideoManagement::FrequencyPlanning)
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Some data structures for frequency planning
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_frequency_planning_helper.h"
|
||||
#include <QObject>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
QString getOperatingModeText(int operatingMode)
|
||||
{
|
||||
switch (operatingMode)
|
||||
{
|
||||
case 0:
|
||||
return QObject::tr("Fixed frequency, no encryption");
|
||||
case 1:
|
||||
return QObject::tr("Fixed frequency, encryption: HW_KR");
|
||||
case 2:
|
||||
return QObject::tr("Fixed frequency, encryption: HW_KR_KL");
|
||||
case 3:
|
||||
return QObject::tr("AKW, no encryption");
|
||||
case 4:
|
||||
return QObject::tr("AKW, encryption: ECCM");
|
||||
default:
|
||||
return QObject::tr("Unknown Operating Mode");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Some data structures for frequency planning
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include "../CombatNetRadioConfiguration/avm_combat_net_radio_dialog_model.h" // only for Q_DECLARE_METATYPE(AudioVideoManagement::CnrConfig)
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
QString getOperatingModeText(int operatingMode);
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
template<typename Key, typename T, class Iterator>
|
||||
class QKeyValueIterator
|
||||
{
|
||||
public:
|
||||
typedef typename Iterator::iterator_category iterator_category;
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef std::pair<Key, T> value_type;
|
||||
typedef const value_type *pointer;
|
||||
typedef const value_type &reference;
|
||||
|
||||
QKeyValueIterator() = default;
|
||||
Q_DECL_CONSTEXPR explicit QKeyValueIterator(Iterator o) Q_DECL_NOEXCEPT_EXPR(std::is_nothrow_move_constructible<Iterator>::value)
|
||||
: i(std::move(o)) {}
|
||||
|
||||
std::pair<Key, T> operator*() const {
|
||||
return std::pair<Key, T>(i.key(), i.value());
|
||||
}
|
||||
|
||||
friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) Q_DECL_NOEXCEPT { return lhs.i == rhs.i; }
|
||||
friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) Q_DECL_NOEXCEPT { return lhs.i != rhs.i; }
|
||||
|
||||
inline QKeyValueIterator &operator++() { ++i; return *this; }
|
||||
inline QKeyValueIterator operator++(int) { return QKeyValueIterator(i++); }
|
||||
inline QKeyValueIterator &operator--() { --i; return *this; }
|
||||
inline QKeyValueIterator operator--(int) { return QKeyValueIterator(i--); }
|
||||
Iterator base() const { return i; }
|
||||
|
||||
private:
|
||||
Iterator i;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper class in order to iterate over key-value-pairs of a QMap using
|
||||
* a range-for loop. The returned iterator allows only read-only access.
|
||||
* The class keeps a const reference; the user has to make sure
|
||||
* that the referenced instance lives long enough.
|
||||
*/
|
||||
template<class Key, class T>
|
||||
class OverKeyValue
|
||||
{
|
||||
public:
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
using const_iterator_tmp = typename QMap<Key, T>::const_iterator;
|
||||
using const_key_value_iterator = QKeyValueIterator<const Key&, const T&, const_iterator_tmp>;
|
||||
using const_iterator = typename OverKeyValue<Key, T>::const_key_value_iterator;
|
||||
#else
|
||||
using const_iterator = typename QMap<Key, T>::const_key_value_iterator;
|
||||
#endif
|
||||
|
||||
explicit OverKeyValue(const QMap<Key, T> &map)
|
||||
: m_map(map)
|
||||
{}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
|
||||
const_iterator begin() const { return const_key_value_iterator(m_map.begin()); }
|
||||
const_iterator end() const { return const_key_value_iterator(m_map.end()); }
|
||||
#else
|
||||
const_iterator begin() const { return m_map.keyValueBegin(); }
|
||||
const_iterator end() const { return m_map.keyValueEnd(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
const QMap<Key, T> &m_map;
|
||||
};
|
||||
|
||||
template<class Key, class T>
|
||||
OverKeyValue<Key, T> overKeyValue(const QMap<Key, T> &map)
|
||||
{
|
||||
return OverKeyValue<Key, T>(map);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
+246
@@ -0,0 +1,246 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The FrequencyPlanningDialog contains the controls for the editFrequencyPlanningResourceDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Verena Eberlein, SPMO, 2023-09-21
|
||||
*/
|
||||
|
||||
#include "avm_frequency_planning_widget.h"
|
||||
#include <LtsWidgets/lts_spinbox.h>
|
||||
#include "ui_avm_frequency_planning_widget.h"
|
||||
#include "avm_edit_frequency_planning_set_resource_dialog.h"
|
||||
#include "avm_radio_specifica_hf_widget.h"
|
||||
#include "avm_radio_specifica_vhf_widget.h"
|
||||
#include "avm_radio_specifica_uhf_widget.h"
|
||||
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
#include <InfrastructureManagement/Gui/IsmComboBox/ism_combobox_gui_plugin.h>
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
FrequencyPlanningWidget::FrequencyPlanningWidget(const std::shared_ptr<Interface::Dtc> &avmDtc, QSet<int> &allocatedDataSets, QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_ui(new Ui::FrequencyPlanningWidget)
|
||||
, m_assignedFrequencySetDataIds(allocatedDataSets)
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_logger(getLogger("EditFrequencyPlanningResourceDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->cbFrequencyBand->addItem(toString(FrequencyBand_def::VHF), FrequencyBand_def::VHF);
|
||||
m_ui->cbFrequencyBand->addItem(toString(FrequencyBand_def::HF), FrequencyBand_def::HF);
|
||||
m_ui->cbFrequencyBand->addItem(toString(FrequencyBand_def::UHF), FrequencyBand_def::UHF);
|
||||
|
||||
connect(m_ui->leName, &QLineEdit::textChanged,
|
||||
this, &FrequencyPlanningWidget::onNameChanged);
|
||||
connect(m_ui->cbFrequencyBand, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this, &FrequencyPlanningWidget::onFrequencyBandChanged);
|
||||
connect(m_avmDtc.get(), &AudioVideoManagement::Interface::Dtc::cnrConfigChanged,
|
||||
this, &FrequencyPlanningWidget::onCnrConfigChanged);
|
||||
}
|
||||
|
||||
bool FrequencyPlanningWidget::init(LtsSession::LtsSession *session, RadioCircuit *data, const CnrConfig &cnrConfigId, int frequencySetId, FrequencyBand ft)
|
||||
{
|
||||
m_frequencySetId = frequencySetId;
|
||||
m_cnrConfigId = cnrConfigId.id();
|
||||
m_hasParty = cnrConfigId.partyId() != 0;
|
||||
|
||||
if (!session->getForeignGuiInterface<InfrastructureManagement::ForeignGuiComboboxInterface>(m_ismCbxIfc))
|
||||
return false;
|
||||
|
||||
m_ui->cbFrequencyBand->setCurrentIndex(m_ui->cbFrequencyBand->findData(ft.underlying()));
|
||||
m_ui->cbFrequencyBand->setVisible(false);
|
||||
m_ui->lbxFrequencyBand->setVisible(false);
|
||||
|
||||
switch (ft.underlying())
|
||||
{
|
||||
// Mehrere OperationModes nur fuer Devices 'VHF' oder 'REL'/'R01'/'R02' moeglich
|
||||
case FrequencyBand_def::HF:
|
||||
{
|
||||
createHFWidget(data);
|
||||
break;
|
||||
}
|
||||
case FrequencyBand_def::UHF:
|
||||
{
|
||||
createUHFWidget(data);
|
||||
break;
|
||||
}
|
||||
case FrequencyBand_def::VHF:
|
||||
{
|
||||
createVHFWidget(data);
|
||||
break;
|
||||
}
|
||||
default: //FrequencyBand_def::REL
|
||||
{
|
||||
ft = data ? data->freqBand : FrequencyBand::VHF;
|
||||
m_isRelay = true;
|
||||
|
||||
m_ui->cbFrequencyBand->setCurrentIndex(m_ui->cbFrequencyBand->findData(ft.underlying()));
|
||||
m_ui->cbFrequencyBand->setVisible(true);
|
||||
m_ui->lbxFrequencyBand->setVisible(true);
|
||||
switch (ft.underlying())
|
||||
{
|
||||
case FrequencyBand_def::HF:
|
||||
createHFWidget(data);
|
||||
break;
|
||||
case FrequencyBand_def::UHF:
|
||||
createUHFWidget(data);
|
||||
break;
|
||||
case FrequencyBand_def::VHF:
|
||||
createVHFWidget(data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_ismCbxIfc->fillRadioStationsComboBox(m_ui->cbRadioStation, ft.underlying());
|
||||
if (m_hasParty && !m_isRelay)
|
||||
m_ui->cbRadioStation->addItem(tr("Automatic"), 0);
|
||||
if (!data)
|
||||
m_ui->leName->clear();
|
||||
else
|
||||
{
|
||||
m_ui->leName->setText(data->name);
|
||||
m_ui->cbRadioStation->setCurrentIndex(m_ui->cbRadioStation->findData(data->radioStationId));
|
||||
}
|
||||
|
||||
adjustSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::setNameDisabled(bool disable)
|
||||
{
|
||||
m_ui->leName->setDisabled(disable);
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::setName(const QString &name)
|
||||
{
|
||||
m_ui->leName->setText(name);
|
||||
}
|
||||
|
||||
// Aktuell sollen bei Relais nur VHF-Kanäle möglich sein!
|
||||
void FrequencyPlanningWidget::setRelaisRestrictions(bool restrict)
|
||||
{
|
||||
if (restrict)
|
||||
{
|
||||
m_ui->cbFrequencyBand->setCurrentIndex(m_ui->cbFrequencyBand->findData(FrequencyBand_def::VHF));
|
||||
m_ui->cbFrequencyBand->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->cbFrequencyBand->setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QJsonObject FrequencyPlanningWidget::toJson() const
|
||||
{
|
||||
return frequencyPlanningJson(m_radioSpecificaWidget->toJson(),
|
||||
m_ui->leName->text(),
|
||||
static_cast<FrequencyBand::inner_enum>(m_ui->cbFrequencyBand->currentData().toInt()),
|
||||
m_ui->cbRadioStation->currentData().toInt());
|
||||
}
|
||||
|
||||
QVector<QPair<QLabel *, const std::function<bool ()> > > FrequencyPlanningWidget::requirements() const
|
||||
{
|
||||
return m_radioSpecificaWidget->requirements();
|
||||
}
|
||||
|
||||
FrequencyPlanningWidget::~FrequencyPlanningWidget()
|
||||
{
|
||||
if(m_radioSpecificaWidget)
|
||||
{
|
||||
delete m_radioSpecificaWidget;
|
||||
m_radioSpecificaWidget = nullptr;
|
||||
}
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::onFrequencyBandChanged()
|
||||
{
|
||||
switch (m_ui->cbFrequencyBand->currentData().toInt())
|
||||
{
|
||||
case FrequencyBand_def::HF:
|
||||
createHFWidget();
|
||||
break;
|
||||
case FrequencyBand_def::UHF:
|
||||
createUHFWidget();
|
||||
break;
|
||||
case FrequencyBand_def::VHF:
|
||||
createVHFWidget();
|
||||
break;
|
||||
}
|
||||
|
||||
m_ui->cbRadioStation->clear();
|
||||
m_ismCbxIfc->fillRadioStationsComboBox(m_ui->cbRadioStation, m_ui->cbFrequencyBand->currentData().toInt());
|
||||
if(m_hasParty && !m_isRelay)
|
||||
m_ui->cbRadioStation->addItem(tr("Automatic"), 0);
|
||||
|
||||
if(m_radioSpecificaWidget)
|
||||
m_ui->gridLayout->addWidget(m_radioSpecificaWidget,5,0,1,2);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::createHFWidget(RadioCircuit* circuit)
|
||||
{
|
||||
if(m_radioSpecificaWidget)
|
||||
{
|
||||
delete m_radioSpecificaWidget;
|
||||
m_radioSpecificaWidget = nullptr;
|
||||
}
|
||||
m_radioSpecificaWidget = new RadioSpecificaHfWidget(m_ui->radioSpecificaWidget);
|
||||
if(!circuit)
|
||||
return;
|
||||
RadioCircuitHF *dataHf = dynamic_cast<RadioCircuitHF*>(circuit);
|
||||
m_radioSpecificaWidget->setValues(dataHf);
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::createUHFWidget(RadioCircuit* circuit)
|
||||
{
|
||||
if(m_radioSpecificaWidget)
|
||||
{
|
||||
delete m_radioSpecificaWidget;
|
||||
m_radioSpecificaWidget = nullptr;
|
||||
}
|
||||
m_radioSpecificaWidget = new RadioSpecificaUhfWidget(m_ui->radioSpecificaWidget);
|
||||
if(!circuit)
|
||||
return;
|
||||
RadioCircuitUHF* dataUhf = dynamic_cast<RadioCircuitUHF*>(circuit);
|
||||
m_radioSpecificaWidget->setValues(dataUhf);
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::createVHFWidget(RadioCircuit* circuit)
|
||||
{
|
||||
if(m_radioSpecificaWidget)
|
||||
{
|
||||
delete m_radioSpecificaWidget;
|
||||
m_radioSpecificaWidget = nullptr;
|
||||
}
|
||||
auto *widget = new RadioSpecificaVhfWidget(m_assignedFrequencySetDataIds, m_ui->radioSpecificaWidget);
|
||||
widget->init(m_frequencySetId, m_avmDtc, m_cnrConfigId);
|
||||
m_radioSpecificaWidget = widget;
|
||||
|
||||
if(!circuit)
|
||||
return;
|
||||
RadioCircuitVHF* dataVhf = dynamic_cast<RadioCircuitVHF*>(circuit);
|
||||
m_radioSpecificaWidget->setValues(dataVhf);
|
||||
}
|
||||
|
||||
void FrequencyPlanningWidget::onCnrConfigChanged(const AudioVideoManagement::CnrConfig &config, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
if (m_cnrConfigId == config.id())
|
||||
{
|
||||
m_ui->leName->setText(QString::fromStdString(config.radioCircuit()));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace LtsWidgets
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The FrequencyPlanningWidget contains the controls for the editFrequencyPlanningResourceDialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Verena Eberlein, SPMO, 2023-09-21
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QWidget>
|
||||
#include <AudioVideoManagement/avm.hpp>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
|
||||
class QLabel;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FrequencyPlanningWidget;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
class ForeignGuiComboboxInterface;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace LtsWidgets
|
||||
{
|
||||
class LtsSpinBox;
|
||||
class LtsComboBox;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class RadioSpecificaWidget;
|
||||
|
||||
|
||||
class FrequencyPlanningWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
FrequencyPlanningWidget(const std::shared_ptr<Interface::Dtc> &avmDtc, QSet<int> &allocatedDataSets, QWidget *parent = nullptr);
|
||||
~FrequencyPlanningWidget();
|
||||
|
||||
bool init(LtsSession::LtsSession *session, RadioCircuit *data, const CnrConfig &cnrConfigId, int frequencySetId = -1, FrequencyBand ft = FrequencyBand_def::VHF);
|
||||
void setNameDisabled(bool disable);
|
||||
void setName(const QString& name);
|
||||
void setRelaisRestrictions(bool restrict);
|
||||
QJsonObject toJson() const;
|
||||
|
||||
QVector< QPair<QLabel*, const std::function<bool()> > > requirements() const;
|
||||
|
||||
signals:
|
||||
void onNameChanged(const QString&);
|
||||
|
||||
private slots:
|
||||
void onFrequencyBandChanged();
|
||||
void onCnrConfigChanged(const AudioVideoManagement::CnrConfig &config, DataModification modType);
|
||||
|
||||
private:
|
||||
Ui::FrequencyPlanningWidget *m_ui {nullptr};
|
||||
RadioSpecificaWidget *m_radioSpecificaWidget {nullptr};
|
||||
int m_frequencySetId {0};
|
||||
int m_cnrConfigId {0};
|
||||
QSet<int> &m_assignedFrequencySetDataIds;
|
||||
std::shared_ptr<InfrastructureManagement::ForeignGuiComboboxInterface> m_ismCbxIfc;
|
||||
bool m_hasParty;
|
||||
bool m_isRelay {false};
|
||||
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
|
||||
void createHFWidget(RadioCircuit* circuit = nullptr);
|
||||
void createUHFWidget(RadioCircuit* circuit = nullptr);
|
||||
void createVHFWidget(RadioCircuit* circuit = nullptr);
|
||||
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FrequencyPlanningWidget</class>
|
||||
<widget class="QWidget" name="FrequencyPlanningWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>561</width>
|
||||
<height>526</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxName">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leName"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxFrequencyBand">
|
||||
<property name="text">
|
||||
<string>Frequenzband:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cbFrequencyBand"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxRadioStation">
|
||||
<property name="text">
|
||||
<string>Funkstation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbRadioStation"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QWidget" name="radioSpecificaWidget" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* InitFrequencyPlanningDialog - Dialog to get initial data for a FrequencyPlanning
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#include "avm_init_frequency_planning_dialog.h"
|
||||
#include "ui_avm_init_frequency_planning_dialog.h"
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <ngltools/ngltools_dtg.h>
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
InitFrequencyPlanningDialog::InitFrequencyPlanningDialog(LtsSession::LtsSession *session, const std::shared_ptr<Interface::Dtc> &avmDtc, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkCancel)
|
||||
, m_ui(new Ui::InitFrequencyPlanningDialog)
|
||||
, m_dateOfCreation(session->partitionTime())
|
||||
, m_session(session)
|
||||
, m_logger(getLogger("InitFrequencyPlanningDialog"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "---InitFrequencyPlanningDialog() ";
|
||||
m_ui->setupUi(this);
|
||||
|
||||
QMap<int32_t, FrequencySet> frequencySets = avmDtc->frequencySets();
|
||||
|
||||
for (auto it = frequencySets.constBegin(); it != frequencySets.constEnd(); ++it)
|
||||
m_ui->cbFrequencySets->addItem(QString::fromStdString(it.value().name()), QVariant::fromValue(it.key()));
|
||||
|
||||
m_ui->tbTime->setText(DTG::toStringMSec(m_dateOfCreation));
|
||||
|
||||
connect(m_ui->tbTime, &QToolButton::clicked, this, [this]()
|
||||
{
|
||||
m_dateOfCreation = m_session->partitionTime();
|
||||
m_ui->tbTime->setText(DTG::toStringMSec(m_dateOfCreation));
|
||||
});
|
||||
|
||||
m_uiRequirements->addRequirement( { m_ui->lblName, [this]() { return !m_ui->leName->text().isEmpty(); } });
|
||||
m_uiRequirements->addRequirement( { m_ui->lblFrequencySets, [this]() { return !m_ui->cbFrequencySets->currentText().isEmpty(); } });
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Frequency_Planning"));
|
||||
}
|
||||
|
||||
|
||||
InitFrequencyPlanningDialog::~InitFrequencyPlanningDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void InitFrequencyPlanningDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("New Frequency Planning"));
|
||||
}
|
||||
|
||||
|
||||
bool InitFrequencyPlanningDialog::apply()
|
||||
{
|
||||
FrequencyPlanning planning;
|
||||
|
||||
planning.id(0);
|
||||
if(m_session->exerciseId() != 0)
|
||||
planning.exerciseId(m_session->exerciseId());
|
||||
planning.frequencySetId(m_ui->cbFrequencySets->currentData().toInt());
|
||||
planning.name(m_ui->leName->text().toStdString());
|
||||
planning.date(m_dateOfCreation);
|
||||
|
||||
emit newInitFrequencyPlanning(planning);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* InitFrequencyPlanningDialog - Dialog to get initial data for a FrequencyPlanning
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hannes Baeuerle, SLSE, 2017-09-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class InitFrequencyPlanningDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class InitFrequencyPlanningDialog : public LtsWidgets::LtsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InitFrequencyPlanningDialog(LtsSession::LtsSession *session, const std::shared_ptr<Interface::Dtc> &avmDtc, QWidget *parent);
|
||||
|
||||
~InitFrequencyPlanningDialog();
|
||||
|
||||
signals:
|
||||
void newInitFrequencyPlanning(const FrequencyPlanning &);
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
bool apply() override;
|
||||
|
||||
Ui::InitFrequencyPlanningDialog *m_ui;
|
||||
qint64 m_dateOfCreation;
|
||||
LtsSession::LtsSession *m_session;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
}; // class InitFrequencyPlanningDialog
|
||||
} // namespace AudioVideoManagement
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InitFrequencyPlanningDialog</class>
|
||||
<widget class="QWidget" name="InitFrequencyPlanningDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>427</width>
|
||||
<height>228</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Asset Stocks</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblName">
|
||||
<property name="text">
|
||||
<string>Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="leName">
|
||||
<property name="toolTip">
|
||||
<string>Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Date of Creation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="tbTime">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"><TIME></string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextOnly</enum>
|
||||
</property>
|
||||
<property name="arrowType">
|
||||
<enum>Qt::NoArrow</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblFrequencySets">
|
||||
<property name="text">
|
||||
<string>Frequency Set:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbFrequencySets"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The LoadFrequencyPlanningDialog allows to solve clonflicts for loaded FrequencyPlannings
|
||||
* $Id: avm_edit_combat_net_radio_dialog.h 60982 2023-12-01 10:18:25Z eberlein_v $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/optfunk/Lts/Plugins/AudioVideoManagement/Gui/CombatNetRadio/CombatNetRadioConfiguration/avm_edit_combat_net_radio_dialog.h $
|
||||
* $Author: eberlein_v $
|
||||
* Created by Hannes Fritsche, ESZS, 2024-02-06
|
||||
*/
|
||||
|
||||
#include "avm_load_frequency_planning_dialog.h"
|
||||
#include "ui_avm_load_frequency_planning_dialog.h"
|
||||
|
||||
#include "avm_load_frequency_planning_dialog_model.h"
|
||||
#include <QTreeView>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
LoadFrequencyPlanningDialog::LoadFrequencyPlanningDialog(const QByteArray &data, const FrequencyPlanning &initPlan, const std::shared_ptr<Interface::Dtc> &avmDtc, const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc, QWidget *parent)
|
||||
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
|
||||
, m_ui(new Ui::LoadFrequencyPlanningDialog)
|
||||
, m_model(new LoadFrequencyPlanningDialogModel(initPlan, avmDtc, ismDtc, this))
|
||||
, m_logger(getLogger("LoadFrequencyPlanningDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
DrawDelegate *treeDelegate = new DrawDelegate(m_model);
|
||||
m_ui->dataView->treeView()->setItemDelegateForColumn(LoadFrequencyPlanningDialogModel::Columns::PROPERTIES, treeDelegate);
|
||||
m_model->setData(data);
|
||||
|
||||
m_ui->dataView->setModel(m_model);
|
||||
|
||||
connect(m_ui->pbOk, &QPushButton::clicked,
|
||||
this, &LoadFrequencyPlanningDialog::onOk);
|
||||
connect(m_ui->pbCancel, &QPushButton::clicked,
|
||||
this, &LoadFrequencyPlanningDialog::close);
|
||||
connect(m_ui->cbAll, &QCheckBox::clicked,
|
||||
m_model, &LoadFrequencyPlanningDialogModel::checkAll);
|
||||
|
||||
m_ui->dataView->expandAll();
|
||||
}
|
||||
|
||||
QVector<int32_t> LoadFrequencyPlanningDialog::unassignments() const
|
||||
{
|
||||
return m_model->unassignments();
|
||||
}
|
||||
|
||||
QVector<FrequencyPlanningData> LoadFrequencyPlanningDialog::newPlanningData() const
|
||||
{
|
||||
return m_model->planningData();
|
||||
}
|
||||
|
||||
|
||||
bool LoadFrequencyPlanningDialog::isApplied() const
|
||||
{
|
||||
return m_isApplied;
|
||||
}
|
||||
|
||||
void LoadFrequencyPlanningDialog::onOk()
|
||||
{
|
||||
m_isApplied = true;
|
||||
close();
|
||||
}
|
||||
|
||||
LoadFrequencyPlanningDialog::~LoadFrequencyPlanningDialog() = default;
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The LoadFrequencyPlanningDialog allows to solve clonflicts for loaded FrequencyPlannings
|
||||
* $Id: avm_edit_combat_net_radio_dialog.h 60982 2023-12-01 10:18:25Z eberlein_v $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/optfunk/Lts/Plugins/AudioVideoManagement/Gui/CombatNetRadio/CombatNetRadioConfiguration/avm_edit_combat_net_radio_dialog.h $
|
||||
* $Author: eberlein_v $
|
||||
* Created by Hannes Fritsche, ESZS, 2024-02-06
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_frameless_dialog.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class LoadFrequencyPlanningDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
class LoadFrequencyPlanningDialogModel;
|
||||
|
||||
class LoadFrequencyPlanningDialog
|
||||
: public LtsWidgets::LtsFramelessDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LoadFrequencyPlanningDialog(const QByteArray &data,
|
||||
const FrequencyPlanning &initPlan,
|
||||
const std::shared_ptr<AudioVideoManagement::Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
~LoadFrequencyPlanningDialog();
|
||||
|
||||
QVector<int32_t> unassignments() const;
|
||||
QVector<FrequencyPlanningData> newPlanningData() const;
|
||||
|
||||
bool isApplied() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onOk();
|
||||
|
||||
private: // attributes
|
||||
std::unique_ptr<Ui::LoadFrequencyPlanningDialog> m_ui;
|
||||
LoadFrequencyPlanningDialogModel *m_model;
|
||||
bool m_isApplied = false;
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class LoadFrequencyPlanningDialog
|
||||
} // namespace AudioVideoManagement
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LoadFrequencyPlanningDialog</class>
|
||||
<widget class="QWidget" name="LoadFrequencyPlanningDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1200</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Load Cnr Configs</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbAll">
|
||||
<property name="text">
|
||||
<string>Check/Uncheck all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="dataView" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbOk">
|
||||
<property name="text">
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbCancel">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsDataView::LtsDataView</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsDataView/lts_data_view.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+968
@@ -0,0 +1,968 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The LoadFrequencyPlanningDialogModel provices data for LoadFrequencyPlanningDialog
|
||||
* $Id: avm_combat_net_radio_dialog_model.h 60985 2023-12-01 11:53:28Z eberlein_v $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/optfunk/Lts/Plugins/AudioVideoManagement/Gui/CombatNetRadio/CombatNetRadioConfiguration/avm_combat_net_radio_dialog_model.h $
|
||||
* $Author: eberlein_v $
|
||||
* Created by Hannes Fritsche, ESZS, 2023-02-06
|
||||
*/
|
||||
|
||||
#include "avm_load_frequency_planning_dialog_model.h"
|
||||
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <LtsUtilsCore/json_object.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
|
||||
#include <QPainter>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
void LoadFrequencyPlanningDialogModel::onFrequencyPlanningChanged(const FrequencyPlanning &initPlanning, DataModification dm)
|
||||
{
|
||||
Q_UNUSED(dm)
|
||||
|
||||
// Falsche Übung...
|
||||
if (initPlanning.exerciseId().is_set() && initPlanning.exerciseId().get() != m_exerciseId)
|
||||
return;
|
||||
|
||||
// Falsches Planning
|
||||
if (m_exerciseId > 0 && initPlanning.exerciseId().is_set() && initPlanning.id() != m_initPlan.id())
|
||||
return;
|
||||
// Aktuelle Übung = 42 und initPlanning = 0 --> Update alle items mit !exerciseId.isSet()
|
||||
// Aktuelle Übung = 42 und initPlanning = 42 --> Update alle items mit exerciseId.get() == 42
|
||||
// Aktuelle Übung = 0 und initPlanning = 0 --> Update alle items
|
||||
|
||||
beginResetModel();
|
||||
const int rowCount = getRootItem()->childCount();
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
{
|
||||
ConfigTreeItem *item = static_cast<ConfigTreeItem *>(getRootItem()->child(r));
|
||||
|
||||
if(!item)
|
||||
continue;
|
||||
ItemData id = item->data().value<ItemData>();
|
||||
|
||||
if (m_exerciseId == 0 && !initPlanning.exerciseId().is_set())
|
||||
{
|
||||
id.clearRadioCircuit();
|
||||
item->setData(QVariant::fromValue(id));
|
||||
item->removeAllChildren();
|
||||
continue;
|
||||
}
|
||||
|
||||
// --> Aktuelle Übung = 42 <-- und initPlanning = 0 : Update alle items mit !exerciseId.isSet()
|
||||
// --> Aktuelle Übung = 42 <-- und initPlanning = 42 : Update alle items mit exerciseId.get() == 42
|
||||
if (m_exerciseId > 0)
|
||||
{
|
||||
// Aktuelle Übung = 42 und --> initPlanning = 42 <-- : Update alle items mit exerciseId.get() == 42
|
||||
if (initPlanning.exerciseId().is_set())
|
||||
{
|
||||
// Aktuelle Übung = 42 und initPlanning = 42 : Update alle items mit --> exerciseId.get() == 42 <--
|
||||
if (id.cnrConfig.exerciseId().is_set())
|
||||
{
|
||||
id.clearRadioCircuit();
|
||||
item->setData(QVariant::fromValue(id));
|
||||
item->removeAllChildren();
|
||||
}
|
||||
}
|
||||
// Aktuelle Übung = 42 und --> initPlanning = 0 <-- : Update alle items mit !exerciseId.isSet()
|
||||
else
|
||||
{
|
||||
// Aktuelle Übung = 42 und initPlanning = 0 : Update alle items mit --> !exerciseId.isSet() <--
|
||||
if (!id.cnrConfig.exerciseId().is_set())
|
||||
{
|
||||
id.clearRadioCircuit();
|
||||
item->setData(QVariant::fromValue(id));
|
||||
item->removeAllChildren();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_frequencyPlanningData.clear();
|
||||
|
||||
// Search for FP with ExId == 0:
|
||||
//Hier kommen die geplanten Plannings nicht mit raus. Daher fehlen die Daten nach einem Update, wenn die global Konf gändert wurde
|
||||
QMap<qint32,AudioVideoManagement::FrequencyPlanning> frequencyPlannings = m_avmDtc->frequencyPlannings();
|
||||
for(const auto &frequencyPlanning : qAsConst(frequencyPlannings))
|
||||
{
|
||||
//search Planning == 0 for m_exerciseId > 0 or
|
||||
//search Planning > 0 for m_exerciseId == 0
|
||||
if((initPlanning.exerciseId().is_set() && frequencyPlanning.exerciseId().is_set())
|
||||
|| (!initPlanning.exerciseId().is_set() && frequencyPlanning.exerciseId().is_set() && frequencyPlanning.exerciseId().get() != m_exerciseId))
|
||||
continue;
|
||||
|
||||
for(const auto &frequencyPlanningData : frequencyPlanning.data())
|
||||
{
|
||||
m_frequencyPlanningData.insert(frequencyPlanningData.cnrConfigId(), frequencyPlanningData);
|
||||
setFrequencyPlanningData(frequencyPlanningData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for(const auto &frequencyPlanningData : initPlanning.data())
|
||||
{
|
||||
m_frequencyPlanningData.insert(frequencyPlanningData.cnrConfigId(), frequencyPlanningData);
|
||||
setFrequencyPlanningData(frequencyPlanningData);
|
||||
}
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
LoadFrequencyPlanningDialogModel::LoadFrequencyPlanningDialogModel(const FrequencyPlanning &initPlan,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
QObject *parent)
|
||||
: NGLTreeModel(parent, new ConfigTreeItem(QVariant()),
|
||||
{
|
||||
tr("Channel Number"),
|
||||
tr("Conflicts"),
|
||||
tr("Radio Circuit"),
|
||||
tr("Radio Station"),
|
||||
tr("Frequency"),
|
||||
tr("Function"),
|
||||
tr("Device"),
|
||||
tr("AKW Bundle"),
|
||||
tr("FSB Bundle"),
|
||||
tr("AKW Radio Circuit"),
|
||||
tr("COMSEC"),
|
||||
tr("Pilotton"),
|
||||
tr("Operating Mode"),
|
||||
tr("Properties"),
|
||||
tr("Channel Spacing"),
|
||||
tr("Squelch"),
|
||||
})
|
||||
, m_avmDtc(avmDtc)
|
||||
, m_ismDtc(ismDtc)
|
||||
, m_initPlan(initPlan)
|
||||
, m_parentPlan(initPlan)
|
||||
, m_exerciseId(initPlan.exerciseId().is_set() ? initPlan.exerciseId().get() : 0)
|
||||
, m_logger(getLogger("EditFrequencyPlanningDataModel"))
|
||||
{
|
||||
Q_ASSERT(avmDtc);
|
||||
DEBUG_LOG(m_logger) << "---EditFrequencyPlanningDataMod m_frequencyPlanningData[c.id()];el() ";
|
||||
|
||||
m_initPlan.data().clear();
|
||||
|
||||
int frequencySetId = m_initPlan.frequencySetId();
|
||||
std::vector<FrequencySetDataWithId> fsdVec = m_avmDtc->frequencySet(frequencySetId).data();
|
||||
for(FrequencySetDataWithId fsd : fsdVec)
|
||||
{
|
||||
m_freqSetData.insert(fsd.id(), fsd);
|
||||
}
|
||||
onFrequencyPlanningChanged(m_initPlan,DataModification::eAdded);
|
||||
|
||||
m_cnrConfigs = m_avmDtc->cnrConfigs();
|
||||
m_existingCnrConfigs = m_cnrConfigs;
|
||||
m_frequencyPlannings = m_avmDtc->frequencyPlannings();
|
||||
m_ownTakenFrequencySetDataIds = getOwnTakenFrequencySetIds();
|
||||
}
|
||||
|
||||
void LoadFrequencyPlanningDialogModel::setData(const QByteArray &data)
|
||||
{
|
||||
using namespace LtsUtils;
|
||||
const JsonObject obj = JsonObject::fromJson(data);
|
||||
|
||||
if (m_initPlan.frequencySetId() != obj.value<int>("frequencySetId"))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "false frequency set!";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
beginResetModel();
|
||||
m_initPlan.data().clear();
|
||||
for (const JsonObject &association : obj.value<std::vector<JsonObject>>("planningInfos"))
|
||||
{
|
||||
FrequencyPlanningData info;
|
||||
int channelId = association.value<int>("cnrChannelId");
|
||||
int cnrConfigId = findCnrConfigByChannelId(channelId);
|
||||
|
||||
if (cnrConfigId == -1)
|
||||
{
|
||||
cnrConfigId = m_cnrConfigs.size();
|
||||
for(;m_cnrConfigs.contains(cnrConfigId); ++cnrConfigId);
|
||||
CnrConfig invalidConfig;
|
||||
|
||||
invalidConfig.id(cnrConfigId);
|
||||
invalidConfig.cnrChannelId(channelId);
|
||||
|
||||
m_cnrConfigs.insert(cnrConfigId, invalidConfig);
|
||||
}
|
||||
|
||||
info.cnrConfigId(cnrConfigId);
|
||||
info.properties(association.value<QString>("properties").toStdString());
|
||||
|
||||
m_frequencyPlanningData.insert(cnrConfigId, info);
|
||||
|
||||
m_initPlan.data().push_back(info);
|
||||
|
||||
const CnrConfig cnrConfig = m_cnrConfigs.value(cnrConfigId);
|
||||
|
||||
ItemData id(cnrConfig);
|
||||
if (m_frequencyPlanningData.contains(cnrConfig.id()))
|
||||
{
|
||||
FrequencyPlanningData fpd = info;
|
||||
id.readOnly = isReadOnly(fpd.properties());
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
|
||||
if (circuits.size() > 1)
|
||||
{
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
m_checkStates.insert(m_rootItem->childCount(), Qt::Unchecked);
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
id.radioCircuit = circuit;
|
||||
ConfigTreeItem *childItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
|
||||
insertRow(configItem->childCount(), indexFromItem(childItem), childItem);
|
||||
}
|
||||
}
|
||||
else if (circuits.size() == 1)
|
||||
{
|
||||
id.radioCircuit = circuits[0];
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
m_checkStates.insert(m_rootItem->childCount(), Qt::Unchecked);
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigTreeItem *configItem = new ConfigTreeItem(QVariant::fromValue(id));
|
||||
m_checkStates.insert(m_rootItem->childCount(), Qt::Unchecked);
|
||||
insertRow(m_rootItem->childCount(), indexFromItem(m_rootItem), configItem);
|
||||
}
|
||||
}
|
||||
onFrequencyPlanningChanged(m_initPlan, DataModification::eAdded);
|
||||
|
||||
endResetModel();
|
||||
|
||||
checkConflicts();
|
||||
setCheckStates();
|
||||
}
|
||||
|
||||
LoadFrequencyPlanningDialogModel::ItemData LoadFrequencyPlanningDialogModel::itemData(const QModelIndex &index)
|
||||
{
|
||||
NGLTreeItem *item = privateData(index);
|
||||
if (!item->data().canConvert<ItemData>())
|
||||
return {};
|
||||
|
||||
return item->data().value<ItemData>();
|
||||
}
|
||||
|
||||
QVariant LoadFrequencyPlanningDialogModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if ((role != Qt::DisplayRole && role != Qt::ToolTipRole && role != Qt::UserRole && role != Qt::TextColorRole && role != Qt::BackgroundRole && role != Qt::CheckStateRole) || !index.isValid())
|
||||
return NGLTreeModel::data(index, role);
|
||||
ConfigTreeItem *item = static_cast<ConfigTreeItem *>(privateData(index));
|
||||
|
||||
if (!item->data().canConvert<ItemData>())
|
||||
return NGLTreeModel::data(index, role);
|
||||
|
||||
ItemData id = item->data().value<ItemData>();
|
||||
|
||||
const CnrConfig &setData = id.cnrConfig;
|
||||
RadioCircuit *rc = id.radioCircuit;
|
||||
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
if (index.column() != PROPERTIES)
|
||||
return {};
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (rcVhf && !isAkwMode(rcVhf->operatingMode))
|
||||
return tr("Pilot Tone: %1")
|
||||
.arg(rcVhf->pilotTone ? tr("On") : tr("Off"));
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
if (rcUhf)
|
||||
return tr("Clipper: %1, AGC: %2, Modulation Type: %3")
|
||||
.arg(rcUhf->clipper ? tr("On") : tr("Off"))
|
||||
.arg(rcUhf->agc ? tr("On") : tr("Off"))
|
||||
.arg(toString(rcUhf->modulationType));
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (rcHf)
|
||||
return tr("Channel Spacing: %1, Squelch: %2")
|
||||
.arg(toString(rcHf->channelSpacing))
|
||||
.arg(rcHf->squelch > 0 ? QString::number(rcHf->squelch) : tr("Off"));
|
||||
}
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
// FrequenySetDaten fuer den aktuellen Sprechkreis (cnrConfigId) ermitteln/anzeigen
|
||||
case FUNCTION:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
return QString::fromStdString(m_freqSetData[rc->frequencySetDataId()].function());
|
||||
}
|
||||
case DEVICE:
|
||||
{
|
||||
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!rcVhf)
|
||||
return QStringLiteral("-");
|
||||
return toString(m_freqSetData[rc->frequencySetDataId()].frequencyBand().underlying());
|
||||
}
|
||||
case FREQUENCY:
|
||||
{
|
||||
QLocale locale(QLocale::German);
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() > 0)
|
||||
{
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (rcVhf && isAkwMode(rcVhf->operatingMode))
|
||||
return QStringLiteral("-");
|
||||
return tr("%1 MHz").arg(locale.toString(m_freqSetData[rc->frequencySetDataId()].frequency() / 1000., 'f', 3));
|
||||
}
|
||||
else
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
|
||||
if (rcUhf)
|
||||
return tr("%1 MHz").arg(locale.toString(rcUhf->frequency / 1000000., 'f', 3));
|
||||
if (rcHf)
|
||||
return tr("%1 MHz").arg(locale.toString(rcHf->frequency / 1000000., 'f', 3));
|
||||
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
case AKW_BUNDLE:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].akwBundle().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].akwBundle().get();
|
||||
}
|
||||
case FSB_BUNDLE:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].fsbBundle().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].fsbBundle().get();
|
||||
}
|
||||
case AKW_RADIO_CIRCUIT:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].akwRadioCircuit().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].akwRadioCircuit().get();
|
||||
}
|
||||
case COMSEC:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
if (rc->frequencySetDataId() <= 0)
|
||||
return QStringLiteral("-");
|
||||
if (!m_freqSetData[rc->frequencySetDataId()].comsec().is_set())
|
||||
return QStringLiteral("-");
|
||||
|
||||
return m_freqSetData[rc->frequencySetDataId()].comsec().get();
|
||||
}
|
||||
// cnrConfig Daten...
|
||||
case RADIO_CIRCUIT:
|
||||
{
|
||||
if (!rc)
|
||||
return QString::fromStdString(setData.radioCircuit());
|
||||
|
||||
return id.name();
|
||||
}
|
||||
case RADIO_STATION:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
|
||||
if (rc->radioStationId == 0)
|
||||
return tr("Automatic");
|
||||
else
|
||||
return QString::fromStdString(m_ismDtc->mainStructureElement(rc->radioStationId).name());
|
||||
}
|
||||
case PILOTTON:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!rcVhf)
|
||||
return QStringLiteral("-");
|
||||
|
||||
return rcVhf->pilotTone ? tr("On") : tr("Off");
|
||||
}
|
||||
case OPERATING_MODE:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!rcVhf)
|
||||
return QStringLiteral("-");
|
||||
|
||||
return toString(rcVhf->operatingMode);
|
||||
}
|
||||
case CHANNEL:
|
||||
{
|
||||
CnrChannel channel = m_avmDtc->cnrChannel(setData.cnrChannelId());
|
||||
return QString::fromStdString(channel.name());
|
||||
}
|
||||
case PROPERTIES:
|
||||
{
|
||||
if (!rc)
|
||||
return QStringLiteral("-");
|
||||
else
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
RadioCircuitVHF *rcVhf = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
QStringList sl;
|
||||
if (rcUhf)
|
||||
{
|
||||
sl << createIcon(ICON_CLIPPER, rcUhf->clipper );
|
||||
sl << createIcon(ICON_AGC, rcUhf->agc );
|
||||
sl << createIcon(ICON_MODULATION_TYPE, 0, rcUhf->modulationType);
|
||||
// sl << createIcon(ICON_CHANNEL_SPACING);
|
||||
// sl << toString(rcUhf->channelSpacing);
|
||||
// sl << createIcon(ICON_SQUELCH, rcUhf->squelchDB > 0) ;
|
||||
// if(rcUhf->squelchDB > 0)
|
||||
// sl << tr("%1 dB").arg(rcUhf->squelchDB);
|
||||
|
||||
return sl.join(QStringLiteral(" "));
|
||||
}
|
||||
if (rcVhf && !isAkwMode(rcVhf->operatingMode))
|
||||
{
|
||||
sl << createIcon(ICON_PILOTTON, rcVhf->pilotTone > 0);
|
||||
return sl.join(QStringLiteral(" "));
|
||||
}
|
||||
if (rcHf)
|
||||
{
|
||||
// sl << createIcon(ICON_CHANNEL_SPACING);
|
||||
// sl << toString(rcHf->channelSpacing);
|
||||
// sl << createIcon(ICON_SQUELCH, rcHf->squelch);
|
||||
// if(rcHf->squelch > 0)
|
||||
// sl << QString::number(rcHf->squelch);
|
||||
|
||||
return sl.join(QStringLiteral(" "));
|
||||
}
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
case CHANNEL_SPACING:
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (rcUhf)
|
||||
return toString(rcUhf->channelSpacing);
|
||||
if (rcHf)
|
||||
return toString(rcHf->channelSpacing);
|
||||
return {};
|
||||
}
|
||||
case SQUELCH:
|
||||
{
|
||||
RadioCircuitUHF *rcUhf = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
RadioCircuitHF *rcHf = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (rcUhf)
|
||||
return rcUhf->squelchDB > 0 ? tr("%1 dB").arg(rcUhf->squelchDB) : QVariant();
|
||||
if (rcHf)
|
||||
return rcHf->squelch > 0 ? QString::number(rcHf->squelch) : QVariant();
|
||||
return {};
|
||||
}
|
||||
case CONFLICTS:
|
||||
{
|
||||
if (index.parent() != QModelIndex())
|
||||
return NGLTreeModel::data(index, role);
|
||||
|
||||
if (m_conflicts.contains(index.row()))
|
||||
return getConflictText(m_conflicts.value(index.row()));
|
||||
|
||||
return QLatin1String("-");
|
||||
}
|
||||
default:
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
|
||||
if (role == Qt::UserRole)
|
||||
return setData.id();
|
||||
|
||||
if (role == Qt::TextColorRole)
|
||||
{
|
||||
// Zeilen der doppelt vergebenen Resourcen markieren
|
||||
for (int id : m_multipleAssignedCnrIds)
|
||||
{
|
||||
if (id == setData.id())
|
||||
return QColor(Qt::red);
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::BackgroundRole)
|
||||
{
|
||||
if (index.parent() == QModelIndex())
|
||||
{
|
||||
if (m_conflicts.contains(index.row()))
|
||||
return getConflictColor(m_conflicts.value(index.row()));
|
||||
|
||||
return QColor(Qt::green).lighter();
|
||||
}
|
||||
|
||||
return data(index.parent(), role);
|
||||
}
|
||||
|
||||
if (role == Qt::CheckStateRole && index.column() == 0 && index.parent() == QModelIndex())
|
||||
return m_checkStates.value(index.row());
|
||||
|
||||
return NGLTreeModel::data(index, role);
|
||||
}
|
||||
|
||||
QString LoadFrequencyPlanningDialogModel::createIcon(PropertyData propertyDataType, bool on, ModulationType type) const
|
||||
{
|
||||
QString imgHeader = QStringLiteral("<img src=\"%1\" height=\"32\" title=\"%2\" image-rendering=\"optimizeQuality\">");
|
||||
|
||||
switch(propertyDataType)
|
||||
{
|
||||
case ICON_PILOTTON:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/pilotton-on.svg")
|
||||
: QStringLiteral(":/style/pilotton-off.svg"))
|
||||
.arg(on ?
|
||||
tr("Pilot Tone: On")
|
||||
: tr("Pilot Tone: Off"));
|
||||
case ICON_MODULATION_TYPE:
|
||||
return imgHeader
|
||||
.arg(type == ModulationType::AM ?
|
||||
QStringLiteral(":/style/AM.svg")
|
||||
: QStringLiteral(":/style/FM.svg"))
|
||||
.arg(on ?
|
||||
tr("Modulation Type: AM")
|
||||
: tr("Modulation Type: FM"));
|
||||
case ICON_SQUELCH:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/squelch-on.svg")
|
||||
: QStringLiteral(":/style/squelch-off.svg"))
|
||||
.arg(on ?
|
||||
tr("Squelch: On")
|
||||
: tr("Squelch: Off"));
|
||||
case ICON_CLIPPER:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/clipper-on.svg")
|
||||
: QStringLiteral(":/style/clipper-off.svg"))
|
||||
.arg(on ?
|
||||
tr("Clipper: On")
|
||||
: tr("Clipper: Off"));
|
||||
case ICON_AGC:
|
||||
return imgHeader
|
||||
.arg(on ?
|
||||
QStringLiteral(":/style/agc-on.svg")
|
||||
: QStringLiteral(":/style/agc-off.svg"))
|
||||
.arg(on ?
|
||||
tr("Automatic Gain Control (AGC): On")
|
||||
: tr("Automatic Gain Control (AGC): Off"));
|
||||
case ICON_CHANNEL_SPACING:
|
||||
return imgHeader
|
||||
.arg(QStringLiteral(":/style/channel-spacing-on.svg"))
|
||||
.arg(tr("Channel Spacing"));
|
||||
case ICON_SPACER:
|
||||
return imgHeader
|
||||
.arg(QStringLiteral(":/style/line_style_solid_v.svg"))
|
||||
.arg(tr("Channel Spacing"));
|
||||
default:
|
||||
return QStringLiteral("-");
|
||||
}
|
||||
}
|
||||
|
||||
int LoadFrequencyPlanningDialogModel::findCnrConfigByChannelId(int32_t channelId) const
|
||||
{
|
||||
int id = -1;
|
||||
std::function<bool(const CnrConfig &)> findByChannelIdInExercise = [this, channelId, &id] (const CnrConfig &cnrConfig)
|
||||
{
|
||||
if (cnrConfig.exerciseId().is_set() && cnrConfig.exerciseId() != m_exerciseId)
|
||||
return false;
|
||||
if (cnrConfig.cnrChannelId() != channelId)
|
||||
return false;
|
||||
|
||||
id = cnrConfig.id();
|
||||
return true;
|
||||
};
|
||||
|
||||
m_avmDtc->cnrConfigs(findByChannelIdInExercise);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void LoadFrequencyPlanningDialogModel::checkConflicts()
|
||||
{
|
||||
for (int32_t row = 0; row < rowCount(); ++row)
|
||||
{
|
||||
QModelIndex rowIndex = index(row, 0);
|
||||
ConfigTreeItem *item = static_cast<ConfigTreeItem *>(privateData(rowIndex));
|
||||
|
||||
if (!item || !item->data().canConvert<ItemData>())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Could not get item for row " << row;
|
||||
continue;
|
||||
}
|
||||
|
||||
QVector<NGLTreeItem *> itemsInRow;
|
||||
itemsInRow.reserve(item->childCount() + 1);
|
||||
|
||||
itemsInRow.append(item);
|
||||
itemsInRow += item->children();
|
||||
|
||||
for (NGLTreeItem *treeItem : qAsConst(itemsInRow))
|
||||
{
|
||||
ItemData itemData = treeItem->data().value<ItemData>();
|
||||
|
||||
if (!isCnrChannelInOwnConfig(itemData.cnrConfig.cnrChannelId()))
|
||||
{
|
||||
m_conflicts.insert(row, CHANNEL_NOT_IN_CNR_CONFIG);
|
||||
emit dataChanged(rowIndex, rowIndex, {Qt::BackgroundRole, Qt::DisplayRole});
|
||||
break;
|
||||
}
|
||||
|
||||
if (itemData.radioCircuit)
|
||||
{
|
||||
if (isFrequencySetDataTakenInOtherExercise(itemData.radioCircuit->frequencySetDataId()))
|
||||
{
|
||||
if (m_conflicts.value(row, FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING) > FREQUENCYSET_DATA_TAKEN_IN_OTHER_EXERCISE)
|
||||
{
|
||||
m_conflicts.insert(row, FREQUENCYSET_DATA_TAKEN_IN_OTHER_EXERCISE);
|
||||
emit dataChanged(rowIndex, rowIndex, {Qt::BackgroundRole, Qt::DisplayRole});
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isFrequencySetDataTakenInOwnFrequencyPlanning(itemData.radioCircuit->frequencySetDataId()))
|
||||
{
|
||||
if (m_conflicts.value(row, FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING) == FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING)
|
||||
{
|
||||
m_conflicts.insert(row, FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING);
|
||||
addUnassignmentForRow(parentCnrConfigIdByFrequencySetDataId(itemData.radioCircuit->frequencySetDataId()), row);
|
||||
emit dataChanged(rowIndex, rowIndex, {Qt::BackgroundRole, Qt::DisplayRole});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoadFrequencyPlanningDialogModel::setCheckStates()
|
||||
{
|
||||
for (int32_t row = 0; row < rowCount(); ++row)
|
||||
{
|
||||
if (m_conflicts.contains(row))
|
||||
continue;
|
||||
|
||||
m_checkStates[row] = Qt::Checked;
|
||||
|
||||
QModelIndex changeIndex = index(row, 0);
|
||||
|
||||
emit dataChanged(changeIndex, changeIndex, {Qt::CheckStateRole});
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadFrequencyPlanningDialogModel::isCnrChannelInOwnConfig(int32_t channelId) const
|
||||
{
|
||||
for (auto it = m_existingCnrConfigs.constBegin(); it != m_existingCnrConfigs.constEnd(); ++it)
|
||||
{
|
||||
const CnrConfig cnrConfig = it.value();
|
||||
const int32_t exerciseId = cnrConfig.exerciseId().is_set() ? cnrConfig.exerciseId().get() : 0;
|
||||
|
||||
if (exerciseId == m_exerciseId && cnrConfig.cnrChannelId() == channelId)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LoadFrequencyPlanningDialogModel::isFrequencySetDataTakenInOwnFrequencyPlanning(int32_t frequencySetDataId) const
|
||||
{
|
||||
return m_ownTakenFrequencySetDataIds.contains(frequencySetDataId);
|
||||
}
|
||||
|
||||
bool LoadFrequencyPlanningDialogModel::isFrequencySetDataTakenInOtherExercise(int32_t frequencySetDataId) const
|
||||
{
|
||||
for (auto it = m_frequencyPlannings.constBegin(); it != m_frequencyPlannings.constEnd(); ++it)
|
||||
{
|
||||
const FrequencyPlanning frequencyPlanning = it.value();
|
||||
const int32_t currentExerciseId = frequencyPlanning.exerciseId().is_set() ? frequencyPlanning.exerciseId().get() : 0;
|
||||
|
||||
if (currentExerciseId == m_exerciseId)
|
||||
continue;
|
||||
|
||||
for (const FrequencyPlanningData &data : frequencyPlanning.data())
|
||||
{
|
||||
QSet<int> frequencySetDataIds = AudioVideoManagement::frequencySetDataIds(data.properties());
|
||||
|
||||
if (frequencySetDataIds.contains(frequencySetDataId))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t LoadFrequencyPlanningDialogModel::parentCnrConfigIdByFrequencySetDataId(int32_t frequencySetDataId) const
|
||||
{
|
||||
for (const FrequencyPlanningData ¤tPlanning : m_parentPlan.data())
|
||||
{
|
||||
QSet<int> parentFrequencySetDataIds = AudioVideoManagement::frequencySetDataIds(currentPlanning.properties());
|
||||
|
||||
if (parentFrequencySetDataIds.contains(frequencySetDataId))
|
||||
return currentPlanning.cnrConfigId();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString LoadFrequencyPlanningDialogModel::getConflictText(LoadFrequencyPlanningDialogModel::Conflict conflict) const
|
||||
{
|
||||
switch (conflict)
|
||||
{
|
||||
case CHANNEL_NOT_IN_CNR_CONFIG:
|
||||
return tr("Cnr Channel not included in Cnr Config");
|
||||
case FREQUENCYSET_DATA_TAKEN_IN_OTHER_EXERCISE:
|
||||
return tr("Frequency Set data already taken in another exercise");
|
||||
case FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING:
|
||||
return tr("Frequency set data already taken in own frequency planning");
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
QColor LoadFrequencyPlanningDialogModel::getConflictColor(LoadFrequencyPlanningDialogModel::Conflict conflict) const
|
||||
{
|
||||
switch (conflict)
|
||||
{
|
||||
case CHANNEL_NOT_IN_CNR_CONFIG:
|
||||
case FREQUENCYSET_DATA_TAKEN_IN_OTHER_EXERCISE:
|
||||
return QColor(Qt::red).lighter();
|
||||
case FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING:
|
||||
return QColor(Qt::yellow).lighter();
|
||||
}
|
||||
|
||||
return QColor();
|
||||
}
|
||||
|
||||
bool LoadFrequencyPlanningDialogModel::isSolvableConflict(LoadFrequencyPlanningDialogModel::Conflict conflict) const
|
||||
{
|
||||
return conflict >= FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING;
|
||||
}
|
||||
|
||||
QSet<int> LoadFrequencyPlanningDialogModel::getOwnTakenFrequencySetIds() const
|
||||
{
|
||||
QSet<int> ownTakenFrequencySetIds;
|
||||
ownTakenFrequencySetIds.reserve(m_parentPlan.data().size() * 2);
|
||||
|
||||
for (const FrequencyPlanningData &data : m_parentPlan.data())
|
||||
ownTakenFrequencySetIds += AudioVideoManagement::frequencySetDataIds(data.properties());
|
||||
|
||||
return ownTakenFrequencySetIds;
|
||||
}
|
||||
|
||||
void LoadFrequencyPlanningDialogModel::addUnassignmentForRow(int32_t unassignment, int32_t row)
|
||||
{
|
||||
if (!m_unassignmentsPerRow.contains(row))
|
||||
m_unassignmentsPerRow.insert(row, {});
|
||||
|
||||
m_unassignmentsPerRow[row].append(unassignment);
|
||||
}
|
||||
|
||||
// Assign FrequencyPlanningData to RadioCircuit
|
||||
void LoadFrequencyPlanningDialogModel::setFrequencyPlanningData(const FrequencyPlanningData &fpd)
|
||||
{
|
||||
beginResetModel();
|
||||
ConfigTreeItem* item = searchCnrConfig(m_rootItem, fpd.cnrConfigId());
|
||||
if(!item)
|
||||
return;
|
||||
QVector<RadioCircuit*> circuits = AudioVideoManagement::fromJson(fpd.properties());
|
||||
ItemData data = item->data().value<ItemData>();
|
||||
item->removeAllChildren();
|
||||
|
||||
if (circuits.size() == 1)
|
||||
{
|
||||
data.radioCircuit = circuits[0];
|
||||
item->setData(QVariant::fromValue(data));
|
||||
m_frequencyPlanningData.insert(fpd.cnrConfigId(), fpd);
|
||||
}
|
||||
if (circuits.size() <= 1)
|
||||
return;
|
||||
|
||||
for (RadioCircuit *circuit : qAsConst(circuits))
|
||||
{
|
||||
data.radioCircuit = circuit;
|
||||
ConfigTreeItem *childItem = new ConfigTreeItem(QVariant::fromValue(data));
|
||||
insertRow(item->childCount(), indexFromItem(item), childItem);
|
||||
}
|
||||
m_frequencyPlanningData.insert(fpd.cnrConfigId(), fpd);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
Qt::ItemFlags LoadFrequencyPlanningDialogModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (index.isValid() && index.column() == 0)
|
||||
{
|
||||
if (m_conflicts.contains(index.row()) && !isSolvableConflict(m_conflicts.value(index.row())))
|
||||
return Qt::NoItemFlags;
|
||||
|
||||
return Qt::ItemIsUserCheckable | NGLTreeModel::flags(index);
|
||||
}
|
||||
|
||||
return NGLTreeModel::flags(index);
|
||||
}
|
||||
|
||||
bool LoadFrequencyPlanningDialogModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (role != Qt::CheckStateRole || !index.isValid() || index.parent() != QModelIndex())
|
||||
return NGLTreeModel::setData(index, value, role);
|
||||
|
||||
m_checkStates[index.row()] = value.value<Qt::CheckState>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QVector<int32_t> LoadFrequencyPlanningDialogModel::unassignments() const
|
||||
{
|
||||
QVector<int32_t> unassignmentsVec;
|
||||
unassignmentsVec.reserve(m_conflicts.size());
|
||||
|
||||
for (auto it = m_conflicts.constBegin(); it != m_conflicts.constEnd(); ++it)
|
||||
{
|
||||
if (!m_unassignmentsPerRow.contains(it.key()) || m_checkStates.value(it.key()) != Qt::Checked)
|
||||
continue;
|
||||
|
||||
unassignmentsVec += m_unassignmentsPerRow.value(it.key());
|
||||
}
|
||||
|
||||
return unassignmentsVec;
|
||||
}
|
||||
|
||||
QVector<FrequencyPlanningData> LoadFrequencyPlanningDialogModel::planningData() const
|
||||
{
|
||||
QVector<FrequencyPlanningData> planningDataVec;
|
||||
planningDataVec.reserve(rowCount());
|
||||
|
||||
for (int32_t row = 0; row < rowCount(); ++row)
|
||||
{
|
||||
if (m_checkStates.value(row, Qt::Unchecked) == Qt::Unchecked)
|
||||
continue;
|
||||
|
||||
QModelIndex rowIndex = index(row, 0);
|
||||
ConfigTreeItem *item = static_cast<ConfigTreeItem *>(privateData(rowIndex));
|
||||
|
||||
if (!item || !item->data().canConvert<ItemData>())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Could not get item for row " << row;
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemData itemData = item->data().value<ItemData>();
|
||||
|
||||
planningDataVec.append(m_frequencyPlanningData.value(itemData.cnrConfig.id()));
|
||||
}
|
||||
|
||||
return planningDataVec;
|
||||
}
|
||||
|
||||
void LoadFrequencyPlanningDialogModel::checkAll(bool isChecked)
|
||||
{
|
||||
for (int32_t row = 0; row < rowCount(); ++row)
|
||||
{
|
||||
if ((m_conflicts.contains(row) && !isSolvableConflict(m_conflicts.value(row))) || !m_checkStates.contains(row))
|
||||
continue;
|
||||
|
||||
m_checkStates[row] = isChecked ? Qt::Checked : Qt::Unchecked;
|
||||
|
||||
QModelIndex changedIndex = index(row, 0);
|
||||
|
||||
emit dataChanged(changedIndex, changedIndex, {Qt::CheckStateRole});
|
||||
}
|
||||
}
|
||||
|
||||
LoadFrequencyPlanningDialogModel::ConfigTreeItem* LoadFrequencyPlanningDialogModel::searchCnrConfig(const NGLTreeItem *parentItem, int cnrConfigId) const
|
||||
{
|
||||
const int rowCount = parentItem->childCount();
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
{
|
||||
ConfigTreeItem *child = static_cast<ConfigTreeItem *>(parentItem->child(r));
|
||||
if (child->data().value<ItemData>().cnrConfig.id() == cnrConfigId)
|
||||
return child;
|
||||
child = searchCnrConfig(child, cnrConfigId);
|
||||
if (child)
|
||||
return child;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//=============================================================================================================================
|
||||
// DrawDelegate
|
||||
//=============================================================================================================================
|
||||
DrawDelegate::DrawDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
void DrawDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||
{
|
||||
if (index.column() == LoadFrequencyPlanningDialogModel::Columns::PROPERTIES)
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
painter->save();
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(options.text);
|
||||
|
||||
options.text = QString();
|
||||
options.widget->style()->drawControl(QStyle::CE_ItemViewItem, &options, painter);
|
||||
|
||||
painter->translate(options.rect.left(), options.rect.top());
|
||||
QRect clip(0, 0, options.rect.width(), options.rect.height());
|
||||
doc.drawContents(painter, clip);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
else
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
|
||||
|
||||
QSize DrawDelegate::sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const
|
||||
{
|
||||
QStyleOptionViewItem options = option;
|
||||
initStyleOption(&options, index);
|
||||
|
||||
QTextDocument doc;
|
||||
doc.setHtml(options.text);
|
||||
doc.setTextWidth(options.rect.width());
|
||||
return QSize(doc.idealWidth(), doc.size().height());
|
||||
}
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* The LoadFrequencyPlanningDialogModel provices data for LoadFrequencyPlanningDialog
|
||||
* $Id: avm_combat_net_radio_dialog_model.h 60985 2023-12-01 11:53:28Z eberlein_v $
|
||||
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/optfunk/Lts/Plugins/AudioVideoManagement/Gui/CombatNetRadio/CombatNetRadioConfiguration/avm_combat_net_radio_dialog_model.h $
|
||||
* $Author: eberlein_v $
|
||||
* Created by Hannes Fritsche, ESZS, 2023-02-06
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <AudioVideoManagement/logger.h>
|
||||
#include "avm_frequency_planning_helper.h"
|
||||
#include <nglwidgets/ngltreemodel.h>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
|
||||
class CnrConfig;
|
||||
|
||||
class DrawDelegate
|
||||
: public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DrawDelegate(QObject *parent = nullptr);
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
QSize sizeHint( const QStyleOptionViewItem & option, const QModelIndex & index ) const override;
|
||||
|
||||
}; // DrawDelegate
|
||||
|
||||
class LoadFrequencyPlanningDialogModel
|
||||
: public NGLTreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
CHANNEL,
|
||||
CONFLICTS,
|
||||
RADIO_CIRCUIT,
|
||||
RADIO_STATION,
|
||||
FREQUENCY,
|
||||
FUNCTION,
|
||||
DEVICE,
|
||||
AKW_BUNDLE,
|
||||
FSB_BUNDLE,
|
||||
AKW_RADIO_CIRCUIT,
|
||||
COMSEC,
|
||||
PILOTTON,
|
||||
OPERATING_MODE,
|
||||
PROPERTIES,
|
||||
CHANNEL_SPACING,
|
||||
SQUELCH,
|
||||
COUNT,
|
||||
};
|
||||
|
||||
enum PropertyData
|
||||
{
|
||||
ICON_PILOTTON,
|
||||
ICON_MODULATION_TYPE,
|
||||
ICON_SQUELCH,
|
||||
ICON_CLIPPER,
|
||||
ICON_AGC,
|
||||
ICON_CHANNEL_SPACING,
|
||||
ICON_SPACER,
|
||||
ICON_COUNT,
|
||||
};
|
||||
|
||||
enum Conflict
|
||||
{
|
||||
CHANNEL_NOT_IN_CNR_CONFIG = 1,
|
||||
FREQUENCYSET_DATA_TAKEN_IN_OTHER_EXERCISE = 2,
|
||||
FREQUENCYSET_DATA_TAKEN_IN_OWN_FREQUENCY_PLANNING = 3,
|
||||
};
|
||||
|
||||
struct ItemData
|
||||
{
|
||||
CnrConfig cnrConfig;
|
||||
RadioCircuit* radioCircuit = nullptr;
|
||||
QString _name; // eigtl. Private...
|
||||
bool readOnly = false;
|
||||
|
||||
ItemData() = default;
|
||||
ItemData(const CnrConfig &_cnrConfig, const QString &itemName = {}, RadioCircuit* _rc = nullptr)
|
||||
: cnrConfig(_cnrConfig)
|
||||
, radioCircuit(_rc)
|
||||
, _name(itemName)
|
||||
{}
|
||||
|
||||
QString name() const { return radioCircuit ? radioCircuit->name : _name; }
|
||||
void setName(const QString &itemName) { _name = itemName; }
|
||||
void setName(const std::string &itemName) { setName(QString::fromStdString(itemName)); }
|
||||
void clearRadioCircuit() { delete radioCircuit; radioCircuit = nullptr; }
|
||||
};
|
||||
|
||||
class ConfigTreeItem final : public NGLTreeItem
|
||||
{
|
||||
public:
|
||||
using NGLTreeItem::NGLTreeItem;
|
||||
};
|
||||
|
||||
explicit LoadFrequencyPlanningDialogModel(const FrequencyPlanning &initPlan,
|
||||
const std::shared_ptr<Interface::Dtc> &avmDtc,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> &ismDtc,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
QVariant data(const QModelIndex &index, int role) const override final;
|
||||
ItemData itemData(const QModelIndex &index);
|
||||
|
||||
void setData(const QByteArray &data);
|
||||
|
||||
void setFrequencyPlanningData(const FrequencyPlanningData &fpd);
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const final override;
|
||||
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
||||
|
||||
QVector<int32_t> unassignments() const;
|
||||
QVector<FrequencyPlanningData> planningData() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
void checkAll(bool isChecked);
|
||||
|
||||
private:
|
||||
void onFrequencyPlanningChanged(const FrequencyPlanning &initPlanning, DataModification dm);
|
||||
int findCnrConfigByChannelId(int32_t channelId) const;
|
||||
void checkConflicts();
|
||||
void setCheckStates();
|
||||
bool isCnrChannelInOwnConfig(int32_t channelId) const;
|
||||
bool isFrequencySetDataTakenInOwnFrequencyPlanning(int32_t frequencySetDataId) const;
|
||||
bool isFrequencySetDataTakenInOtherExercise(int32_t frequencySetDataId) const;
|
||||
int32_t parentCnrConfigIdByFrequencySetDataId(int32_t frequencySetDataId) const;
|
||||
QString getConflictText(Conflict conflict) const;
|
||||
QColor getConflictColor(Conflict conflict) const;
|
||||
bool isSolvableConflict(Conflict conflict) const;
|
||||
QSet<int> getOwnTakenFrequencySetIds() const;
|
||||
void addUnassignmentForRow(int32_t unassignment, int32_t row);
|
||||
|
||||
|
||||
LoadFrequencyPlanningDialogModel::ConfigTreeItem* searchCnrConfig(const NGLTreeItem *parentItem, int cnrConfigId) const;
|
||||
QString createIcon(PropertyData PropertyDataType, bool on = true, ModulationType type = ModulationType::AM) const;
|
||||
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
FrequencyPlanning m_initPlan;
|
||||
FrequencyPlanning m_parentPlan;
|
||||
int32_t m_exerciseId;
|
||||
QMap<int, FrequencySetDataWithId> m_freqSetData; // key = freqSetDataId
|
||||
QMap<int, FrequencyPlanningData> m_frequencyPlanningData; // key = cnrConfigId (radioCircuit)
|
||||
QMap<int, FrequencyPlanning> m_frequencyPlannings; // key = cnrConfigId (radioCircuit)
|
||||
QMap<int, CnrConfig> m_cnrConfigs; // key = cnrConfigId (radioCircuit)
|
||||
QMap<int, CnrConfig> m_existingCnrConfigs;
|
||||
QVector<int> m_multipleAssignedCnrIds;
|
||||
int32_t m_frequencySetId;
|
||||
QSet<int> m_result;
|
||||
QMap<int32_t, Qt::CheckState> m_checkStates; //<row, checkstate>
|
||||
QMap<int32_t, Conflict> m_conflicts; //<row, Conflict>
|
||||
QSet<int> m_ownTakenFrequencySetDataIds;
|
||||
QMap<int32_t, QVector<int32_t>> m_unassignmentsPerRow; //<row, cnrConfigIds>
|
||||
|
||||
LOGGER_T m_logger;
|
||||
}; // class LoadFrequencyPlanningDialogModelB
|
||||
} // namespace AudioVideoManagement
|
||||
|
||||
Q_DECLARE_METATYPE(AudioVideoManagement::LoadFrequencyPlanningDialogModel::ItemData)
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* This widget is a setter/getter widget for specific values fro programming HF radios.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Malte Diers, SLTE, 2023-10-19
|
||||
*/
|
||||
|
||||
|
||||
#include "avm_radio_specifica_hf_widget.h"
|
||||
#include "ui_avm_radio_specifica_hf_widget.h"
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
|
||||
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
RadioSpecificaHfWidget::RadioSpecificaHfWidget(QWidget *parent)
|
||||
: RadioSpecificaWidget(parent)
|
||||
, m_ui(new Ui::RadioSpecificaHfWidget)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
m_ui->rbMtAm->setEnabled(false);
|
||||
// Modulation Type
|
||||
// Nothing to do yet
|
||||
|
||||
// Channel Spacing
|
||||
m_ui->cobChannelSpacing->addItem(toString(ChannelSpacingHF_def::CS_100_Hz), ChannelSpacingHF_def::CS_100_Hz);
|
||||
|
||||
|
||||
// Frequency
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
QVariant var = ps->value(QStringLiteral("avm"), QStringLiteral("hfRanges"));
|
||||
m_ranges = initFrequency(QJsonDocument::fromJson(var.toByteArray()).object(), m_ui->sbFrequency);
|
||||
connect(m_ui->sbFrequency, qOverload<int>(&QSpinBox::valueChanged),
|
||||
this, &RadioSpecificaHfWidget::onFrequencyValueChanged);
|
||||
m_ui->sbFrequency->setSingleStep(100);
|
||||
|
||||
// Squelch
|
||||
connect(m_ui->chbSquelch, &QCheckBox::toggled, m_ui->sbSquelch, &QSpinBox::setEnabled);
|
||||
connect(m_ui->chbSquelch, &QCheckBox::toggled, this, &RadioSpecificaHfWidget::squelchStateChanged);
|
||||
m_ui->chbSquelch->setChecked(false);
|
||||
m_ui->sbSquelch->setEnabled(false);
|
||||
m_ui->sbSquelch->setRange(RadioCircuitHF::SQUELCH_MIN, RadioCircuitHF::SQUELCH_MAX);
|
||||
squelchStateChanged();
|
||||
|
||||
}
|
||||
|
||||
bool RadioSpecificaHfWidget::setValues(RadioCircuit *rc)
|
||||
{
|
||||
RadioCircuitHF* spec = dynamic_cast<RadioCircuitHF*>(rc);
|
||||
if (!spec)
|
||||
return true;
|
||||
|
||||
bool succ = true;
|
||||
// Modulation Type
|
||||
// Nothing to do yet...
|
||||
|
||||
// Channel Spacing
|
||||
int idx = m_ui->cobChannelSpacing->findData(static_cast<int>(spec->channelSpacing.underlying()));
|
||||
m_ui->cobChannelSpacing->setCurrentIndex(idx);
|
||||
succ &= (idx >= 0);
|
||||
|
||||
// Frequency
|
||||
m_ui->sbFrequency->setValue(spec->frequency);
|
||||
succ &= (m_ui->sbFrequency->value() == spec->frequency);
|
||||
|
||||
// Squelch
|
||||
if (spec->squelch > 0)
|
||||
{
|
||||
m_ui->sbSquelch->setValue(spec->squelch);
|
||||
m_ui->chbSquelch->setChecked(true);
|
||||
}
|
||||
else
|
||||
squelchStateChanged();
|
||||
succ &= (spec->squelch == 0 || m_ui->sbSquelch->value() == spec->squelch);
|
||||
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
bool RadioSpecificaHfWidget::setValues(const QJsonObject &json)
|
||||
{
|
||||
RadioCircuitHF* spec = RadioCircuitHF::fromJson(json);
|
||||
if (!spec->isValid())
|
||||
return false;
|
||||
|
||||
bool succ = setValues(spec);
|
||||
delete spec;
|
||||
return succ;
|
||||
}
|
||||
|
||||
RadioCircuitHF RadioSpecificaHfWidget::values() const
|
||||
{
|
||||
RadioCircuitHF spec;
|
||||
spec.modulationType = ModulationType::AM;
|
||||
spec.channelSpacing = static_cast<ChannelSpacingHF::inner_enum>(m_ui->cobChannelSpacing->currentData().toInt());
|
||||
spec.frequency = m_ui->sbFrequency->value();
|
||||
spec.squelch = m_ui->chbSquelch->isChecked() ? m_ui->sbSquelch->value() : 0;
|
||||
return spec;
|
||||
}
|
||||
|
||||
QJsonObject RadioSpecificaHfWidget::toJson() const
|
||||
{
|
||||
return values().toJson();
|
||||
}
|
||||
|
||||
bool RadioSpecificaHfWidget::isFreqValid() const
|
||||
{
|
||||
for (const auto &range : qAsConst(m_ranges))
|
||||
if(m_ui->sbFrequency->value() >= range.first && m_ui->sbFrequency->value() <= range.second)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<QPair<QLabel *, const std::function<bool ()> > > RadioSpecificaHfWidget::requirements() const
|
||||
{
|
||||
return {{m_ui->lbxFrequency, std::bind(&RadioSpecificaHfWidget::isFreqValid, this)}};
|
||||
}
|
||||
|
||||
RadioSpecificaHfWidget::~RadioSpecificaHfWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void RadioSpecificaHfWidget::squelchStateChanged()
|
||||
{
|
||||
|
||||
if(m_ui->chbSquelch->checkState() == Qt::Unchecked )
|
||||
{
|
||||
m_ui->sbSquelch->setValue(m_ui->sbSquelch->minimum());
|
||||
m_ui->sbSquelch->setSpecialValueText(QStringLiteral("--"));
|
||||
}
|
||||
else
|
||||
m_ui->sbSquelch->setSpecialValueText({});
|
||||
}
|
||||
|
||||
void RadioSpecificaHfWidget::onFrequencyValueChanged(int value)
|
||||
{
|
||||
const int stepSize = 100;
|
||||
const int modRest = value % stepSize;
|
||||
|
||||
if (modRest == 0)
|
||||
return;
|
||||
|
||||
int newValue = 0;
|
||||
|
||||
if (value < m_ui->sbFrequency->minimum())
|
||||
newValue = m_ui->sbFrequency->minimum();
|
||||
else if (value > m_ui->sbFrequency->maximum())
|
||||
newValue = m_ui->sbFrequency->maximum();
|
||||
else
|
||||
newValue = modRest < stepSize / 2 ? value - modRest : value + stepSize - modRest;
|
||||
|
||||
QSignalBlocker(m_ui->sbFrequency);
|
||||
|
||||
m_ui->sbFrequency->setValue(newValue);
|
||||
}
|
||||
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* This widget is a setter/getter widget for specific values fro programming HF radios.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Malte Diers, SLTE, 2023-10-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include "avm_radio_specifica_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class RadioSpecificaHfWidget;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class RadioSpecificaHfWidget : public RadioSpecificaWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RadioSpecificaHfWidget(QWidget *parent = nullptr);
|
||||
~RadioSpecificaHfWidget();
|
||||
|
||||
RadioCircuitHF values() const;
|
||||
QJsonObject toJson() const override;
|
||||
|
||||
QVector< QPair<QLabel*, const std::function<bool()> > > requirements() const override;
|
||||
|
||||
public slots:
|
||||
bool setValues(RadioCircuit *rc) override;
|
||||
bool setValues(const QJsonObject &json) override;
|
||||
|
||||
private slots:
|
||||
void squelchStateChanged();
|
||||
void onFrequencyValueChanged(int value);
|
||||
|
||||
private:
|
||||
bool isFreqValid() const;
|
||||
|
||||
private:
|
||||
Ui::RadioSpecificaHfWidget *m_ui;
|
||||
QVector<QPair<int,int>> m_ranges;
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RadioSpecificaHfWidget</class>
|
||||
<widget class="QWidget" name="RadioSpecificaHfWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>404</width>
|
||||
<height>168</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxModulationType">
|
||||
<property name="text">
|
||||
<string>Modulation Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="hlModulationType">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbMtAm">
|
||||
<property name="text">
|
||||
<string>AM</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxChannelSpacing">
|
||||
<property name="text">
|
||||
<string>Channel Spacing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cobChannelSpacing"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxFrequency">
|
||||
<property name="text">
|
||||
<string>Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxSquelch">
|
||||
<property name="text">
|
||||
<string>Squelch:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="hlSquelch">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chbSquelch">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sbSquelch">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="sbFrequency">
|
||||
<property name="suffix">
|
||||
<string> Hz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* This widget is a setter/getter widget for specific values fro programming HF radios.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Malte Diers, SLTE, 2023-10-19
|
||||
*/
|
||||
|
||||
|
||||
#include "avm_radio_specifica_uhf_widget.h"
|
||||
#include "ui_avm_radio_specifica_uhf_widget.h"
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <QButtonGroup>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
RadioSpecificaUhfWidget::RadioSpecificaUhfWidget(QWidget *parent)
|
||||
: RadioSpecificaWidget(parent)
|
||||
, m_ui(new Ui::RadioSpecificaUhfWidget)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
// Modulation Type
|
||||
m_ui->rbMtAm->setProperty("myIcon", QStringLiteral(":/style/AM.svg"));
|
||||
m_ui->rbMtAm->setProperty("enum", ModulationType::AM);
|
||||
m_ui->rbMtFm->setProperty("myIcon", QStringLiteral(":/style/FM.svg"));
|
||||
m_ui->rbMtFm->setProperty("enum", ModulationType::FM);
|
||||
|
||||
m_ui->rbMtAm->setChecked(true);
|
||||
connect(m_ui->bgModulationType, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), this, [this](QAbstractButton *btn, bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
m_ui->lblModulationType->setText(IMG_HEADER.arg(btn->property("myIcon").toString()));
|
||||
});
|
||||
m_ui->rbMtFm->setChecked(true);
|
||||
|
||||
|
||||
// Channel Spacing
|
||||
m_ui->cobChannelSpacing->addItem(toString(ChannelSpacing_def::CS_25_00_kHz), ChannelSpacing_def::CS_25_00_kHz);
|
||||
m_ui->cobChannelSpacing->addItem(toString(ChannelSpacing_def::CS_12_50_kHz), ChannelSpacing_def::CS_12_50_kHz);
|
||||
m_ui->cobChannelSpacing->addItem(toString(ChannelSpacing_def::CS_8_33_kHz), ChannelSpacing_def::CS_8_33_kHz);
|
||||
|
||||
// Frequency
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
QVariant var = ps->value(QStringLiteral("avm"), QStringLiteral("uhfRanges"));
|
||||
m_ranges = initFrequency(QJsonDocument::fromJson(var.toByteArray()).object(), m_ui->sbFrequency);
|
||||
|
||||
// Squelch
|
||||
connect(m_ui->chbSquelch, &QCheckBox::toggled, m_ui->sbSquelch, &QSpinBox::setEnabled);
|
||||
connect(m_ui->chbSquelch, &QCheckBox::toggled, this, &RadioSpecificaUhfWidget::squelchStateChanged);
|
||||
m_ui->chbSquelch->setChecked(false);
|
||||
m_ui->sbSquelch->setEnabled(false);
|
||||
m_ui->sbSquelch->setRange(RadioCircuitUHF::SQUELCH_MIN, RadioCircuitUHF::SQUELCH_MAX);
|
||||
squelchStateChanged();
|
||||
|
||||
// Clipper
|
||||
m_ui->rbClipperOn->setProperty("myIcon", QStringLiteral(":/style/clipper-on.svg"));
|
||||
m_ui->rbClipperOff->setProperty("myIcon", QStringLiteral(":/style/clipper-off.svg"));
|
||||
m_ui->rbClipperOn->setChecked(true);
|
||||
connect(m_ui->bgClipper, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), this, [this](QAbstractButton *btn, bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
m_ui->lblClipper->setText(IMG_HEADER.arg(btn->property("myIcon").toString()));
|
||||
});
|
||||
m_ui->rbClipperOff->setChecked(true);
|
||||
|
||||
// AGC
|
||||
m_ui->rbAgcOn->setProperty("myIcon", QStringLiteral(":/style/agc-on.svg"));
|
||||
m_ui->rbAgcOff->setProperty("myIcon", QStringLiteral(":/style/agc-off.svg"));
|
||||
m_ui->rbAgcOn->setChecked(true);
|
||||
connect(m_ui->bgAgc, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), this, [this](QAbstractButton *btn, bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
m_ui->lblAgc->setText(IMG_HEADER.arg(btn->property("myIcon").toString()));
|
||||
});
|
||||
m_ui->rbAgcOff->setChecked(true);
|
||||
}
|
||||
|
||||
bool RadioSpecificaUhfWidget::setValues(RadioCircuit* rc)
|
||||
{
|
||||
RadioCircuitUHF* spec = dynamic_cast<RadioCircuitUHF*>(rc);
|
||||
if (!spec)
|
||||
return true;
|
||||
|
||||
bool succ = true;
|
||||
// Modulation Type
|
||||
switch(spec->modulationType.underlying())
|
||||
{
|
||||
case ModulationType::FM:
|
||||
m_ui->rbMtFm->setChecked(true);
|
||||
break;
|
||||
case ModulationType::AM:
|
||||
m_ui->rbMtAm->setChecked(true);
|
||||
break;
|
||||
default: // No enumerated value? No good!
|
||||
m_ui->rbMtFm->setChecked(true);
|
||||
succ &= false;
|
||||
}
|
||||
|
||||
// Channel Spacing
|
||||
int idx = m_ui->cobChannelSpacing->findData(static_cast<int>(spec->channelSpacing.underlying()));
|
||||
m_ui->cobChannelSpacing->setCurrentIndex(idx);
|
||||
succ &= (idx >= 0);
|
||||
|
||||
// Frequency
|
||||
m_ui->sbFrequency->setValue(spec->frequency / 1000);
|
||||
succ &= (m_ui->sbFrequency->value() == spec->frequency / 1000);
|
||||
|
||||
// Squelch
|
||||
if (spec->squelchDB > 0)
|
||||
{
|
||||
m_ui->sbSquelch->setValue(spec->squelchDB);
|
||||
m_ui->chbSquelch->setChecked(true);
|
||||
}
|
||||
else
|
||||
squelchStateChanged();
|
||||
succ &= (spec->squelchDB == 0 || m_ui->sbSquelch->value() == spec->squelchDB);
|
||||
|
||||
|
||||
// Clipper
|
||||
if (spec->clipper)
|
||||
m_ui->rbClipperOn->setChecked(true);
|
||||
else
|
||||
m_ui->rbClipperOff->setChecked(true);
|
||||
|
||||
// AGC
|
||||
if (spec->agc)
|
||||
m_ui->rbAgcOn->setChecked(true);
|
||||
else
|
||||
m_ui->rbAgcOff->setChecked(true);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
bool RadioSpecificaUhfWidget::setValues(const QJsonObject &obj)
|
||||
{
|
||||
RadioCircuitUHF *spec = RadioCircuitUHF::fromJson(obj);
|
||||
if (!spec->isValid())
|
||||
return false;
|
||||
|
||||
bool succ = setValues(spec);
|
||||
delete spec;
|
||||
return succ;
|
||||
}
|
||||
|
||||
RadioCircuitUHF RadioSpecificaUhfWidget::values() const
|
||||
{
|
||||
RadioCircuitUHF spec; // Not looking nice, but can easily be extended if mor MTs are present...
|
||||
|
||||
spec.modulationType = static_cast<ModulationType::inner_enum>(m_ui->bgModulationType->checkedButton()->property("enum").toInt());
|
||||
spec.channelSpacing = static_cast<ChannelSpacing::inner_enum>(m_ui->cobChannelSpacing->currentData().toInt());
|
||||
spec.frequency = m_ui->sbFrequency->value() * 1000;
|
||||
spec.squelchDB = m_ui->chbSquelch->isChecked() ? m_ui->sbSquelch->value() : 0;
|
||||
spec.clipper = m_ui->rbClipperOn->isChecked();
|
||||
spec.agc = m_ui->rbAgcOn->isChecked();
|
||||
return spec;
|
||||
}
|
||||
|
||||
QJsonObject RadioSpecificaUhfWidget::toJson() const
|
||||
{
|
||||
return values().toJson();
|
||||
}
|
||||
|
||||
bool RadioSpecificaUhfWidget::isFreqValid() const
|
||||
{
|
||||
for (const auto &range : qAsConst(m_ranges))
|
||||
if(m_ui->sbFrequency->value() >= range.first && m_ui->sbFrequency->value() <= range.second)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
QVector<QPair<QLabel *, const std::function<bool ()> > > RadioSpecificaUhfWidget::requirements() const
|
||||
{
|
||||
return {{m_ui->lbxFrequency, std::bind(&RadioSpecificaUhfWidget::isFreqValid, this)}};
|
||||
}
|
||||
|
||||
RadioSpecificaUhfWidget::~RadioSpecificaUhfWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void RadioSpecificaUhfWidget::squelchStateChanged()
|
||||
{
|
||||
if(m_ui->chbSquelch->checkState() == Qt::Unchecked )
|
||||
{
|
||||
m_ui->sbSquelch->setValue(m_ui->sbSquelch->minimum());
|
||||
m_ui->sbSquelch->setSpecialValueText(QStringLiteral("--"));
|
||||
}
|
||||
else
|
||||
m_ui->sbSquelch->setSpecialValueText({});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* This widget is a setter/getter widget for specific values fro programming HF radios.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Malte Diers, SLTE, 2023-10-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include "avm_radio_specifica_widget.h"
|
||||
|
||||
namespace Ui {
|
||||
class RadioSpecificaUhfWidget;
|
||||
}
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class RadioSpecificaUhfWidget : public RadioSpecificaWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RadioSpecificaUhfWidget(QWidget *parent = nullptr);
|
||||
~RadioSpecificaUhfWidget();
|
||||
|
||||
RadioCircuitUHF values() const;
|
||||
QJsonObject toJson() const override;
|
||||
|
||||
QVector< QPair<QLabel*, const std::function<bool()> > > requirements() const override;
|
||||
|
||||
public slots:
|
||||
bool setValues(RadioCircuit *rc) override;
|
||||
bool setValues(const QJsonObject &obj) override;
|
||||
|
||||
private slots:
|
||||
void squelchStateChanged();
|
||||
|
||||
private:
|
||||
bool isFreqValid() const;
|
||||
|
||||
private:
|
||||
|
||||
Ui::RadioSpecificaUhfWidget *m_ui;
|
||||
QVector<QPair<int,int>> m_ranges;
|
||||
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+281
@@ -0,0 +1,281 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RadioSpecificaUhfWidget</class>
|
||||
<widget class="QWidget" name="RadioSpecificaUhfWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>345</width>
|
||||
<height>254</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxModulationType">
|
||||
<property name="text">
|
||||
<string>Modulation Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="hlModulationType">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbMtAm">
|
||||
<property name="text">
|
||||
<string>AM</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme=":/style/AM.svg">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgModulationType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbMtFm">
|
||||
<property name="text">
|
||||
<string>FM</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset theme=":/style/FM.svg">
|
||||
<normaloff>.</normaloff>.</iconset>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgModulationType</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblModulationType">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>[ICON]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbxChannelSpacing">
|
||||
<property name="text">
|
||||
<string>Channel Spacing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cobChannelSpacing"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxFrequency">
|
||||
<property name="text">
|
||||
<string>Frequency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxSquelch">
|
||||
<property name="text">
|
||||
<string>Squelch:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="hlSquelch">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chbSquelch">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="sbSquelch">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> dB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lbxClipper">
|
||||
<property name="text">
|
||||
<string>Clipper:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<layout class="QHBoxLayout" name="hlClipper">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbClipperOff">
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgClipper</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbClipperOn">
|
||||
<property name="text">
|
||||
<string>On</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgClipper</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblClipper">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>[ICON]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lbxAgc">
|
||||
<property name="text">
|
||||
<string>AGC:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<layout class="QHBoxLayout" name="hlAgc">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbAgcOff">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>4</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>4</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgAgc</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbAgcOn">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>4</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>On</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgAgc</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblAgc">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>[ICON]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSpinBox" name="sbFrequency">
|
||||
<property name="suffix">
|
||||
<string> kHz</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>rbMtAm</tabstop>
|
||||
<tabstop>rbMtFm</tabstop>
|
||||
<tabstop>cobChannelSpacing</tabstop>
|
||||
<tabstop>chbSquelch</tabstop>
|
||||
<tabstop>sbSquelch</tabstop>
|
||||
<tabstop>rbClipperOff</tabstop>
|
||||
<tabstop>rbAgcOff</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="bgModulationType"/>
|
||||
<buttongroup name="bgClipper"/>
|
||||
<buttongroup name="bgAgc"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
+196
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* This widget is a setter/getter widget for specific values fro programming HF radios.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Malte Diers, SLTE, 2023-10-19
|
||||
*/
|
||||
|
||||
#include "avm_edit_frequency_planning_set_resource_dialog.h"
|
||||
#include "avm_radio_specifica_vhf_widget.h"
|
||||
#include "ui_avm_radio_specifica_vhf_widget.h"
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <AudioVideoManagement/avm_enums.hpp>
|
||||
#include <AudioVideoManagement/avm_translation.h>
|
||||
#include <AudioVideoManagement/avm_dtc.h>
|
||||
#include <QButtonGroup>
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
RadioSpecificaVhfWidget::RadioSpecificaVhfWidget(QSet<int> &assignedFrequencySetDataIds, QWidget *parent)
|
||||
: RadioSpecificaWidget(parent)
|
||||
, m_ui(new Ui::RadioSpecificaVhfWidget)
|
||||
, m_assignedFrequencySetDataIds(assignedFrequencySetDataIds)
|
||||
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
// Operating Mode
|
||||
m_ui->cobOperatingMode->addItem(toString(RcOperatingMode_def::FixedFreqEncNone), RcOperatingMode_def::FixedFreqEncNone);
|
||||
m_ui->cobOperatingMode->addItem(toString(RcOperatingMode_def::FixedFreqEncHwKr), RcOperatingMode_def::FixedFreqEncHwKr);
|
||||
m_ui->cobOperatingMode->addItem(toString(RcOperatingMode_def::FixedFreqEncHwKrKl), RcOperatingMode_def::FixedFreqEncHwKrKl);
|
||||
m_ui->cobOperatingMode->addItem(toString(RcOperatingMode_def::AkwEncNone), RcOperatingMode_def::AkwEncNone);
|
||||
m_ui->cobOperatingMode->addItem(toString(RcOperatingMode_def::AkwEncEccm), RcOperatingMode_def::AkwEncEccm);
|
||||
|
||||
// Frequency Set
|
||||
m_ui->leFrequencySet->setEnabled(false);
|
||||
|
||||
connect(m_ui->tbFrequencySet, &QToolButton::clicked, this, &RadioSpecificaVhfWidget::onSelectFrequencySetData);
|
||||
connect(m_ui->cobOperatingMode, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &RadioSpecificaVhfWidget::onOperatingModeChanged);
|
||||
|
||||
// Pilot Tone
|
||||
m_ui->rbPilotToneOn->setProperty("myIcon", QStringLiteral(":/style/pilotton-on.svg"));
|
||||
m_ui->rbPilotToneOff->setProperty("myIcon", QStringLiteral(":/style/pilotton-off.svg"));
|
||||
m_ui->rbPilotToneOn->setChecked(true);
|
||||
connect(m_ui->bgPilotTone, QOverload<QAbstractButton *, bool>::of(&QButtonGroup::buttonToggled), this, [this](QAbstractButton *btn, bool checked)
|
||||
{
|
||||
if (!checked)
|
||||
return;
|
||||
m_ui->lblPilotTone->setText(IMG_HEADER.arg(btn->property("myIcon").toString()));
|
||||
});
|
||||
m_ui->rbPilotToneOff->setChecked(true);
|
||||
|
||||
}
|
||||
|
||||
bool RadioSpecificaVhfWidget::init(const int &frequencySetId, const std::shared_ptr<Interface::Dtc> &avmDtc, const int &cnrConfigId)
|
||||
{
|
||||
m_avmDtc = avmDtc;
|
||||
m_frequencySetId = frequencySetId;
|
||||
m_cnrConfigId = cnrConfigId;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RadioSpecificaVhfWidget::setFrequencySetData(int frequencySetDataId)
|
||||
{
|
||||
m_frequencySetDataId = frequencySetDataId;
|
||||
m_ui->leFrequencySet->clear();
|
||||
bool found = false;
|
||||
std::vector<FrequencySetDataWithId> dataVec = m_avmDtc->frequencySet(m_frequencySetId).data();
|
||||
for (const auto &it : dataVec)
|
||||
{
|
||||
if(it.id() == m_frequencySetDataId)
|
||||
{
|
||||
m_ui->leFrequencySet->setText(QString::fromStdString(it.function()));
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
bool RadioSpecificaVhfWidget::setValues(RadioCircuit* rc)
|
||||
{
|
||||
RadioCircuitVHF* spec = dynamic_cast<RadioCircuitVHF*>(rc);
|
||||
if (!spec)
|
||||
return true;
|
||||
|
||||
bool succ = true;
|
||||
// Operating Mode
|
||||
m_operatingMode = spec->operatingMode;
|
||||
int idx = m_ui->cobOperatingMode->findData(static_cast<int>(spec->operatingMode.underlying()));
|
||||
m_ui->cobOperatingMode->setCurrentIndex(idx);
|
||||
succ &= (idx >= 0);
|
||||
|
||||
// Frequency Set
|
||||
succ &= setFrequencySetData(spec->freqSetDataId);
|
||||
|
||||
// Pilot Tone
|
||||
if (spec->pilotTone)
|
||||
m_ui->rbPilotToneOn->setChecked(true);
|
||||
else
|
||||
m_ui->rbPilotToneOff->setChecked(true);
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
bool RadioSpecificaVhfWidget::setValues(const QJsonObject &json)
|
||||
{
|
||||
RadioCircuitVHF *spec = RadioCircuitVHF::fromJson(json);
|
||||
|
||||
if (!spec->isValid())
|
||||
return false;
|
||||
|
||||
bool succ = setValues(spec);
|
||||
delete spec;
|
||||
return succ;
|
||||
}
|
||||
|
||||
RadioCircuitVHF RadioSpecificaVhfWidget::values() const
|
||||
{
|
||||
RadioCircuitVHF spec;
|
||||
spec.operatingMode = static_cast<RcOperatingMode::inner_enum>(m_ui->cobOperatingMode->currentData().toInt());
|
||||
spec.freqSetDataId = m_frequencySetDataId;
|
||||
spec.pilotTone = isAkwMode(spec.operatingMode) ? false : m_ui->rbPilotToneOn->isChecked();
|
||||
return spec;
|
||||
}
|
||||
|
||||
QJsonObject RadioSpecificaVhfWidget::toJson() const
|
||||
{
|
||||
return values().toJson();
|
||||
}
|
||||
|
||||
bool RadioSpecificaVhfWidget::isFreqSetValid() const
|
||||
{
|
||||
return m_frequencySetDataId > 0;
|
||||
}
|
||||
|
||||
QVector<QPair<QLabel *, const std::function<bool ()> > > RadioSpecificaVhfWidget::requirements() const
|
||||
{
|
||||
return {{m_ui->lbxFrequencySet, std::bind(&RadioSpecificaVhfWidget::isFreqSetValid, this)}};
|
||||
}
|
||||
|
||||
RadioSpecificaVhfWidget::~RadioSpecificaVhfWidget()
|
||||
{
|
||||
m_ui->lbxFrequencySet ->deleteLater();
|
||||
m_ui->lbxFrequencySet = nullptr;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void RadioSpecificaVhfWidget::onSelectFrequencySetData()
|
||||
{
|
||||
RadioCircuitVHF current = values();
|
||||
|
||||
EditFrequencyPlanningSetResourceDialog *dlg = new EditFrequencyPlanningSetResourceDialog(m_assignedFrequencySetDataIds,
|
||||
current.operatingMode,
|
||||
m_frequencySetId,
|
||||
m_cnrConfigId,
|
||||
m_avmDtc,
|
||||
this);
|
||||
|
||||
connect(dlg, &EditFrequencyPlanningSetResourceDialog::onSelectedFrequencySet,
|
||||
this, &RadioSpecificaVhfWidget::onFrequencySetData);
|
||||
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
void RadioSpecificaVhfWidget::onOperatingModeChanged()
|
||||
{
|
||||
RcOperatingMode rcMode = static_cast<RcOperatingMode::inner_enum>(m_ui->cobOperatingMode->currentData().toInt());
|
||||
const bool enablePilotTone = !isAkwMode(rcMode);
|
||||
m_ui->lbxPilotTone->setEnabled(enablePilotTone);
|
||||
m_ui->rbPilotToneOn->setEnabled(enablePilotTone);
|
||||
m_ui->rbPilotToneOff->setEnabled(enablePilotTone);
|
||||
|
||||
if (!enablePilotTone)
|
||||
m_ui->rbPilotToneOff->setChecked(true);
|
||||
|
||||
if(isAkwMode(m_operatingMode) != isAkwMode(rcMode))
|
||||
onFrequencySetData(0);
|
||||
|
||||
m_operatingMode = rcMode;
|
||||
}
|
||||
|
||||
void RadioSpecificaVhfWidget::onFrequencySetData(int selectedFrequencySetDataId)
|
||||
{
|
||||
if(m_frequencySetDataId == selectedFrequencySetDataId)
|
||||
return;
|
||||
|
||||
m_assignedFrequencySetDataIds.remove(m_frequencySetDataId);
|
||||
m_assignedFrequencySetDataIds.insert(selectedFrequencySetDataId);
|
||||
setFrequencySetData(selectedFrequencySetDataId);
|
||||
}
|
||||
}//namespace
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* This widget is a setter/getter widget for specific values fro programming HF radios.
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Malte Diers, SLTE, 2023-10-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <Proxies/CombatNetRadio/Helper/cnr_frequency_planning_helper.h>
|
||||
#include "avm_radio_specifica_widget.h"
|
||||
|
||||
|
||||
#include <AudioVideoManagement/avm.hpp>
|
||||
|
||||
class QLabel;
|
||||
|
||||
namespace Ui {
|
||||
class RadioSpecificaVhfWidget;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class RadioSpecificaVhfWidget : public RadioSpecificaWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RadioSpecificaVhfWidget(QSet<int> &assignedFrequencySetDataIds, QWidget *parent = nullptr);
|
||||
~RadioSpecificaVhfWidget();
|
||||
|
||||
bool init(const int &frequencySetId, const std::shared_ptr<Interface::Dtc> &avmDtc, const int &cnrConfigId);
|
||||
|
||||
RadioCircuitVHF values() const;
|
||||
QJsonObject toJson() const override;
|
||||
QVector< QPair<QLabel*, const std::function<bool()> > > requirements() const override;
|
||||
|
||||
public slots:
|
||||
bool setValues(RadioCircuit *rc) override;
|
||||
bool setValues(const QJsonObject &json) override;
|
||||
|
||||
private slots:
|
||||
void onSelectFrequencySetData();
|
||||
void onFrequencySetData(int selectedFrequencySetDataId);
|
||||
void onOperatingModeChanged();
|
||||
|
||||
private:
|
||||
bool setFrequencySetData(int frequencySetDataId);
|
||||
bool isFreqSetValid() const;
|
||||
|
||||
Ui::RadioSpecificaVhfWidget *m_ui;
|
||||
int m_frequencySetDataId {0};
|
||||
int m_frequencySetId {0};
|
||||
int m_cnrConfigId{0};
|
||||
RcOperatingMode m_operatingMode;
|
||||
std::shared_ptr<Interface::Dtc> m_avmDtc;
|
||||
QSet<int> &m_assignedFrequencySetDataIds;
|
||||
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>RadioSpecificaVhfWidget</class>
|
||||
<widget class="QWidget" name="RadioSpecificaVhfWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>334</width>
|
||||
<height>178</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="hlFrequencySet">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="leFrequencySet"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="tbFrequencySet">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbxOperatingMode">
|
||||
<property name="text">
|
||||
<string>Operating Mode:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbxPilotTone">
|
||||
<property name="text">
|
||||
<string>Pilot Tone:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cobOperatingMode"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbxFrequencySet">
|
||||
<property name="text">
|
||||
<string>Function:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="hlPilotTone">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbPilotToneOff">
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgPilotTone</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="rbPilotToneOn">
|
||||
<property name="text">
|
||||
<string>On</string>
|
||||
</property>
|
||||
<attribute name="buttonGroup">
|
||||
<string notr="true">bgPilotTone</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lblPilotTone">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>[ICON]</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<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>
|
||||
<tabstops>
|
||||
<tabstop>cobOperatingMode</tabstop>
|
||||
<tabstop>leFrequencySet</tabstop>
|
||||
<tabstop>tbFrequencySet</tabstop>
|
||||
<tabstop>rbPilotToneOn</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
<buttongroups>
|
||||
<buttongroup name="bgPilotTone"/>
|
||||
</buttongroups>
|
||||
</ui>
|
||||
Lts/Plugins/AudioVideoManagement/Gui/CombatNetRadio/FrequencyPlanning/avm_radio_specifica_widget.cpp
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#include "avm_radio_specifica_widget.h"
|
||||
|
||||
#include <QSpinBox>
|
||||
#include <QJsonArray>
|
||||
namespace AudioVideoManagement {
|
||||
|
||||
RadioSpecificaWidget::RadioSpecificaWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVector<QPair<int,int>> RadioSpecificaWidget::initFrequency(const QJsonObject &obj, QSpinBox *sb)
|
||||
{
|
||||
const QJsonArray arr = obj.value(QStringLiteral("Ranges")).toArray();
|
||||
|
||||
QVector<QPair<int,int>> ranges;
|
||||
QStringList rangeStrings;
|
||||
|
||||
ranges.reserve(arr.size());
|
||||
rangeStrings.reserve(ranges.size());
|
||||
|
||||
int min = INT_MAX;
|
||||
int max = 0;
|
||||
for (const auto &item : arr)
|
||||
{
|
||||
const QJsonObject obj = item.toObject();
|
||||
int currentMin = obj.value(QStringLiteral("min")).toInt();
|
||||
int currentMax = obj.value(QStringLiteral("max")).toInt();
|
||||
ranges.push_back({currentMin, currentMax});
|
||||
if (currentMax > max)
|
||||
max = currentMax;
|
||||
if (currentMin < min)
|
||||
min = currentMin;
|
||||
rangeStrings << tr("%1-%2%3").arg(currentMin).arg(currentMax).arg(sb->suffix());
|
||||
}
|
||||
sb->setSingleStep(25);
|
||||
sb->setRange(min, max);
|
||||
sb->setToolTip(tr("Ranges:\n%1").arg(rangeStrings.join(QStringLiteral(",\n"))));
|
||||
return ranges;
|
||||
}
|
||||
|
||||
}//namespace
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <QJsonObject>
|
||||
#include <functional>
|
||||
|
||||
class QLabel;
|
||||
class QSpinBox;
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
struct RadioCircuit;
|
||||
|
||||
class RadioSpecificaWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RadioSpecificaWidget(QWidget *parent);
|
||||
|
||||
virtual QJsonObject toJson() const = 0;
|
||||
|
||||
virtual QVector< QPair<QLabel*, const std::function<bool()> > > requirements() const = 0;
|
||||
protected:
|
||||
const QString IMG_HEADER = QStringLiteral("<img src=\"%1\" height=\"32\" image-rendering=\"optimizeQuality\">");
|
||||
QVector<QPair<int, int> > initFrequency(const QJsonObject &obj, QSpinBox *sb);
|
||||
|
||||
public slots:
|
||||
virtual bool setValues(const QJsonObject &json) = 0;
|
||||
virtual bool setValues(RadioCircuit *rc) = 0;
|
||||
};
|
||||
} //namespace
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
#include "radiocircuit.h"
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
RadioCircuit::RadioCircuit()
|
||||
{
|
||||
|
||||
}
|
||||
} //namespace
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
class RadioCircuit
|
||||
{
|
||||
public:
|
||||
RadioCircuit();
|
||||
};
|
||||
|
||||
} //namespace
|
||||
Reference in new issue
Block a user