Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+73
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for MapObjects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2017-04-11
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "map_object_custom_view.h"
|
||||
#include "ui_map_object_custom_view.h"
|
||||
#include "map_object_model.h"
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
// Ot
|
||||
#include <QDataWidgetMapper>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
|
||||
MapObjectCustomView::MapObjectCustomView(QWidget *parent)
|
||||
: BaseClass(parent)
|
||||
, m_ui(new Ui::MapObjectCustomView)
|
||||
, m_mapper(new QDataWidgetMapper(this))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
if (LtsSessionData::LtsSessionData::getInstance()->isTablet())
|
||||
{
|
||||
constexpr auto scaleFactor = 1.4;
|
||||
resize(size() * scaleFactor);
|
||||
m_ui->lbIcon->setMinimumSize(m_ui->lbIcon->minimumSize() * scaleFactor);
|
||||
m_ui->lbIcon->setMaximumSize(m_ui->lbIcon->maximumSize() * scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
MapObjectCustomView::~MapObjectCustomView()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool MapObjectCustomView::init(const QModelIndex &idx)
|
||||
{
|
||||
if (!idx.isValid())
|
||||
return false;
|
||||
|
||||
if (idx.model() != m_mapper->model())
|
||||
{
|
||||
// create mapping;
|
||||
m_mapper->setModel(const_cast<QAbstractItemModel *>(idx.model()));
|
||||
m_mapper->addMapping(m_ui->lbDescription, MapObjectModel::Columns::SINGLE_DESCRIPTION, "text");
|
||||
m_mapper->addMapping(m_ui->lbIcon, MapObjectModel::Columns::PICTURE, "pixmap");
|
||||
}
|
||||
|
||||
setRow(idx.row());
|
||||
return true;
|
||||
}
|
||||
|
||||
void MapObjectCustomView::setRow(int row)
|
||||
{
|
||||
m_mapper->setCurrentIndex(row);
|
||||
|
||||
// assume for now, that the relation between row and uniqueMapId will not change:
|
||||
QAbstractItemModel *modelPtr = m_mapper->model();
|
||||
if (modelPtr)
|
||||
m_uniqueMapId = modelPtr->data(modelPtr->index(row, MapObjectModel::Columns::UNIQUE_MAP_ID)).toInt();
|
||||
else
|
||||
m_uniqueMapId = -1;
|
||||
}
|
||||
|
||||
} // namespace SituationMap
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* CustomView for MapObjects
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2017-04-11
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Own
|
||||
#include <Map/situation_map_types.h>
|
||||
#include <Viewer/LtsDataView/abstract_display_widget.h>
|
||||
|
||||
|
||||
class QDataWidgetMapper;
|
||||
namespace Ui
|
||||
{
|
||||
class MapObjectCustomView;
|
||||
}
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
class MapObjectCustomView final : public LtsDataView::AbstractDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = AbstractDisplayWidget;
|
||||
|
||||
public:
|
||||
explicit MapObjectCustomView(QWidget *parent = nullptr);
|
||||
~MapObjectCustomView();
|
||||
bool init(const QModelIndex &idx) override;
|
||||
|
||||
private:
|
||||
void setRow(int row);
|
||||
private:
|
||||
Ui::MapObjectCustomView *m_ui;
|
||||
QDataWidgetMapper *m_mapper = nullptr;
|
||||
|
||||
UniqueMapId m_uniqueMapId = INVALID_MAP_ID;
|
||||
};
|
||||
|
||||
} // SituationMap
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MapObjectCustomView</class>
|
||||
<widget class="QWidget" name="MapObjectCustomView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>63</width>
|
||||
<height>88</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"/>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbIcon">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>50</width>
|
||||
<height>50</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="lbDescription">
|
||||
<property name="text">
|
||||
<string notr="true"><Desc></string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+545
@@ -0,0 +1,545 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for ExerciseManangement - Exercise Overview Dialog Model
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "map_object_model.h"
|
||||
#include <Symbology/sidc_codec.h>
|
||||
|
||||
#include <SituationMap/Map/party_id_to_color_functor.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
// Qt
|
||||
#include <QString>
|
||||
#include <QBuffer>
|
||||
#include <QPainter>
|
||||
#include <QGuiApplication>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
static constexpr int ICON_RESOLUTION_CUSTOM = 128;
|
||||
static constexpr int ICON_RESOLUTION_TABLE = 32;
|
||||
|
||||
|
||||
void updateMapObjectDataToEnsureGoodQuality(MapObjectData *mod)
|
||||
{
|
||||
mod->m_symDataToRender.sizeL = ICON_RESOLUTION_CUSTOM;
|
||||
}
|
||||
|
||||
MapObjectData::~MapObjectData()
|
||||
{
|
||||
delete m_symbolResultWatcher;
|
||||
}
|
||||
|
||||
void MapObjectData::onResultReady()
|
||||
{
|
||||
if (!m_symbolResultWatcher)
|
||||
return;
|
||||
QSharedPointer<AdvancedSymbology::SymbolResult> symResult = m_symbolResultWatcher->symbolResult();
|
||||
if (!symResult)
|
||||
return; // should NEVER happen! (Which object should have triggered the signal???)
|
||||
setImage(symResult->symbolImage().image());
|
||||
emit dataChanged(m_uniqueMapId);
|
||||
m_symbolResultWatcher->deleteLater();
|
||||
m_symbolResultWatcher = nullptr;
|
||||
}
|
||||
|
||||
void MapObjectData::requestImage(AdvancedSymbology::SymbolDictionary *dict)
|
||||
{
|
||||
if (!m_symbolResultWatcher)
|
||||
{
|
||||
m_symbolResultWatcher = new AdvancedSymbology::SymbolResultWatcher;
|
||||
connect(m_symbolResultWatcher, &AdvancedSymbology::SymbolResultWatcher::resultReady,
|
||||
this, &MapObjectData::onResultReady);
|
||||
}
|
||||
updateMapObjectDataToEnsureGoodQuality(this);
|
||||
m_symbolResultWatcher->setSymbolResult(dict->findImage(m_symDataToRender));
|
||||
}
|
||||
|
||||
void MapObjectData::setImage(const QImage &img)
|
||||
{
|
||||
if (img.isNull())
|
||||
{
|
||||
m_pixIcon = QPixmap();
|
||||
m_pixPicture = QPixmap();
|
||||
return;
|
||||
}
|
||||
const auto dpr = qApp->devicePixelRatio(); // only works when all screens have the same dpr, otherwise
|
||||
// the widget (= screen) must be known
|
||||
m_pixIcon = QPixmap::fromImage(img.scaled(QSize(ICON_RESOLUTION_TABLE, ICON_RESOLUTION_TABLE) * dpr,
|
||||
Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||
m_pixPicture = QPixmap::fromImage(img.scaled(QSize(ICON_RESOLUTION_CUSTOM, ICON_RESOLUTION_CUSTOM) * dpr,
|
||||
Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation));
|
||||
m_pixIcon.setDevicePixelRatio(dpr);
|
||||
m_pixPicture.setDevicePixelRatio(dpr);
|
||||
}
|
||||
|
||||
//---------------------------------
|
||||
// MapObjectModel
|
||||
//---------------------------------
|
||||
|
||||
MapObjectModel::MapObjectModel(QObject *parent)
|
||||
: LtsWidgets::LtsAbstractTableModel<QSharedPointer<MapObjectData>>(
|
||||
{
|
||||
tr("UniqueMapid"),
|
||||
tr("Sidc"),
|
||||
tr("Description"),
|
||||
tr("Icon"),
|
||||
tr("ParticipantId"),
|
||||
tr("Equipment number"),
|
||||
tr("Party"),
|
||||
tr("TypeId"),
|
||||
tr("Type"),
|
||||
tr("VulnerabilityStateId"),
|
||||
tr("VulnerabilityState"),
|
||||
tr("Designator"),
|
||||
tr("Tact. Identifier"),
|
||||
tr("Picture")
|
||||
},
|
||||
parent)
|
||||
, m_logger(getLogger("MapObjectModel"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
MapObjectModel::~MapObjectModel()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void MapObjectModel::initModel(Map *map)
|
||||
{
|
||||
m_map = map;
|
||||
m_dictionary = &(m_map->symbolDictionary());
|
||||
|
||||
// Assume that the dialog (and therefore this underlying model) is created
|
||||
// AFTER all user-defined data is udes to update SymbolDictionary.
|
||||
// So we can simply use the changedDELAYED:
|
||||
connect(m_dictionary, &AdvancedSymbology::SymbolDictionary::changedDelayed, this, &MapObjectModel::requestCivilIcons, Qt::UniqueConnection);
|
||||
|
||||
connect(this, &MapObjectModel::rowsInserted, this, &MapObjectModel::updateUsedPartyIds);
|
||||
connect(this, &MapObjectModel::rowsRemoved, this, &MapObjectModel::updateUsedPartyIds);
|
||||
connect(this, &MapObjectModel::modelReset, this, &MapObjectModel::updateUsedPartyIds);
|
||||
}
|
||||
|
||||
bool MapObjectModel::contains(UniqueMapId uniqueMapId) const
|
||||
{
|
||||
return findRowForUniqueMapId(uniqueMapId) >= 0;
|
||||
}
|
||||
|
||||
|
||||
void MapObjectModel::remove(UniqueMapId uniqueMapId)
|
||||
{
|
||||
const int row = findRowForUniqueMapId(uniqueMapId);
|
||||
removeRow(row);
|
||||
}
|
||||
|
||||
void MapObjectModel::setMapObjectData(const QVector<QSharedPointer<MapObjectData>> &mapObjectDataVec)
|
||||
{
|
||||
setData(mapObjectDataVec);
|
||||
|
||||
for (const QSharedPointer<MapObjectData> &mapObjectData : mapObjectDataVec)
|
||||
if (mapObjectData)
|
||||
{
|
||||
updateMapObjectDataToEnsureGoodQuality(mapObjectData.data());
|
||||
connect(mapObjectData.data(), &MapObjectData::dataChanged,
|
||||
this, &MapObjectModel::onDataChanged, Qt::UniqueConnection);
|
||||
}
|
||||
}
|
||||
|
||||
bool MapObjectModel::addMapObjectData(const QSharedPointer<MapObjectData> &mapObjectData)
|
||||
{
|
||||
const int row = findRowForUniqueMapId(mapObjectData->m_uniqueMapId);
|
||||
if (row >= 0)
|
||||
return false;
|
||||
|
||||
updateMapObjectDataToEnsureGoodQuality(mapObjectData.data());
|
||||
|
||||
// APPEND
|
||||
if (!insertRow(mapObjectData))
|
||||
return false;
|
||||
|
||||
connect(mapObjectData.data(), &MapObjectData::dataChanged,
|
||||
this, &MapObjectModel::onDataChanged, Qt::UniqueConnection);
|
||||
return true;
|
||||
}
|
||||
|
||||
QImage markImage(const QPixmap &orgPixmap)
|
||||
{
|
||||
QImage newImage(orgPixmap.size(), QImage::Format_ARGB32);
|
||||
static QColor fillColor = QColor(211, 211, 211, 120);
|
||||
newImage.fill(fillColor);
|
||||
|
||||
QPainter painter(&newImage);
|
||||
painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
|
||||
|
||||
painter.drawPixmap(orgPixmap.rect(), orgPixmap);
|
||||
painter.end();
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
bool MapObjectModel::updateMapObjectData(const QSharedPointer<MapObjectData> &mapObjectData)
|
||||
{
|
||||
const int row = findRowForUniqueMapId(mapObjectData->m_uniqueMapId);
|
||||
if (row < 0)
|
||||
return false;
|
||||
|
||||
// UPDATE
|
||||
if (!mapObjectData->m_symDataToRender.sidc.isEmpty()) // if sidc is provided
|
||||
{
|
||||
updateMapObjectDataToEnsureGoodQuality(mapObjectData.data());
|
||||
|
||||
const auto &oldRowData = m_vecData.at(row);
|
||||
if (oldRowData->m_symDataToRender == mapObjectData->m_symDataToRender)
|
||||
return true; // image will not change -> return;
|
||||
|
||||
// 1) 'mark' old image and reuse it:
|
||||
mapObjectData->setImage(markImage(oldRowData->m_pixPicture));
|
||||
|
||||
// 2) icons are 'reused', but start update
|
||||
requestIcon(mapObjectData);
|
||||
}
|
||||
|
||||
connect(mapObjectData.data(), &MapObjectData::dataChanged,
|
||||
this, &MapObjectModel::onDataChanged, Qt::UniqueConnection);
|
||||
|
||||
return setRowData(row, mapObjectData);
|
||||
}
|
||||
|
||||
void MapObjectModel::requestCivilIcons()
|
||||
{
|
||||
for (const DATA_T &moData : qAsConst(m_vecData))
|
||||
{
|
||||
if (!moData)
|
||||
continue;
|
||||
const QString &sidc = moData->m_symDataToRender.sidc;
|
||||
if (!AdvancedSymbology::SidcCodec::isEncoded(sidc))
|
||||
continue;
|
||||
if (!AdvancedSymbology::SidcCodec::isCivil(sidc))
|
||||
continue;
|
||||
requestIcon(moData);
|
||||
} // for
|
||||
}
|
||||
|
||||
QVariant MapObjectModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole &&
|
||||
orientation == Qt::Horizontal)
|
||||
{
|
||||
if (section == PARTY)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
cfc.data.reserve(m_usedPartyIds.size());
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (const int partyId : m_usedPartyIds)
|
||||
{
|
||||
const PartyIdToColorFunctor::PartyData party = m_map->partyIdToColorFunctor().partyId(partyId);// m_parties.value(partyId);
|
||||
cfd.data = partyId;
|
||||
cfd.text = party.m_name;
|
||||
cfd.icon = party.m_icon;
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = false;
|
||||
return cfc.toVariant();
|
||||
}
|
||||
|
||||
if (section == TYPE_NAME)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
cfc.data.reserve(m_usedTypeName.size());
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (const QString &typeName : m_usedTypeName)
|
||||
{
|
||||
cfd.data = typeName;
|
||||
cfd.text = typeName;
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = true;
|
||||
return cfc.toVariant();
|
||||
}
|
||||
|
||||
if (section == VULNERABILITY_STATE)
|
||||
{
|
||||
LtsWidgets::ComboboxFilterContent cfc;
|
||||
cfc.data.reserve(m_usedVulnerabilities.size());
|
||||
LtsWidgets::ComboboxFilterData cfd;
|
||||
for (auto it = m_usedVulnerabilities.begin(); it != m_usedVulnerabilities.end(); ++it)
|
||||
{
|
||||
cfd.data = it.key();
|
||||
cfd.text = it.value();
|
||||
cfc.data.push_back(cfd);
|
||||
}
|
||||
cfc.sortItems = false;
|
||||
return cfc.toVariant();
|
||||
}
|
||||
}
|
||||
|
||||
return BaseClass::headerData(section, orientation, role);
|
||||
}
|
||||
|
||||
QVariant MapObjectModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return QVariant();
|
||||
if (role != Qt::DisplayRole &&
|
||||
role != Qt::ToolTipRole &&
|
||||
role != Qt::EditRole && // required by QDataWidgetMapper of MapObjectCustomView
|
||||
role != Qt::DecorationRole &&
|
||||
role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
return QVariant();
|
||||
|
||||
const DATA_T &moData = m_vecData.at(index.row());
|
||||
|
||||
if (role == Qt::ToolTipRole)
|
||||
{
|
||||
switch (index.column())
|
||||
{
|
||||
case PARTY:
|
||||
return QStringLiteral("%1 (%2)").arg(moData->m_partyName).arg(moData->m_partyId);
|
||||
case UNIQUE_MAP_ID: // CustomView -> ToolTipRole and column==UNIQUE_MAP_ID (0)
|
||||
case ICON: // TableView -> ToolTipRole and column==ICON
|
||||
{
|
||||
QString tooltip(QStringLiteral("<html>"));
|
||||
|
||||
const QPixmap &img = moData->m_pixPicture;
|
||||
if (!img.isNull())
|
||||
{
|
||||
// without a temporary file:
|
||||
QByteArray data;
|
||||
QBuffer buffer(&data);
|
||||
img.save(&buffer, "PNG", 100);
|
||||
tooltip.append(QStringLiteral("<center><img src='data:image/png;base64,%1'></center>").arg(QString::fromLatin1(data.toBase64())));
|
||||
}
|
||||
|
||||
if (!moData->m_typeName.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::TYPE_NAME , Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_typeName));
|
||||
}
|
||||
if (!moData->m_typeName.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::VULNERABILITY_STATE, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_vulnerabilityString));
|
||||
}
|
||||
if (!moData->m_description1.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::DESCRIPTION1, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_description1));
|
||||
}
|
||||
if (!moData->m_description2.isEmpty())
|
||||
{
|
||||
const QString &hdr = this->headerData(MapObjectModel::Columns::DESCRIPTION2, Qt::Horizontal, Qt::DisplayRole).toString();
|
||||
tooltip.append(QStringLiteral("<p>%1: %2</p>").arg(hdr, moData->m_description2));
|
||||
}
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
tooltip.append(QStringLiteral("<p>participantId: %2</p>").arg(moData->m_participantId));
|
||||
tooltip.append(QStringLiteral("<p>row: %2</p>").arg(index.row()));
|
||||
tooltip.append(QStringLiteral("<p>uniqueMapId: %2</p>").arg(moData->m_uniqueMapId));
|
||||
tooltip.append(QStringLiteral("<p>typeId: %2</p>").arg(moData->m_typeId));
|
||||
tooltip.append(QStringLiteral("<p>vulnerabilityStateId: %2</p>").arg(moData->m_vulnerabilityState));
|
||||
#endif // LTS_DEBUG
|
||||
|
||||
tooltip.append(QStringLiteral("</html>"));
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
} // switch
|
||||
|
||||
} // if ((role == Qt::ToolTipRole))
|
||||
|
||||
|
||||
if ((role == Qt::DisplayRole) || (role == Qt::EditRole) || (role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole))
|
||||
{
|
||||
const UniqueMapId &uniqueMapId = moData->m_uniqueMapId;
|
||||
|
||||
switch (index.column())
|
||||
{
|
||||
case UNIQUE_MAP_ID:
|
||||
return uniqueMapId;
|
||||
case SIDC:
|
||||
return moData->m_symDataToRender.sidc;
|
||||
case SINGLE_DESCRIPTION:
|
||||
if (moData->m_equipmentNumber >= 0)
|
||||
return moData->m_equipmentNumber;
|
||||
else
|
||||
return moData->m_description1;
|
||||
case ICON:
|
||||
{
|
||||
// provided or already cached?
|
||||
if (moData->m_pixIcon.isNull())
|
||||
{
|
||||
moData->setImage(AdvancedSymbology::SymbolDictionary::temporaryImage());
|
||||
requestIcon(moData);
|
||||
}
|
||||
if (moData->m_pixIcon.isNull())
|
||||
return QVariant();
|
||||
return moData->m_pixIcon;
|
||||
}
|
||||
case PARTICIPANT_ID:
|
||||
return moData->m_participantId <= 0 ? QVariant() : QVariant(moData->m_participantId);
|
||||
case EQUIPMENT_NUMBER:
|
||||
return moData->m_equipmentNumber <= 0 ? QVariant() : QVariant(moData->m_equipmentNumber);
|
||||
case PARTY:
|
||||
return moData->m_partyName;
|
||||
case TYPE_ID:
|
||||
return moData->m_typeId <= 0 ? QVariant() : QVariant(moData->m_typeId);
|
||||
case TYPE_NAME:
|
||||
return moData->m_typeName;
|
||||
case VULNERABILITY_STATE:
|
||||
return moData->m_vulnerabilityString;
|
||||
case VULNERABILITY_STATE_ID:
|
||||
return moData->m_vulnerabilityState <= 0 ? QVariant() : QVariant(moData->m_vulnerabilityState);
|
||||
case DESCRIPTION1:
|
||||
return moData->m_description1;
|
||||
case DESCRIPTION2:
|
||||
return moData->m_description2;
|
||||
case PICTURE:
|
||||
{
|
||||
// provided or already cached?
|
||||
if (moData->m_pixPicture.isNull())
|
||||
{
|
||||
moData->setImage(AdvancedSymbology::SymbolDictionary::temporaryImage());
|
||||
requestIcon(moData);
|
||||
}
|
||||
if (moData->m_pixPicture.isNull())
|
||||
return QVariant();
|
||||
return moData->m_pixPicture;
|
||||
} // case PICTURE
|
||||
} // switch
|
||||
}
|
||||
|
||||
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
|
||||
{
|
||||
if (index.column() == PARTY)
|
||||
return moData->m_partyId;
|
||||
|
||||
if (index.column() == TYPE_NAME)
|
||||
return moData->m_typeName;
|
||||
|
||||
if (index.column() == VULNERABILITY_STATE)
|
||||
return moData->m_vulnerabilityState;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
UniqueMapId MapObjectModel::uniqueMapIdOfIndex(const QModelIndex &index) const
|
||||
{
|
||||
if (!indexIsValid(index))
|
||||
return SituationMap::INVALID_MAP_ID;
|
||||
|
||||
const DATA_T &moData = m_vecData.at(index.row());
|
||||
if (!moData)
|
||||
return SituationMap::INVALID_MAP_ID;
|
||||
|
||||
return moData->m_uniqueMapId;
|
||||
}
|
||||
|
||||
void MapObjectModel::onDataChanged(UniqueMapId uniqueMapId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapId=" << uniqueMapId;
|
||||
|
||||
// resultWatcher has generated a new image -> update view:
|
||||
int row = findRowForUniqueMapId(uniqueMapId);
|
||||
emit dataChanged(index(row, 0), index(row, LtsAbstractTableModel::columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
|
||||
int MapObjectModel::findRowForUniqueMapId(UniqueMapId uniqueMapId) const
|
||||
{
|
||||
for (int i = 0; i < m_vecData.size(); ++i)
|
||||
{
|
||||
if (m_vecData.at(i)->m_uniqueMapId == uniqueMapId)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MapObjectModel::requestIcon(const MapObjectModel::DATA_T &data) const
|
||||
{
|
||||
// start rendering using SymbolResultWatcher:
|
||||
data->requestImage(m_dictionary);
|
||||
}
|
||||
|
||||
void MapObjectModel::updateUsedPartyIds()
|
||||
{
|
||||
m_usedPartyIds.clear();
|
||||
m_usedTypeName.clear();
|
||||
m_usedVulnerabilities.clear();
|
||||
for (const QSharedPointer<MapObjectData> &item : qAsConst(m_vecData))
|
||||
{
|
||||
if (!item)
|
||||
continue;
|
||||
m_usedPartyIds[item->m_partyId] = item->m_partyId;
|
||||
m_usedTypeName.insert(item->m_typeName);
|
||||
m_usedVulnerabilities.insert(item->m_vulnerabilityState,
|
||||
item->m_vulnerabilityState < 0 ? QStringLiteral("-") : item->m_vulnerabilityString);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
// MapObjectProxyModel
|
||||
// --------------------------------------------------------
|
||||
void MapObjectProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
|
||||
{
|
||||
m_sourceModel = qobject_cast<MapObjectModel*>(sourceModel);
|
||||
BaseClass::setSourceModel(sourceModel);
|
||||
}
|
||||
|
||||
bool MapObjectProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
|
||||
{
|
||||
if (!m_sourceModel ||
|
||||
source_left.column() != source_right.column() ||
|
||||
source_left.row() < 0 || source_left.row() >= m_sourceModel->m_vecData.size() ||
|
||||
source_right.row() < 0 || source_right.row() >= m_sourceModel->m_vecData.size()
|
||||
)
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
|
||||
|
||||
const QSharedPointer<MapObjectData> &left = m_sourceModel->m_vecData.at(source_left.row());
|
||||
const QSharedPointer<MapObjectData>&right = m_sourceModel->m_vecData.at(source_right.row());
|
||||
switch (source_left.column())
|
||||
{
|
||||
case MapObjectModel::Columns::UNIQUE_MAP_ID:
|
||||
return left->m_uniqueMapId < right->m_uniqueMapId;
|
||||
case MapObjectModel::Columns::SIDC:
|
||||
return left->m_symDataToRender.sidc < right->m_symDataToRender.sidc;
|
||||
case MapObjectModel::Columns::SINGLE_DESCRIPTION:
|
||||
if (left->m_equipmentNumber && right->m_equipmentNumber)
|
||||
return left->m_equipmentNumber < right->m_equipmentNumber;
|
||||
if (left->m_equipmentNumber)
|
||||
return true;
|
||||
if (right->m_equipmentNumber)
|
||||
return true;
|
||||
return left->m_description1 < left->m_description1;
|
||||
case MapObjectModel::Columns::PARTICIPANT_ID:
|
||||
return left->m_participantId < right->m_participantId;
|
||||
case MapObjectModel::Columns::EQUIPMENT_NUMBER:
|
||||
return left->m_equipmentNumber < right->m_equipmentNumber;
|
||||
case MapObjectModel::Columns::PARTY:
|
||||
return left->m_partyId < right->m_partyId;
|
||||
case MapObjectModel::Columns::TYPE_ID:
|
||||
return left->m_typeId < right->m_typeId;
|
||||
case MapObjectModel::Columns::TYPE_NAME:
|
||||
return left->m_typeName < right->m_typeName;
|
||||
case MapObjectModel::Columns::DESCRIPTION1:
|
||||
return left->m_description1 < right->m_description1;
|
||||
case MapObjectModel::Columns::DESCRIPTION2:
|
||||
return left->m_description2 < right->m_description2;
|
||||
}
|
||||
|
||||
return BaseClass::lessThan(source_left, source_right);
|
||||
}
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* MapObjectModel
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thoden, SLSE, 2017-04-11
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Own
|
||||
#include <Map/map.h>
|
||||
#include <Symbology/symbol_result.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
#include <LtsWidgets/lts_abstract_table_model.h>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
// --------------------------------------------------------
|
||||
// MapObjectData
|
||||
// --------------------------------------------------------
|
||||
class MapObjectData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MapObjectData(UniqueMapId uniqueMapId = INVALID_MAP_ID)
|
||||
: m_uniqueMapId(uniqueMapId)
|
||||
{}
|
||||
~MapObjectData();
|
||||
|
||||
void requestImage(AdvancedSymbology::SymbolDictionary *dict);
|
||||
void setImage(const QImage &img);
|
||||
|
||||
// basic data:
|
||||
UniqueMapId m_uniqueMapId;
|
||||
int m_participantId{-1};
|
||||
int m_equipmentNumber{-1};
|
||||
int m_partyId{-1};
|
||||
int m_typeId{-1};
|
||||
int m_vulnerabilityState{-1};
|
||||
QString m_partyName;
|
||||
QString m_typeName;
|
||||
QString m_vulnerabilityString;
|
||||
|
||||
int m_buildingId{-1};
|
||||
|
||||
QString m_description1;
|
||||
QString m_description2;
|
||||
|
||||
|
||||
// sidc -> icon/image:
|
||||
SymbolDataToRender m_symDataToRender;
|
||||
QPixmap m_pixIcon;
|
||||
QPixmap m_pixPicture;
|
||||
|
||||
private:
|
||||
AdvancedSymbology::SymbolResultWatcher *m_symbolResultWatcher = nullptr;
|
||||
|
||||
Q_SIGNALS:
|
||||
void dataChanged(UniqueMapId uniqueMapId);
|
||||
|
||||
public Q_SLOTS:
|
||||
void onResultReady();
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// MapObjectModel
|
||||
// --------------------------------------------------------
|
||||
class MapObjectModel : public LtsWidgets::LtsAbstractTableModel<QSharedPointer<MapObjectData>>
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = LtsWidgets::LtsAbstractTableModel<QSharedPointer<MapObjectData>>;
|
||||
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
UNIQUE_MAP_ID = 0,
|
||||
SIDC,
|
||||
SINGLE_DESCRIPTION,
|
||||
ICON,
|
||||
PARTICIPANT_ID,
|
||||
EQUIPMENT_NUMBER,
|
||||
PARTY,
|
||||
TYPE_ID,
|
||||
TYPE_NAME,
|
||||
VULNERABILITY_STATE_ID,
|
||||
VULNERABILITY_STATE,
|
||||
DESCRIPTION1,
|
||||
DESCRIPTION2,
|
||||
PICTURE
|
||||
};
|
||||
|
||||
explicit MapObjectModel(QObject *parent = nullptr);
|
||||
~MapObjectModel();
|
||||
|
||||
void initModel(Map *map);
|
||||
|
||||
bool contains(UniqueMapId uniqueMapId) const;
|
||||
|
||||
void remove(UniqueMapId uniqueMapId);
|
||||
|
||||
void setMapObjectData(const QVector<QSharedPointer<MapObjectData>> &mapObjectDataVec);
|
||||
bool addMapObjectData(const QSharedPointer<MapObjectData> &mapObjectData);
|
||||
bool updateMapObjectData(const QSharedPointer<MapObjectData> &mapObjectData);
|
||||
|
||||
template<typename T = QVector<UniqueMapId>>
|
||||
T allMapObjects() const
|
||||
{
|
||||
T uniqueMapIds;
|
||||
uniqueMapIds.reserve(m_vecData.size());
|
||||
|
||||
for (const DATA_T &item : m_vecData)
|
||||
if (item)
|
||||
uniqueMapIds += item->m_uniqueMapId;
|
||||
return uniqueMapIds;
|
||||
}
|
||||
|
||||
template<typename T = QVector<int>>
|
||||
T allEquipmentNumbers() const
|
||||
{
|
||||
T equipmentNumbers;
|
||||
equipmentNumbers.reserve(m_vecData.size());
|
||||
|
||||
for (const DATA_T &item : m_vecData)
|
||||
if (item && item->m_equipmentNumber > 0)
|
||||
equipmentNumbers += item->m_equipmentNumber;
|
||||
return equipmentNumbers;
|
||||
}
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override final;
|
||||
QVariant data(const QModelIndex &, int) const override final;
|
||||
|
||||
UniqueMapId uniqueMapIdOfIndex(const QModelIndex &index) const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onDataChanged(UniqueMapId uniqueMapId);
|
||||
void requestCivilIcons();
|
||||
void updateUsedPartyIds();
|
||||
|
||||
private:
|
||||
using DATA_T = QSharedPointer<MapObjectData>;
|
||||
|
||||
int findRowForUniqueMapId(UniqueMapId uniqueMapId) const;
|
||||
void requestIcon(const DATA_T &data) const;
|
||||
|
||||
Map *m_map = nullptr;
|
||||
AdvancedSymbology::SymbolDictionary *m_dictionary = nullptr;
|
||||
|
||||
QMap<int, int> m_usedPartyIds; // keep sorted
|
||||
QSet<QString> m_usedTypeName;
|
||||
QMap<int, QString> m_usedVulnerabilities; // keep sorted
|
||||
|
||||
LOGGER_T m_logger;
|
||||
|
||||
friend class MapObjectProxyModel;
|
||||
|
||||
};
|
||||
// MapObjectModel
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// MapObjectProxyModel
|
||||
// --------------------------------------------------------
|
||||
class MapObjectProxyModel : public LtsWidgets::LtsColumnFilterProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
using BaseClass = LtsWidgets::LtsColumnFilterProxyModel;
|
||||
|
||||
public:
|
||||
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
|
||||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
|
||||
protected:
|
||||
MapObjectModel *m_sourceModel = nullptr;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MapObjectSelectionDialog</class>
|
||||
<widget class="QWidget" name="MapObjectSelectionDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>600</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Map Object Selection</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="LtsDataView::LtsDataView" name="ltsDataView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>250</height>
|
||||
</size>
|
||||
</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>
|
||||
Executable
+726
@@ -0,0 +1,726 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class MapObjectSelection
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
// Own
|
||||
#include "map_object_selection_widget.h"
|
||||
#include "map_object_custom_view.h"
|
||||
#include "map_object_model.h"
|
||||
#include "ui_map_object_selection_dialog.h"
|
||||
|
||||
#include <Map/object_factory.h>
|
||||
#include <Map/party_id_to_color_functor.h>
|
||||
#include <Map/object_indicator.h>
|
||||
#include <MapObjects/participant.h>
|
||||
#include <Map/bounding_box.h>
|
||||
#include <AdapterDds/adapter_dds.h>
|
||||
|
||||
// PDM (for Single Service Equipment Check)
|
||||
#include <ProjectDataManagement/pdm_to_string.h>
|
||||
|
||||
// BLD
|
||||
#include <Proxies/Buildings/bld_ftc.h>
|
||||
|
||||
// Qt
|
||||
#include <QMenu>
|
||||
#include <QItemSelection>
|
||||
#include <QGridLayout>
|
||||
#include <LtsWidgets/lts_column_filter_proxy_model.h>
|
||||
|
||||
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MapObjectSelectionQDialog - Qt-Dialog - TestDialog
|
||||
//----------------------------------------------------------------------------
|
||||
MapObjectSelectionQDialog::MapObjectSelectionQDialog(QWidget *parent)
|
||||
: BaseClass(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
this->setLayout(layout);
|
||||
|
||||
m_mosw = new MapObjectSelectionWidget(this);
|
||||
|
||||
layout->addWidget(m_mosw);
|
||||
}
|
||||
bool MapObjectSelectionQDialog::init(Map *map, AdapterDds *adapterDds)
|
||||
{
|
||||
bool success = m_mosw->init(map, adapterDds);
|
||||
|
||||
if (map)
|
||||
connect(map, &Map::beginDestroy, this, &MapObjectSelectionQDialog::onMapDestroyed, Qt::UniqueConnection);
|
||||
|
||||
return success;
|
||||
}
|
||||
void MapObjectSelectionQDialog::reset()
|
||||
{
|
||||
m_mosw->reset();
|
||||
}
|
||||
|
||||
|
||||
void MapObjectSelectionQDialog::setMapObjectsToDisplay(const Map::RefPointerMapObjectList &mapObjList)
|
||||
{
|
||||
m_mosw->setMapObjectsToDisplay(mapObjList);
|
||||
}
|
||||
void MapObjectSelectionQDialog::setMapObjectsToDisplay(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
m_mosw->setMapObjectsToDisplay(uniqueMapIds);
|
||||
}
|
||||
|
||||
void MapObjectSelectionQDialog::onMapDestroyed()
|
||||
{
|
||||
// commit suicide";
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MapObjectSelectionLtsDialog - LtsDialog
|
||||
//----------------------------------------------------------------------------
|
||||
MapObjectSelectionLtsDialog::MapObjectSelectionLtsDialog(QWidget *parent, LtsWidgets::ButtonCombination buttonCombination)
|
||||
: BaseClass(parent, buttonCombination)
|
||||
, m_mosw(new MapObjectSelectionWidget(this))
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_checkButtonHandler(nullptr)
|
||||
{
|
||||
// signal-signal connection:
|
||||
connect(m_mosw, &MapObjectSelectionWidget::mapObjectsClicked,
|
||||
this, &MapObjectSelectionLtsDialog::mapObjectsClicked);
|
||||
|
||||
QGridLayout *layout = new QGridLayout(this);
|
||||
layout->addWidget(m_mosw);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::retranslate()
|
||||
{
|
||||
if (!m_mosw)
|
||||
return;
|
||||
translate(m_mosw->m_ui, tr("Map Object Selection"));
|
||||
}
|
||||
|
||||
bool MapObjectSelectionLtsDialog::init(Map *map, AdapterDds *adapterDds,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
|
||||
const std::shared_ptr<Buildings::Interface::Ftc> &bldFtc)
|
||||
{
|
||||
bool success = m_mosw->init(map, adapterDds);
|
||||
|
||||
if (map)
|
||||
{
|
||||
connect(map, &Map::beginDestroy, this, &MapObjectSelectionLtsDialog::onMapDestroyed, Qt::UniqueConnection);
|
||||
connect(map, &Map::escapePressed, this, &MapObjectSelectionLtsDialog::onEscapePressed, Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
m_ppmDtc = ppmDtc;
|
||||
m_ppmFtc = ppmFtc;
|
||||
m_bldFtc = bldFtc;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::enableServiceMonitorRequest(bool enable)
|
||||
{
|
||||
enableServiceMonitorRequestSendToServiceMonitor(enable);
|
||||
enableServiceMonitorRequestCheckButton(enable);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::enableServiceMonitorRequestSendToServiceMonitor(bool enable)
|
||||
{
|
||||
// Import-Button is used as Open in Service Monitor-Button
|
||||
QPushButton *btn = m_buttonBox->getButton(LtsWidgets::DialogButton::Import);
|
||||
if (!btn)
|
||||
return;
|
||||
btn->setVisible(enable);
|
||||
btn->setText(tr("Open in Service Monitor") + QStringLiteral(" ")); // since QMenu is added
|
||||
btn->setIcon(QIcon(QLatin1String("icon:player_equipment_check.svg")));
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Import, true);
|
||||
|
||||
if (!btn->menu())
|
||||
{
|
||||
QMenu *menu = new QMenu(this);
|
||||
QAction *replaceAction = new QAction(tr("Replace in Service Monitor"), this);
|
||||
QAction *addAction = new QAction(tr("Add to current Service Monitor"), this);
|
||||
menu->addAction(replaceAction);
|
||||
menu->addAction(addAction);
|
||||
btn->setMenu(menu);
|
||||
|
||||
connect(replaceAction, &QAction::triggered, this, &MapObjectSelectionLtsDialog::onServiceMonitorRequestedReplace);
|
||||
connect(addAction, &QAction::triggered, this, &MapObjectSelectionLtsDialog::onServiceMonitorRequestedAdd);
|
||||
}
|
||||
}
|
||||
void MapObjectSelectionLtsDialog::enableServiceMonitorRequestCheckButton(bool enable)
|
||||
{
|
||||
// Export-Button is used as Check-Button
|
||||
QPushButton *btn = m_buttonBox->getButton(LtsWidgets::DialogButton::Export);
|
||||
if (!btn)
|
||||
return;
|
||||
|
||||
btn->setVisible(enable);
|
||||
btn->setEnabled(m_ppmFtc.get());
|
||||
|
||||
// Added QStringLiteral is workaround for REGG-3773. Author of this dialog should fix this properly.
|
||||
btn->setText(tr("Check") + QStringLiteral(" "));
|
||||
btn->setIcon(QIcon(QStringLiteral(":/style/dialog-ok.svg")));
|
||||
|
||||
if (!m_checkButtonHandler && m_ppmFtc.get())
|
||||
{
|
||||
m_checkButtonHandler = new ServiceMonitor::CheckButtonHandler(btn);
|
||||
m_checkButtonHandler->setPpm(m_ppmDtc, m_ppmFtc);
|
||||
m_checkButtonHandler->addReset();
|
||||
m_checkButtonHandler->addTacticalState();
|
||||
|
||||
connect(m_mosw, &MapObjectSelectionWidget::visibleObjectsChanged,
|
||||
this, &MapObjectSelectionLtsDialog::updateCheckButtonHandler);
|
||||
// reset the buildings also:
|
||||
connect(m_checkButtonHandler, &ServiceMonitor::CheckButtonHandler::combatReadyRequested,
|
||||
this, &MapObjectSelectionLtsDialog::onServiceMonitorBtnCombatReadyRequested);
|
||||
connect(m_checkButtonHandler, &ServiceMonitor::CheckButtonHandler::combatReadyResetContamintationRequested,
|
||||
this, &MapObjectSelectionLtsDialog::onServiceMonitorBtnCombatReadyResetContaminationRequested);
|
||||
connect(m_checkButtonHandler, &ServiceMonitor::CheckButtonHandler::resetContaminationRequested,
|
||||
this, &MapObjectSelectionLtsDialog::onServiceMonitorBtnResetContaminationRequested);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> MapObjectSelectionLtsDialog::visibleParticipantIdsDds() const
|
||||
{
|
||||
if (!m_mosw)
|
||||
return {};
|
||||
return m_mosw->visibleParticipantIds();
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::updateCheckButtonHandler()
|
||||
{
|
||||
if (!m_checkButtonHandler)
|
||||
return;
|
||||
|
||||
const std::vector<int> &visiPart = visibleParticipantIdsDds();
|
||||
m_checkButtonHandler->setSelectedParticipantIds(visiPart);
|
||||
|
||||
// [NLDEVCTRL-1357] MASIE-60: Zurücksetzen Gebäude über VorauswahlDialog - auch wenn nur Bldgs selektiert sind.
|
||||
if (!m_mosw)
|
||||
return;
|
||||
const QVector<int> &visiBldgs = m_mosw->visibleBuildingIds();
|
||||
if (visiBldgs.isEmpty())
|
||||
return;
|
||||
m_checkButtonHandler->enableForBuildingReset_OfMapObjectSelectionWidget();
|
||||
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onServiceMonitorBtnCombatReadyRequested()
|
||||
{
|
||||
onServiceMonitorBtnVulnerabiltyResetRequested(ProjectDataManagement::VulnerabilityState_def::CombatReady, false);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onServiceMonitorBtnCombatReadyResetContaminationRequested()
|
||||
{
|
||||
onServiceMonitorBtnVulnerabiltyResetRequested(ProjectDataManagement::VulnerabilityState_def::CombatReady, true);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onServiceMonitorBtnResetContaminationRequested()
|
||||
{
|
||||
onServiceMonitorBtnVulnerabiltyResetRequested(ProjectDataManagement::VulnerabilityState_def::NoChange, true);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onServiceMonitorBtnVulnerabiltyResetRequested( const ProjectDataManagement::VulnerabilityState &vs, bool resetContamination )
|
||||
{
|
||||
if (!m_mosw || !m_bldFtc)
|
||||
return;
|
||||
|
||||
const QVector<int> &buildingIds = m_mosw->visibleBuildingIds();
|
||||
if (buildingIds.empty())
|
||||
return;
|
||||
|
||||
std::vector<Buildings::Building> buildings;
|
||||
buildings.reserve(buildingIds.size());
|
||||
Buildings::Building bldg;
|
||||
for (int buildingId : buildingIds)
|
||||
{
|
||||
bldg.buildingId(buildingId);
|
||||
buildings.push_back(bldg);
|
||||
} // for
|
||||
Buildings::SetBuildingStatesRequest request;
|
||||
request.buildings(buildings);
|
||||
request.vulnerabilityState(vs);
|
||||
request.resetContamination(resetContamination);
|
||||
|
||||
m_requestHelper->addRequest([this, request]()
|
||||
{
|
||||
return m_bldFtc->setBuildingStatesRequest(request, this);
|
||||
});
|
||||
|
||||
m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onSetBuildingStatesReply(const Core::FunctionReplyObject &reply)
|
||||
{
|
||||
m_requestHelper->requestReply(reply);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::reset()
|
||||
{
|
||||
m_mosw->reset();
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::setMapObjectsToDisplay(const Map::RefPointerMapObjectList &mapObjList)
|
||||
{
|
||||
m_mosw->setMapObjectsToDisplay(mapObjList);
|
||||
}
|
||||
void MapObjectSelectionLtsDialog::setMapObjectsToDisplay(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
m_mosw->setMapObjectsToDisplay(uniqueMapIds);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onMapDestroyed()
|
||||
{
|
||||
// commit suicide";
|
||||
delete this;
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onEscapePressed()
|
||||
{
|
||||
if (!m_mosw)
|
||||
return;
|
||||
m_mosw->clearSelectionOfMapObjects(true);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onServiceMonitorRequestedReplace()
|
||||
{
|
||||
const QVector<int> allEquipmentNumbers = m_mosw->visibleEquipmentNumbers();
|
||||
if (allEquipmentNumbers.isEmpty())
|
||||
return;
|
||||
emit serviceMonitorRequested(allEquipmentNumbers, true);
|
||||
}
|
||||
|
||||
void MapObjectSelectionLtsDialog::onServiceMonitorRequestedAdd()
|
||||
{
|
||||
const QVector<int> allEquipmentNumbers = m_mosw->visibleEquipmentNumbers();
|
||||
if (allEquipmentNumbers.isEmpty())
|
||||
return;
|
||||
emit serviceMonitorRequested(allEquipmentNumbers, false);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MapObjectSelectionWidget
|
||||
//----------------------------------------------------------------------------
|
||||
MapObjectSelectionWidget::MapObjectSelectionWidget(QWidget *parent)
|
||||
: BaseClass(parent)
|
||||
, m_ui(new Ui::MapObjectSelectionDialog)
|
||||
, m_logger(getLogger("MapObjectSelectionWidget"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->setupUi(this);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
MapObjectSelectionWidget::~MapObjectSelectionWidget()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
// 'clear' current selection and MapObjectIndicator
|
||||
clearSelectionOfMapObjects(true);
|
||||
|
||||
// delete ui:
|
||||
delete m_ui;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool MapObjectSelectionWidget::init(Map *map, AdapterDds *adapterDds)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!map)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no map";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!adapterDds)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no adapterDds";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_map = map;
|
||||
m_adapterDds = adapterDds;
|
||||
|
||||
connect(m_adapterDds.data(), &AdapterDds::mapObjectChanged, this, &MapObjectSelectionWidget::updateMapObject, Qt::UniqueConnection);
|
||||
connect(m_adapterDds.data(), &AdapterDds::mapObjectRemoved, this, &MapObjectSelectionWidget::onMapObjectRemoved, Qt::UniqueConnection);
|
||||
connect(&m_map->partyIdToColorFunctor(), &PartyIdToColorFunctor::partyChanged,
|
||||
this, &MapObjectSelectionWidget::onPartyIdsChanged, Qt::UniqueConnection);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
return true;
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::reset()
|
||||
{
|
||||
if (m_map.isNull())
|
||||
return;
|
||||
|
||||
// clear selection and MapObjectIndicator:
|
||||
clearSelectionOfMapObjects(true);
|
||||
|
||||
// clear model:
|
||||
if (m_mapObjectModel)
|
||||
{
|
||||
m_mapObjectModel->clear();
|
||||
m_mapObjectModel->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::clearSelectionOfMapObjects(bool clearMapObjectIndicator)
|
||||
{
|
||||
if (!m_mapObjectModel)
|
||||
return;
|
||||
if (!m_map)
|
||||
return;
|
||||
|
||||
const QVector<UniqueMapId> &uniqueMapIds = m_mapObjectModel->allMapObjects();
|
||||
if (uniqueMapIds.isEmpty())
|
||||
return;
|
||||
|
||||
ObjectFactory &objFac = m_map->objectFactory();
|
||||
for (auto uniqueMapId : uniqueMapIds)
|
||||
{
|
||||
RefPointer<AbstractMapObject> mapObj = objFac.get<AbstractMapObject>(uniqueMapId);
|
||||
if (mapObj)
|
||||
{
|
||||
mapObj->setSelected(false);
|
||||
mapObj->updateView();
|
||||
}
|
||||
}
|
||||
|
||||
if (clearMapObjectIndicator)
|
||||
{
|
||||
// remove MapObjectIndicator:
|
||||
m_map->objectIndicator().remove();
|
||||
}
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::setMapObjectsToDisplay(const Map::RefPointerMapObjectList &mapObjList)
|
||||
{
|
||||
// 'clear' current selection:
|
||||
clearSelectionOfMapObjects(false);
|
||||
|
||||
// apply Ids:
|
||||
QVector<UniqueMapId> uniqueMapIds;
|
||||
uniqueMapIds.reserve(mapObjList.size());
|
||||
for (const auto &mapObj : mapObjList)
|
||||
if (mapObj && (isUniqueMapIdValid(mapObj->uniqueMapId())))
|
||||
uniqueMapIds.append(mapObj->uniqueMapId());
|
||||
setMapObjectsToDisplay(uniqueMapIds);
|
||||
}
|
||||
|
||||
|
||||
void MapObjectSelectionWidget::setMapObjectsToDisplay(const QVector<UniqueMapId> &uniqueMapIds)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapIds.size()=" << uniqueMapIds.size();
|
||||
|
||||
if (m_map.isNull())
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no map";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_mapObjectModel)
|
||||
{
|
||||
// initialize model:
|
||||
m_mapObjectModel = QPointer<MapObjectModel>(new MapObjectModel(this));
|
||||
m_mapObjectModel->initModel(m_map);
|
||||
|
||||
// proxyModel:
|
||||
auto proxyModel = new MapObjectProxyModel(this);
|
||||
proxyModel->setSourceModel(static_cast<MapObjectModel*>(m_mapObjectModel.data()));
|
||||
proxyModel->setDynamicSortFilter(false);
|
||||
|
||||
// set view: (LtsDataView)
|
||||
// m_ui->ltsDataView->seamless();
|
||||
m_ui->ltsDataView->setSelectionMode(QAbstractItemView::SelectionMode::SingleSelection);
|
||||
m_ui->ltsDataView->selectCustomView();
|
||||
m_ui->ltsDataView->setModel(proxyModel, [this]()
|
||||
{
|
||||
MapObjectCustomView *mocw = new MapObjectCustomView(this);
|
||||
return mocw;
|
||||
});
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::UNIQUE_MAP_ID);
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::SIDC);
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::PARTICIPANT_ID);
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::TYPE_ID);
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::VULNERABILITY_STATE_ID);
|
||||
#endif
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::SINGLE_DESCRIPTION);
|
||||
m_ui->ltsDataView->hideColumn(MapObjectModel::Columns::PICTURE); // do not "print" the picture
|
||||
|
||||
// connect signals of TableView/CustomView:
|
||||
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::clicked, this, &MapObjectSelectionWidget::onTableViewClicked);
|
||||
connect(m_ui->ltsDataView, &LtsDataView::LtsDataView::signalEntered, this, &MapObjectSelectionWidget::onMapObjectEntered);
|
||||
|
||||
// signal-signal
|
||||
connect(proxyModel, &MapObjectProxyModel::rowsInserted, this, &MapObjectSelectionWidget::visibleObjectsChanged);
|
||||
connect(proxyModel, &MapObjectProxyModel::rowsRemoved, this, &MapObjectSelectionWidget::visibleObjectsChanged);
|
||||
connect(proxyModel, &MapObjectProxyModel::modelReset, this, &MapObjectSelectionWidget::visibleObjectsChanged);
|
||||
}
|
||||
|
||||
|
||||
// old approach:
|
||||
// add just the new items to avoid unneccessary m_adapterDds->unifiedMapObjectData
|
||||
// leads to many GUI updates (CustomView of LtsDataView and therefore a few min for ~5000 entries.
|
||||
// So simply replace completely.
|
||||
|
||||
// fill completely new:
|
||||
QVector<QSharedPointer<MapObjectData>> mapObjectDataVec;
|
||||
mapObjectDataVec.reserve(uniqueMapIds.size());
|
||||
|
||||
UnifiedMapObjectData umodOut;
|
||||
for (const auto uniqueMapId : uniqueMapIds)
|
||||
{
|
||||
if (m_adapterDds->unifiedMapObjectData(uniqueMapId, umodOut))
|
||||
mapObjectDataVec.append(dataFromUnified(uniqueMapId, umodOut));
|
||||
else
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " unifiedMapObjectData failed, uniqueMapId=" << uniqueMapId;
|
||||
|
||||
} // for
|
||||
|
||||
m_mapObjectModel->setMapObjectData(mapObjectDataVec);
|
||||
|
||||
// so the data gets sorted by equipment number + party
|
||||
m_ui->ltsDataView->setSortIndicator(MapObjectModel::Columns::EQUIPMENT_NUMBER, Qt::AscendingOrder);
|
||||
m_ui->ltsDataView->setSortIndicator(MapObjectModel::Columns::PARTY, Qt::AscendingOrder);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, uniqueMapIds.size()=" << uniqueMapIds.size();
|
||||
}
|
||||
|
||||
|
||||
std::vector<int> MapObjectSelectionWidget::visibleParticipantIds() const
|
||||
{
|
||||
std::vector<int> ret;
|
||||
if (!m_mapObjectModel)
|
||||
return ret;
|
||||
const auto filterProxy = m_ui->ltsDataView->proxyModel();
|
||||
const int rowCount = filterProxy->rowCount();
|
||||
ret.reserve(rowCount);
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
{
|
||||
const QModelIndex idx = filterProxy->mapToSource(filterProxy->index(r, 0, QModelIndex()));
|
||||
if (!idx.isValid())
|
||||
continue;
|
||||
const auto &item = m_mapObjectModel->getRowData(idx.row());
|
||||
if (!item || item->m_participantId <= 0)
|
||||
continue;
|
||||
ret.push_back(item->m_participantId);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVector<int> MapObjectSelectionWidget::visibleEquipmentNumbers() const
|
||||
{
|
||||
QVector<int> ret;
|
||||
if (!m_mapObjectModel)
|
||||
return ret;
|
||||
const auto filterProxy = m_ui->ltsDataView->proxyModel();
|
||||
const int rowCount = filterProxy->rowCount();
|
||||
ret.reserve(rowCount);
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
{
|
||||
const QModelIndex idx = filterProxy->mapToSource(filterProxy->index(r, 0, QModelIndex()));
|
||||
if (!idx.isValid())
|
||||
continue;
|
||||
const auto &item = m_mapObjectModel->getRowData(idx.row());
|
||||
if (!item || item->m_equipmentNumber <= 0)
|
||||
continue;
|
||||
ret += item->m_equipmentNumber;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QVector<int> MapObjectSelectionWidget::visibleBuildingIds() const
|
||||
{
|
||||
QVector<int> ret;
|
||||
if (!m_mapObjectModel)
|
||||
return ret;
|
||||
const auto filterProxy = m_ui->ltsDataView->proxyModel();
|
||||
const int rowCount = filterProxy->rowCount();
|
||||
ret.reserve(rowCount);
|
||||
for (int r = 0; r < rowCount; ++r)
|
||||
{
|
||||
const QModelIndex idx = filterProxy->mapToSource(filterProxy->index(r, 0, QModelIndex()));
|
||||
if (!idx.isValid())
|
||||
continue;
|
||||
const auto &item = m_mapObjectModel->getRowData(idx.row());
|
||||
|
||||
if (!item || item->m_buildingId<0)
|
||||
continue;
|
||||
if (!ret.contains(item->m_buildingId)) // avoid duplicates
|
||||
ret.push_back(item->m_buildingId);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool MapObjectSelectionWidget::addMapObject(const UniqueMapId &uniqueMapId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapId=" << uniqueMapId;
|
||||
|
||||
if (m_map.isNull() || m_adapterDds.isNull() || m_mapObjectModel.isNull())
|
||||
return false;
|
||||
|
||||
if (m_mapObjectModel->contains(uniqueMapId))
|
||||
return false;
|
||||
|
||||
UnifiedMapObjectData umodOut;
|
||||
if (m_adapterDds->unifiedMapObjectData(uniqueMapId, umodOut))
|
||||
return m_mapObjectModel->addMapObjectData(dataFromUnified(uniqueMapId, umodOut));
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, uniqueMapId=" << uniqueMapId;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MapObjectSelectionWidget::updateMapObject(const UniqueMapId &uniqueMapId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapId=" << uniqueMapId;
|
||||
|
||||
if (m_map.isNull() || m_adapterDds.isNull() || !m_mapObjectModel)
|
||||
return false;
|
||||
|
||||
if (!m_mapObjectModel->contains(uniqueMapId))
|
||||
return true;
|
||||
|
||||
UnifiedMapObjectData umodOut;
|
||||
if (m_adapterDds->unifiedMapObjectData(uniqueMapId, umodOut))
|
||||
return m_mapObjectModel->updateMapObjectData(dataFromUnified(uniqueMapId, umodOut));
|
||||
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " unifiedMapObjectData failed, uniqueMapId=" << uniqueMapId;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, uniqueMapId=" << uniqueMapId;
|
||||
return false;
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::onMapObjectRemoved(UniqueMapId uniqueMapId)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, uniqueMapId=" << uniqueMapId;
|
||||
|
||||
if (!m_mapObjectModel)
|
||||
return;
|
||||
|
||||
m_mapObjectModel->remove(uniqueMapId);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, uniqueMapId=" << uniqueMapId;
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::onPartyIdsChanged()
|
||||
{
|
||||
if (!m_mapObjectModel)
|
||||
return;
|
||||
const QVector<UniqueMapId> &uniqueMapIds = m_mapObjectModel->allMapObjects();
|
||||
|
||||
this->setMapObjectsToDisplay(uniqueMapIds);
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::onTableViewClicked(const QModelIndex &index)
|
||||
{
|
||||
if (!m_mapObjectModel)
|
||||
return;
|
||||
onMapObjectClicked(m_mapObjectModel->uniqueMapIdOfIndex(index));
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::onMapObjectClicked(UniqueMapId uniqueMapId)
|
||||
{
|
||||
if (m_map && QGuiApplication::keyboardModifiers().testFlag(Qt::KeyboardModifier::ShiftModifier))
|
||||
{
|
||||
RefPointer<AbstractMapObject> mapObj = m_map->objectFactory().get(uniqueMapId);
|
||||
if (!mapObj)
|
||||
return;
|
||||
BoundingBox bbox;
|
||||
mapObj->boundingBox(bbox);
|
||||
if (bbox.isValid())
|
||||
{
|
||||
m_map->setCenterPoint(bbox.center().toPointF());
|
||||
m_map->objectIndicator().remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emit mapObjectsClicked(QVector<UniqueMapId>() << uniqueMapId);
|
||||
}
|
||||
|
||||
void MapObjectSelectionWidget::onMapObjectEntered(const QModelIndex &index)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
if (!m_mapObjectModel)
|
||||
return;
|
||||
|
||||
if (m_map.isNull())
|
||||
return;
|
||||
|
||||
const UniqueMapId uniqueMapId = m_mapObjectModel->uniqueMapIdOfIndex(index);
|
||||
|
||||
//
|
||||
// MapObjectIndicator
|
||||
//
|
||||
m_map->objectIndicator().setMapObjectToPointTo(uniqueMapId);
|
||||
|
||||
//
|
||||
// setSelected
|
||||
//
|
||||
// remove old:
|
||||
ObjectFactory &objFac = m_map->objectFactory();
|
||||
{
|
||||
for (auto uid : qAsConst(m_selectedMapObjects))
|
||||
{
|
||||
RefPointer<AbstractMapObject> mapObj = objFac.get<AbstractMapObject>(uid);
|
||||
if (mapObj)
|
||||
{
|
||||
mapObj->setSelected(false);
|
||||
mapObj->updateView();
|
||||
}
|
||||
}
|
||||
}
|
||||
m_selectedMapObjects.clear();
|
||||
|
||||
{
|
||||
m_selectedMapObjects.insert(uniqueMapId);
|
||||
RefPointer<AbstractMapObject> mapObj = objFac.get<AbstractMapObject>(uniqueMapId);
|
||||
if (mapObj)
|
||||
{
|
||||
mapObj->setSelected(true);
|
||||
mapObj->updateView();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<MapObjectData> MapObjectSelectionWidget::dataFromUnified(UniqueMapId uniqueMapId,
|
||||
const UnifiedMapObjectData &umod)
|
||||
{
|
||||
// transfer data from Adapter/UnifiedMapObjectData to Model/MapObjectData;
|
||||
QSharedPointer<MapObjectData> mod = QSharedPointer<MapObjectData>(new MapObjectData(uniqueMapId));
|
||||
mod->m_equipmentNumber = umod.m_equipmentNumber;
|
||||
mod->m_partyId = umod.m_partyId;
|
||||
mod->m_partyName = m_map->partyIdToColorFunctor().partyIdToName(mod->m_partyId);
|
||||
|
||||
mod->m_participantId = umod.m_participantData.m_participantId;
|
||||
mod->m_typeId = umod.m_participantData.m_typeId;
|
||||
mod->m_typeName = umod.m_participantData.m_typeName.isEmpty() ? QStringLiteral("-") : umod.m_participantData.m_typeName;
|
||||
mod->m_vulnerabilityState = umod.m_participantData.m_vulnerabilityState;
|
||||
mod->m_vulnerabilityString = umod.m_participantData.m_vulnerabilityString.isEmpty() ? QStringLiteral("-") : umod.m_participantData.m_vulnerabilityString;
|
||||
|
||||
mod->m_buildingId = umod.m_buildingData.buildingId;
|
||||
|
||||
mod->m_description1 = umod.m_description1;
|
||||
mod->m_description2 = umod.m_description2;
|
||||
|
||||
mod->m_symDataToRender = umod.m_symDataToRender;
|
||||
mod->setImage(umod.m_image);
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
} // namespace SituationMap
|
||||
|
||||
Executable
+226
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Class MapObjectSelection
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Own
|
||||
#include <SituationMap/sitmapdds_export.h>
|
||||
#include <Map/map.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <Common/situation_map_logging.h>
|
||||
|
||||
// BLD
|
||||
#include <Buildings/bld_ftc.h>
|
||||
|
||||
// PPM
|
||||
#include <ParticipantManagement/ppm_ftc.h>
|
||||
|
||||
// SMO
|
||||
#include <ServiceMonitor/Gui/Monitors/smo_check_button_handler.h>
|
||||
|
||||
// Qt
|
||||
#include <QPointer>
|
||||
#include <QDialog>
|
||||
|
||||
|
||||
// forward
|
||||
class QItemSelection;
|
||||
class QGridLayout;
|
||||
namespace Ui
|
||||
{
|
||||
class MapObjectSelectionDialog;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
namespace SituationMap
|
||||
{
|
||||
|
||||
// forward
|
||||
class AdapterDds;
|
||||
class MapObjectModel;
|
||||
class MapObjectData;
|
||||
struct UnifiedMapObjectData;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Test Dialog
|
||||
//----------------------------------------------------------------------------
|
||||
// Forward:
|
||||
class MapObjectSelectionWidget;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MapObjectSelectionQDialog - Qt-Dialog
|
||||
//----------------------------------------------------------------------------
|
||||
class SITMAPDDS_EXPORT MapObjectSelectionQDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = QDialog;
|
||||
|
||||
public:
|
||||
explicit MapObjectSelectionQDialog(QWidget *parent = nullptr);
|
||||
~MapObjectSelectionQDialog() = default;
|
||||
|
||||
bool init(Map *map, AdapterDds *adapterDds);
|
||||
void reset();
|
||||
|
||||
void setMapObjectsToDisplay(const Map::RefPointerMapObjectList &mapObjList);
|
||||
void setMapObjectsToDisplay(const QVector<UniqueMapId> &uniqueMapIds);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onMapDestroyed();
|
||||
|
||||
protected:
|
||||
MapObjectSelectionWidget *m_mosw = nullptr;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MapObjectSelectionLtsDialog - LtsDialog
|
||||
//----------------------------------------------------------------------------
|
||||
class SITMAPDDS_EXPORT MapObjectSelectionLtsDialog : public LtsWidgets::LtsDialog
|
||||
, protected Buildings::Interface::Ftc::SetBuildingStatesReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = LtsWidgets::LtsDialog;
|
||||
|
||||
public:
|
||||
explicit MapObjectSelectionLtsDialog(QWidget *parent = nullptr,
|
||||
LtsWidgets::ButtonCombination buttonCombination = LtsWidgets::ButtonCombination::CloseOnly);
|
||||
~MapObjectSelectionLtsDialog() = default;
|
||||
|
||||
bool init(Map *map, AdapterDds *adapterDds,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
|
||||
const std::shared_ptr<Buildings::Interface::Ftc> &bldFtc);
|
||||
void enableServiceMonitorRequest(bool enable);
|
||||
void reset();
|
||||
|
||||
void setMapObjectsToDisplay(const Map::RefPointerMapObjectList &mapObjList);
|
||||
void setMapObjectsToDisplay(const QVector<UniqueMapId> &uniqueMapIds);
|
||||
|
||||
Q_SIGNALS:
|
||||
void mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds);
|
||||
void serviceMonitorRequested(const QVector<int> &equipmentNumbers, bool replace);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onMapDestroyed();
|
||||
void onEscapePressed();
|
||||
|
||||
void onServiceMonitorRequestedReplace();
|
||||
void onServiceMonitorRequestedAdd();
|
||||
void updateCheckButtonHandler();
|
||||
void onServiceMonitorBtnCombatReadyRequested();
|
||||
void onServiceMonitorBtnCombatReadyResetContaminationRequested();
|
||||
void onServiceMonitorBtnResetContaminationRequested();
|
||||
void onServiceMonitorBtnVulnerabiltyResetRequested(const ProjectDataManagement::VulnerabilityState &vs, bool resetContamination);
|
||||
|
||||
|
||||
protected:
|
||||
virtual void onSetBuildingStatesReply(const Core::FunctionReplyObject &reply) override;
|
||||
|
||||
protected:
|
||||
void enableServiceMonitorRequestSendToServiceMonitor(bool enable);
|
||||
void enableServiceMonitorRequestCheckButton(bool enable);
|
||||
std::vector<int> visibleParticipantIdsDds() const;
|
||||
MapObjectSelectionWidget *m_mosw = nullptr;
|
||||
|
||||
// emulate Single Service Equipment Check:
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
|
||||
std::shared_ptr<Buildings::Interface::Ftc> m_bldFtc;
|
||||
LtsUtils::RequestHelper *m_requestHelper{nullptr};
|
||||
ServiceMonitor::CheckButtonHandler *m_checkButtonHandler;
|
||||
|
||||
private:
|
||||
void retranslate() override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// MapObjectSelectionWidget
|
||||
//----------------------------------------------------------------------------
|
||||
class MapObjectSelectionWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using BaseClass = QWidget;
|
||||
|
||||
/*! \name Construction, Destruction */
|
||||
//@{
|
||||
public:
|
||||
|
||||
/*! @brief Constructor */
|
||||
explicit MapObjectSelectionWidget(QWidget *parent = nullptr);
|
||||
|
||||
/*! @brief Destructor */
|
||||
virtual ~MapObjectSelectionWidget();
|
||||
|
||||
bool init(Map *map, AdapterDds *adapterDds);
|
||||
void reset();
|
||||
//@}
|
||||
|
||||
void setMapObjectsToDisplay(const Map::RefPointerMapObjectList &mapObjList);
|
||||
void setMapObjectsToDisplay(const QVector<UniqueMapId> &uniqueMapIds);
|
||||
|
||||
std::vector<int> visibleParticipantIds() const;
|
||||
QVector<int> visibleEquipmentNumbers() const;
|
||||
|
||||
QVector<int> visibleBuildingIds() const;
|
||||
|
||||
|
||||
signals:
|
||||
void mapObjectsClicked(const QVector<UniqueMapId> &uniqueMapIds);
|
||||
void visibleObjectsChanged();
|
||||
|
||||
protected slots:
|
||||
/**
|
||||
* @brief clearSelectionOfMapObjects
|
||||
* If new widgets appear, the other widgtes are re-arranged.
|
||||
* This can swallow some leaveEvents.
|
||||
* To ensure a consistent state, the selection of all MapObjects of the model can be removed.
|
||||
* @param clearMapObjectIndicator removes MapObjectIndicator
|
||||
*
|
||||
*/
|
||||
void clearSelectionOfMapObjects(bool clearMapObjectIndicator);
|
||||
|
||||
void onMapObjectRemoved(UniqueMapId uniqueMapId);
|
||||
void onPartyIdsChanged();
|
||||
|
||||
// TableView
|
||||
void onTableViewClicked(const QModelIndex &index);
|
||||
|
||||
// CustomView
|
||||
void onMapObjectClicked(UniqueMapId uniqueMapId);
|
||||
void onMapObjectEntered(const QModelIndex &index);
|
||||
|
||||
protected:
|
||||
bool addMapObject(const UniqueMapId &uniqueMapId);
|
||||
bool updateMapObject(const UniqueMapId &uniqueMapId);
|
||||
|
||||
QSharedPointer<MapObjectData> dataFromUnified(UniqueMapId uniqueMapId,
|
||||
const UnifiedMapObjectData &umod);
|
||||
|
||||
private:
|
||||
friend class MapObjectSelectionLtsDialog;
|
||||
QPointer<MapObjectModel> m_mapObjectModel;
|
||||
|
||||
|
||||
QPointer<Map> m_map;
|
||||
QPointer<AdapterDds> m_adapterDds;
|
||||
|
||||
QSet<UniqueMapId> m_selectedMapObjects; //typically just one item
|
||||
|
||||
Ui::MapObjectSelectionDialog *m_ui;
|
||||
LOGGER_T m_logger; ///< Interface of the Logging-Facility
|
||||
};
|
||||
|
||||
|
||||
} // namespace SituationMap
|
||||
|
||||
Reference in new issue
Block a user