466 lines
17 KiB
C++
Executable File
466 lines
17 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* GUI Plugin for ParticipantManagement - Participant Organisation
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Patric Karwat, SLSE, 2016-10-17
|
|
*/
|
|
|
|
#include "participant_organisation.h"
|
|
#include "ui_participant_organisation.h"
|
|
|
|
#include "participant_unit_namer.h"
|
|
|
|
#include <Plugins/ParticipantManagement/Gui/ParticipantTemplates/participant_template_chooser_model.h>
|
|
#include <Plugins/ParticipantManagement/ppm_mime_datas.h>
|
|
|
|
#include <QMenu>
|
|
#include <QPainter>
|
|
#include <QRect>
|
|
#include <QMouseEvent>
|
|
#include <LtsWidgets/lts_message_dialog.h>
|
|
#include <LtsUtilsCore/dds_vector.h>
|
|
|
|
namespace ParticipantManagement
|
|
{
|
|
int ParticipantOrganisationDialog::s_preselectedParty = -1;
|
|
|
|
ParticipantOrganisationDialog::ParticipantOrganisationDialog(LtsSession::LtsSession *session,
|
|
bool asSupportService,
|
|
QWidget *parent)
|
|
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::CloseOnly)
|
|
, m_asSupportService(asSupportService)
|
|
, m_poolModel(nullptr)
|
|
, m_proxyModel(nullptr)
|
|
, m_partyModel(nullptr)
|
|
, m_attachedModel(nullptr)
|
|
, m_detachedModel(nullptr)
|
|
, m_cooperateModel(nullptr)
|
|
, m_delegate(nullptr)
|
|
, m_dtc(nullptr)
|
|
, m_ftc(nullptr)
|
|
, m_ppmGuiCbxIfc(nullptr)
|
|
, m_session(session)
|
|
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
|
, m_ui(new Ui::ParticipantOrganisation)
|
|
, m_logger(getLogger("ParticipantOrganisation"))
|
|
{
|
|
m_ui->setupUi(this);
|
|
m_ui->splitter->setStretchFactor(0, 1);
|
|
m_ui->splitter->setStretchFactor(1, 1);
|
|
m_ui->splitter->setStretchFactor(2, 2);
|
|
connect(m_ui->tvParty, &QTreeView::customContextMenuRequested,
|
|
this, &ParticipantOrganisationDialog::showContextMenu);
|
|
connect(m_ui->tvAttached, &QTreeView::customContextMenuRequested,
|
|
this, &ParticipantOrganisationDialog::showContextMenu);
|
|
connect(m_ui->tvDetached, &QTreeView::customContextMenuRequested,
|
|
this, &ParticipantOrganisationDialog::showContextMenu);
|
|
connect(m_ui->tvCooperate, &QTreeView::customContextMenuRequested,
|
|
this, &ParticipantOrganisationDialog::showContextMenu);
|
|
|
|
|
|
if (m_asSupportService)
|
|
setOnlineHelpFilename(QStringLiteral("Situation-Organise_Support_Participants"));
|
|
else
|
|
setOnlineHelpFilename(QStringLiteral("Situation-Organise_Participants"));
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
|
|
ParticipantOrganisationDialog::~ParticipantOrganisationDialog()
|
|
{
|
|
delete m_ui;
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::retranslate()
|
|
{
|
|
QString name;
|
|
if (m_asSupportService)
|
|
name = tr("Organise Support Participants");
|
|
else
|
|
name = tr("Organise Participants");
|
|
|
|
translate(m_ui, name);
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::lock()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
m_ui->cbParty->setEnabled(true); // true !!
|
|
|
|
// avoid BaseClass::lock to be called. PartyEdit stays enabled
|
|
|
|
m_ui->tvParty->setEnabled(false);
|
|
m_ui->tvAttached->setEnabled(false);
|
|
m_ui->tvCooperate->setEnabled(false);
|
|
m_ui->tvDetached->setEnabled(false);
|
|
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::unlock()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
m_ui->cbParty->setEnabled(true);
|
|
|
|
m_ui->tvParty->setEnabled(true);
|
|
m_ui->tvAttached->setEnabled(true);
|
|
m_ui->tvCooperate->setEnabled(true);
|
|
m_ui->tvDetached->setEnabled(true);
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
bool ParticipantOrganisationDialog::init(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtc,
|
|
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ftc,
|
|
const std::shared_ptr<ForeignGuiTemplatesInterface> &ppmGuiTemplateIfc,
|
|
const std::shared_ptr<ForeignGuiComboboxInterface> &ppmGuiCbxIfc,
|
|
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc)
|
|
{
|
|
if (!dtc || !ftc || !ppmGuiCbxIfc)
|
|
return false;
|
|
m_dtc = dtc;
|
|
m_ftc = ftc;
|
|
m_ppmGuiTemplateIfc = ppmGuiTemplateIfc;
|
|
m_ppmGuiCbxIfc = ppmGuiCbxIfc;
|
|
|
|
//templateModel
|
|
m_ppmGuiTemplateIfc->getTemplateModel(m_ui->tvTemplate, m_asSupportService);
|
|
m_ui->tvTemplate->hideColumn(ParticipantTemplateChooserModel::ColTypeClass);
|
|
m_ui->tvTemplate->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
|
|
|
//poolModel
|
|
m_poolModel = new ParticipantPoolModel(this, m_session, m_dtc, m_asSupportService);
|
|
m_ui->tvPool->setModel(m_poolModel);
|
|
m_ui->tvPool->hideColumn(ParticipantPoolModel::ColTypeClass);
|
|
m_ui->tvPool->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
|
connect(m_poolModel, &ParticipantPoolModel::startUnitNamer, this, &ParticipantOrganisationDialog::onStartTemplateUnitNamer);
|
|
connect(m_poolModel, &ParticipantPoolModel::modifyParticipantData, this, &ParticipantOrganisationDialog::onPoolParticipantsChanged);
|
|
m_delegate = new DeleteDelegate(this);
|
|
connect(m_delegate, &DeleteDelegate::removePoolParty, this, &ParticipantOrganisationDialog::onRemovePoolParty);
|
|
m_ui->tvPool->setItemDelegateForColumn(ParticipantPoolModel::ColRemove, m_delegate);
|
|
|
|
if (m_asSupportService)
|
|
{
|
|
m_ui->lblParty->hide();
|
|
m_ui->cbParty->hide();
|
|
m_ui->tvParty->hide();
|
|
m_ui->tvAttached->hide();
|
|
m_ui->tvDetached->hide();
|
|
m_ui->tvCooperate->hide();
|
|
}
|
|
else
|
|
{
|
|
connect(m_ui->cbParty,
|
|
static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
|
|
this,
|
|
&ParticipantOrganisationDialog::onPartyChanged);
|
|
|
|
//PartyModels
|
|
m_partyModel = new ParticipantOrgaModel(ParticipantOrgaModel::PartyOrganisationType::Party,
|
|
m_dtc,
|
|
asbIfc,
|
|
this);
|
|
ParticipantOrgaProxyModel *partyProxy = new ParticipantOrgaProxyModel(this);
|
|
partyProxy->setSourceModel(m_partyModel);
|
|
m_ui->tvParty->setModel(partyProxy);
|
|
|
|
m_attachedModel = new ParticipantOrgaModel(ParticipantOrgaModel::PartyOrganisationType::Attached,
|
|
m_dtc,
|
|
asbIfc,
|
|
this);
|
|
ParticipantOrgaProxyModel *attachProxy = new ParticipantOrgaProxyModel(this);
|
|
attachProxy->setSourceModel(m_attachedModel);
|
|
m_ui->tvAttached->setModel(attachProxy);
|
|
m_detachedModel = new ParticipantOrgaModel(ParticipantOrgaModel::PartyOrganisationType::Detached,
|
|
m_dtc,
|
|
asbIfc,
|
|
this);
|
|
ParticipantOrgaProxyModel *detachProxy = new ParticipantOrgaProxyModel(this);
|
|
detachProxy->setSourceModel(m_detachedModel);
|
|
m_ui->tvDetached->setModel(detachProxy);
|
|
m_cooperateModel = new ParticipantOrgaModel(ParticipantOrgaModel::PartyOrganisationType::Cooperate,
|
|
m_dtc,
|
|
asbIfc,
|
|
this);
|
|
ParticipantOrgaProxyModel *cooperateProxy = new ParticipantOrgaProxyModel(this);
|
|
cooperateProxy->setSourceModel(m_cooperateModel);
|
|
m_ui->tvCooperate->setModel(cooperateProxy);
|
|
|
|
connect(m_partyModel, &ParticipantOrgaModel::participantDataChanged,
|
|
this, &ParticipantOrganisationDialog::onPartyParticipantsChanged);
|
|
connect(m_attachedModel, &ParticipantOrgaModel::participantDataChanged,
|
|
this, &ParticipantOrganisationDialog::onAttachedParticipantsChanged);
|
|
connect(m_detachedModel, &ParticipantOrgaModel::participantDataChanged,
|
|
this, &ParticipantOrganisationDialog::onDetachedParticipantsChanged);
|
|
connect(m_cooperateModel, &ParticipantOrgaModel::participantDataChanged,
|
|
this, &ParticipantOrganisationDialog::onCooperateParticipantsChanged);
|
|
}
|
|
|
|
m_ppmGuiCbxIfc->fillPartyComboBox(m_ui->cbParty);
|
|
const int idx = m_ui->cbParty->findData(s_preselectedParty);
|
|
if (idx >= 0)
|
|
m_ui->cbParty->setCurrentIndex(idx);
|
|
onPartyChanged();
|
|
|
|
return true;
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onModifyParticipantDataReply(const Core::FunctionReplyObject &replyObject)
|
|
{
|
|
m_requestHelper->requestReply(replyObject);
|
|
}
|
|
|
|
//private
|
|
QModelIndex ParticipantOrganisationDialog::selectedIndexView() const
|
|
{
|
|
QItemSelectionModel *selectionModel = m_ui->tvParty->selectionModel();
|
|
QModelIndexList indexL = selectionModel->selectedRows(0);
|
|
if (indexL.size() == 0)
|
|
return QModelIndex();
|
|
|
|
return m_proxyModel->mapToSource(indexL.at(0));
|
|
}
|
|
|
|
bool ParticipantOrganisationDialog::saveParticipantData(const ModifyParticipantDataRequest &request)
|
|
{
|
|
return m_requestHelper->startSingleRequest([this, request]()
|
|
{
|
|
return m_ftc->modifyParticipantDataRequest(request, this);
|
|
});
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onPoolParticipantsChanged(const QVector<ParticipantData> &participants,
|
|
const QString &originatorMimeType)
|
|
{
|
|
if (participants.isEmpty())
|
|
return;
|
|
|
|
ModifyParticipantDataRequest req;
|
|
req.data(LtsUtils::convert<std::vector<ParticipantData>>(participants));
|
|
// move from attached/coperate to pool -> update ParticipantOrganisation
|
|
if (originatorMimeType == ParticipantPartyAttached)
|
|
{
|
|
ParticipantOrganisation orga;
|
|
orga.participantId(participants.first().id());
|
|
orga.currentPartyId(0); // moved to pool
|
|
orga.isAttached(false);
|
|
orga.isCooperate(false);
|
|
req.participantOrganisation(orga);
|
|
}
|
|
|
|
saveParticipantData(req);
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onPartyParticipantsChanged(int addedParticipantId)
|
|
{
|
|
// move from pool/detached -> party was done
|
|
const int curPartyId = m_ui->cbParty->currentData().toInt();
|
|
|
|
const QVector<int> rootParticipantIds = m_partyModel->rootParticipantIds();
|
|
if (rootParticipantIds.isEmpty())
|
|
return;
|
|
bool bMovedFromPool = rootParticipantIds.contains(addedParticipantId);
|
|
|
|
ModifyParticipantDataRequest req;
|
|
if (!bMovedFromPool)
|
|
{
|
|
// search participantOrga with originPartyId = curPartyId, currentPartyId = 0,
|
|
// isAttached/isCooperate = false, participantId = addedParticipantId
|
|
// and remove it
|
|
ParticipantOrganisation orga;
|
|
orga.participantId(addedParticipantId);
|
|
orga.originPartyId(curPartyId);
|
|
orga.currentPartyId(curPartyId); // moved to currentParty
|
|
req.participantOrganisation(orga);
|
|
}
|
|
|
|
const QVector<ParticipantData> participantData = m_partyModel->participantData(curPartyId);
|
|
req.data(LtsUtils::convert<std::vector<ParticipantData>>(participantData));
|
|
|
|
saveParticipantData(req);
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onAttachedParticipantsChanged(int addedParticipantId)
|
|
{
|
|
// a move from pool -> attached was done
|
|
const int curPartyId = m_ui->cbParty->currentData().toInt();
|
|
|
|
// we need to create a new ParticipantOrganisation entry since addedParticipantId was attached to curParty
|
|
ModifyParticipantDataRequest req;
|
|
ParticipantOrganisation orga;
|
|
orga.participantId(addedParticipantId);
|
|
orga.currentPartyId(curPartyId); // moved from pool to curParty
|
|
orga.isAttached(true);
|
|
orga.isCooperate(false);
|
|
req.participantOrganisation(orga);
|
|
|
|
const QVector<ParticipantData> attachedtData = m_attachedModel->participantData(curPartyId); // moved from Pool
|
|
req.data(LtsUtils::convert<std::vector<ParticipantData>>(attachedtData));
|
|
|
|
saveParticipantData(req);
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onDetachedParticipantsChanged(int addedParticipantId)
|
|
{
|
|
// a move from party -> detached was done
|
|
const int curPartyId = m_ui->cbParty->currentData().toInt();
|
|
|
|
// we need to create a new ParticipantOrganisation entry since addedParticipantId was detached from curParty
|
|
ModifyParticipantDataRequest req;
|
|
ParticipantOrganisation orga;
|
|
orga.participantId(addedParticipantId);
|
|
orga.originPartyId(curPartyId);
|
|
orga.currentPartyId(0); // moved from currentParty to pool
|
|
req.participantOrganisation(orga);
|
|
|
|
const QVector<ParticipantData> participantData = m_partyModel->participantData(curPartyId);
|
|
const QVector<ParticipantData> detachedtData = m_detachedModel->participantData(0); // moved to Pool
|
|
req.data(LtsUtils::convert<std::vector<ParticipantData>>(participantData + detachedtData));
|
|
|
|
saveParticipantData(req);
|
|
}
|
|
void ParticipantOrganisationDialog::onCooperateParticipantsChanged(int addedParticipantId)
|
|
{
|
|
// a move from pool -> attached was done
|
|
const int curPartyId = m_ui->cbParty->currentData().toInt();
|
|
|
|
// we need to create a new ParticipantOrganisation entry since addedParticipantId was attached to curParty
|
|
ModifyParticipantDataRequest req;
|
|
ParticipantOrganisation orga;
|
|
orga.participantId(addedParticipantId);
|
|
orga.currentPartyId(curPartyId); // moved from pool to curParty
|
|
orga.isAttached(false);
|
|
orga.isCooperate(true);
|
|
req.participantOrganisation(orga);
|
|
|
|
const QVector<ParticipantData> attachedtData = m_cooperateModel->participantData(curPartyId); // moved from Pool
|
|
req.data(LtsUtils::convert<std::vector<ParticipantData>>(attachedtData));
|
|
|
|
saveParticipantData(req);
|
|
}
|
|
|
|
|
|
|
|
//slots
|
|
void ParticipantOrganisationDialog::onStartTemplateUnitNamer(int templateId)
|
|
{
|
|
const TemplateParticipant tempPart = m_dtc->templateParticipant(templateId);
|
|
//as a framelessdlg it will delete itself
|
|
ParticipantUnitNamer *namer = new ParticipantUnitNamer(QString::fromStdString(tempPart.designator()), QString::fromStdString(tempPart.tacticalIdentifier()), this);
|
|
connect(namer, &ParticipantUnitNamer::newUnitNames, this, [this, templateId](const QString & designator, const QString & tactIdentifer)
|
|
{
|
|
m_poolModel->addNewTemplateToPool(templateId, designator, tactIdentifer);
|
|
});
|
|
namer->show();
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onPartyChanged()
|
|
{
|
|
const int curPartyId = m_ui->cbParty->currentData().toInt();
|
|
s_preselectedParty = curPartyId;
|
|
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, curPartyId" << curPartyId
|
|
<< ", m_asSupportService=" << m_asSupportService;
|
|
// if(!m_asSupportService)
|
|
// {
|
|
// m_ui->cbParty->setEnabled(false); // will be re-enabled with reply (::onLockDataChanged)
|
|
// tryLockTopicNew(QStringLiteral("LockParty"), curPartyId);
|
|
// }
|
|
|
|
|
|
for (auto tv : {m_ui->tvParty, m_ui->tvDetached, m_ui->tvAttached, m_ui->tvCooperate})
|
|
{
|
|
auto model = qobject_cast<ParticipantOrgaProxyModel *>(tv->model());
|
|
if (!model) // e.g. in O/C mode
|
|
continue;
|
|
model->onReinitModel(curPartyId);
|
|
const int colCount = tv->model()->columnCount(QModelIndex());
|
|
tv->expandAll();
|
|
for (int i = 0; i < colCount; ++i)
|
|
tv->resizeColumnToContents(i);
|
|
tv->header()->resizeSection(0, tv->columnWidth(0) + tv->iconSize().width() + 10);
|
|
}
|
|
|
|
//reinit PoolModel if no save on party
|
|
m_poolModel->onReinitModel();
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::onRemovePoolParty()
|
|
{
|
|
const int curIdx = m_ui->tvPool->currentIndex().row();
|
|
if (m_poolModel->canRemoveRow(curIdx))
|
|
m_poolModel->removeRow(curIdx);
|
|
else
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Can not remove unit - is a detached subunit"), tr("Can not remove unit"));
|
|
}
|
|
|
|
void ParticipantOrganisationDialog::showContextMenu(const QPoint &position)
|
|
{
|
|
QTreeView *tv = qobject_cast<QTreeView *>(sender());
|
|
if (!tv)
|
|
return;
|
|
const QModelIndex idx = tv->currentIndex();
|
|
if (!idx.isValid())
|
|
return;
|
|
if (tv->model()->rowCount(idx) == 0)
|
|
return;
|
|
|
|
QMenu menu;
|
|
if (tv->isExpanded(idx))
|
|
{
|
|
QAction *collapseAction = new QAction(tr("Collapse"), &menu);
|
|
connect(collapseAction, &QAction::triggered, this, [tv, idx]() { tv->collapse(idx);});
|
|
menu.addAction(collapseAction);
|
|
}
|
|
else
|
|
{
|
|
QAction *expandAction = new QAction(tr("Expand"), &menu);
|
|
connect(expandAction, &QAction::triggered, this, [tv, idx]() { tv->expand(idx);});
|
|
menu.addAction(expandAction);
|
|
}
|
|
menu.exec(tv->viewport()->mapToGlobal(position));
|
|
}
|
|
|
|
|
|
|
|
//delegate for pool Entries
|
|
DeleteDelegate::DeleteDelegate(QObject *parent)
|
|
: QItemDelegate(parent)
|
|
{
|
|
}
|
|
|
|
void DeleteDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
{
|
|
if (index.column() == ParticipantManagement::ParticipantPoolModel::ColRemove)
|
|
{
|
|
painter->drawImage(option.rect.topLeft(), QImage(QLatin1String("icon:trash-alt.svg")).scaled(option.rect.height(), option.rect.height(),
|
|
Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
|
}
|
|
else
|
|
QItemDelegate::paint(painter, option, index);
|
|
}
|
|
|
|
bool DeleteDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
|
|
{
|
|
if (event->type() != QEvent::MouseButtonRelease)
|
|
return QItemDelegate::editorEvent(event, model, option, index);
|
|
|
|
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
|
QRect imageRect = option.rect;
|
|
imageRect.setWidth(imageRect.height());
|
|
if (mouseEvent && mouseEvent->button() == Qt::MouseButton::LeftButton &&
|
|
imageRect.intersects(QRect(mouseEvent->pos(), mouseEvent->pos())))
|
|
{
|
|
emit removePoolParty();
|
|
return true;
|
|
}
|
|
else
|
|
return QItemDelegate::editorEvent(event, model, option, index);
|
|
}
|
|
|
|
} //namespace ParticipantManagement
|