Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+39
View File
@@ -0,0 +1,39 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Mike Wille, SLSE, 2016-09-06
#
#
# Data Plugin
#
SET(mrk_common_gui_SRCS
mrk_dialog_model.cpp
mrk_dialog_model.h
mrk_apply_filter.cpp
mrk_apply_filter.h
CustomViews/mrk_marker.cpp
CustomViews/mrk_marker.h
)
NGL_WRAP_UI(mrk_common_gui_SRCS
CustomViews/mrk_marker.ui
)
NGL_ADD_LIBRARY2(WS MrkCommon SHARED ${mrk_common_gui_SRCS})
NGL_TARGET_LINK_LIBRARIES(MrkCommon
PRIVATE
NGLLogger
LtsSession
LtsSessionData
LtsUtilsGuiDds
OpmDataPluginInterface
FltDataPluginInterface
ngltools
PUBLIC
MrkDataPluginInterface
Qt5::Widgets
LtsWidgets
LtsDataView
)
@@ -0,0 +1,64 @@
/**
* @RDE_HEADER@
* CustomView for Exercises
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, NLE, 2019-08-01
*/
#include "mrk_marker.h"
#include "ui_mrk_marker.h"
#include "mrk_dialog_model.h"
#include <LtsUtilsCore/dds_vector_to_pixmap.h>
namespace MarkerManagement
{
CustomViewMarker::CustomViewMarker(QWidget *parent)
: AbstractDisplayWidget(parent)
, m_ui(new Ui::CustomViewMarker)
{
m_ui->setupUi(this);
m_ui->image->setMenuEnabled(false); // no menu !
m_ui->image->setDrawOuterRect(false);
#ifndef LTS_DEBUG
m_ui->lbOperator->setVisible(false);
#endif
}
CustomViewMarker::~CustomViewMarker()
{
delete m_ui;
}
bool CustomViewMarker::init(const QModelIndex &idx)
{
if (!idx.isValid())
return false;
const QString mrkNote = rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColNote).toString();
m_ui->lbMarkerNote->setText(mrkNote);
m_ui->lbMarkerNote->setToolTip(mrkNote);
m_ui->lbOperator->setText(rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColOperator).toString());
m_ui->lbTimestamp->setText(rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColTime).toString());
m_ui->lbType->setText(rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColType).toString());
m_ui->lbOffset->setText(rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColOffset).toString());
QPixmap img;
int fileId = rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColFileId).toInt();
if (fileId > 0)
{
QByteArray imgData = rowData(idx, MarkerManagement::MarkerManagementDialogModel::ColImage).toByteArray();
img = LtsUtils::getPixmap(imgData);
}
if (!img.isNull())
m_ui->image->setPixmap(img);
return true;
}
} // namespace MarkerManagement
@@ -0,0 +1,32 @@
/**
* @RDE_HEADER@
* CustomView for Exercises
* $Id$
* $HeadURL$
* $Author$
* Created by Iuliana Ojog, NLE, 2019-08-01
*/
#pragma once
#include <Viewer/LtsDataView/abstract_display_widget.h>
#include <Plugins/MarkerManagement/Gui/Common/mrkcommon_export.h>
namespace Ui
{
class CustomViewMarker;
}
namespace MarkerManagement
{
class MRKCOMMON_EXPORT CustomViewMarker final : public LtsDataView::AbstractDisplayWidget
{
Q_OBJECT
public:
explicit CustomViewMarker(QWidget *parent = nullptr);
~CustomViewMarker();
bool init(const QModelIndex &idx) override;
private:
Ui::CustomViewMarker* m_ui;
};
} // namespace MarkerManagement
@@ -0,0 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CustomViewMarker</class>
<widget class="QWidget" name="CustomViewMarker">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>351</width>
<height>140</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="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="LtsWidgets::LtsImageEditor" name="image">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lbMarkerNote">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">&lt;Marker Note with wordwrap&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lbOperator">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string notr="true">&lt;Operator&gt;</string>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblType">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="lbTimestamp">
<property name="text">
<string notr="true">&lt;Timestamp&gt;</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="lbOffset">
<property name="text">
<string notr="true">&lt;Offset&gt;</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="lbType">
<property name="text">
<string notr="true">&lt;Type&gt;</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblTime">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Time:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblOffset">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>Offset:</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsImageEditor</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_image_editor.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,227 @@
#include "mrk_apply_filter.h"
#include <QJsonParseError>
#include <QJsonObject>
#include <FilterManagement/flt_data_plugin_aes_display_filter.h>
#include <FilterManagement/flt_symbol_appearance_settings.h>
#include <FilterManagement/flt_building_cmpnt_settings.h>
#include <PluginInterfaces/gui_plugin_interface.h>
namespace MarkerManagement
{
MarkerManagementApplyFilter::MarkerManagementApplyFilter(LtsSession::LtsSession *session,
const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
const std::shared_ptr<FilterManagement::ForeignAesGuiInterface> &fltAesIfc,
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> &fltBuildingComponenIfc)
: m_session(session)
, m_fltParticipantIfc(fltParticipantIfc)
, m_fltAesIfc(fltAesIfc)
, m_fltBuildingComponentIfc(fltBuildingComponenIfc)
, m_logger(getLogger("MarkerManagementApplyFilter"))
{
std::shared_ptr<SituationMap::ForeignGuiInterface> spSitMapGuiIfc;
m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(spSitMapGuiIfc);
if (!spSitMapGuiIfc)
{
ERROR_LOG(m_logger) << "No spSitMapGuiIfc";
return;
}
m_sitMapGuiIfc = spSitMapGuiIfc;
}
const QJsonObject MarkerManagementApplyFilter::getFilterParamsJson() const
{
const int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
QJsonObject obj;
// SymbolAppearance
{
auto fltParticipantIfc = m_fltParticipantIfc.lock();
if (fltParticipantIfc)
{
std::shared_ptr<FilterManagement::SymbolAppearanceSettings> symbolAppearanceSettings =
fltParticipantIfc->symbolAppearanceForOperator(operatorId, m_session->workspaceId());
obj[QStringLiteral("SymbolAppearanceJson")] = symbolAppearanceSettings->settingsToJson();
}
else
WARNING_LOG(m_logger) << "cannot get filter as SymApp filter ifc is missing";
}
// AesFilter
{
auto fltIfcPtr = m_fltAesIfc.lock();
if (fltIfcPtr)
{
std::shared_ptr<FilterManagement::AesDisplayFilter> aesDisplayFilter =
fltIfcPtr->aesFilterForOperator(operatorId, m_session->workspaceId());
obj[QStringLiteral("AesFilterJson")] = aesDisplayFilter->filterToJson();
}
else
WARNING_LOG(m_logger) << "cannot get filter as aes filter ifc is missing";
}
// BuildingComponentSettings
{
auto fltIfcPtr = m_fltBuildingComponentIfc.lock();
if (fltIfcPtr)
{
std::shared_ptr<FilterManagement::BuildingComponentSettings> buildingComponentSettings =
fltIfcPtr->buildingComponentSettingsForOperator(operatorId, m_session->workspaceId());
obj[QStringLiteral("BuildingComponentSettingsJson")] = buildingComponentSettings->bldCmpSettingsToJson();
}
else
WARNING_LOG(m_logger) << "cannot get filter as BldgCmpnt filter ifc is missing";
}
return obj;
}
QByteArray MarkerManagementApplyFilter::getFilterParams() const
{
QJsonDocument jDoc(getFilterParamsJson());
return jDoc.toJson(QJsonDocument::Compact);
}
bool MarkerManagementApplyFilter::applyFilter(const QByteArray &filterContent)
{
if (filterContent.isEmpty())
{
ERROR_LOG(m_logger) << "filterContent is empty";
return false;
}
QJsonParseError parserError;
const QJsonDocument jDoc(QJsonDocument::fromJson(filterContent, &parserError));
if (parserError.error != QJsonParseError::NoError)
{
ERROR_LOG(m_logger) << "Error parsing json document: " << parserError.errorString();
return false;
}
return applyFilter(jDoc.object());
}
bool MarkerManagementApplyFilter::applyFilter(const QJsonObject &filterContent)
{
//
// 1. AesFilter
//
FilterManagement::AesFilter aesFilter;
{
const QJsonObject innerObj = filterContent[QStringLiteral("AesFilterJson")].toObject();
if (innerObj.isEmpty())
ERROR_LOG(m_logger) << "inner content AesFilterJson is empty";
else
aesFilter.content(QJsonDocument(innerObj).toJson().constData());
}
//
// 2. SymbolAppearance
//
FilterManagement::SymbolAppearance symbolAppearance;
{
QJsonObject innerObj = filterContent[QStringLiteral("SymbolAppearanceJson")].toObject();
if (innerObj.isEmpty())
ERROR_LOG(m_logger) << "inner content SymbolAppearanceJson is empty";
else
symbolAppearance.content(QJsonDocument(innerObj).toJson().constData());
}
//
// 3. BuildingComponentSettings
//
FilterManagement::BuildingComponentFilter buildingComponentFilter;
{
QJsonObject innerObj = filterContent[QStringLiteral("BuildingComponentSettingsJson")].toObject();
if (innerObj.isEmpty())
ERROR_LOG(m_logger) << "inner content BuildingComponentSettingsJson is empty";
else
buildingComponentFilter.content(QJsonDocument(innerObj).toJson().constData());
}
//
// finally save to Flt to enable reading in App Snapshot (SituationMap)
//
// following block is taken from:
// void InterfaceImpl::filterLoad(const QString &settingsGroup, const QString &filterPresetId)
// (Lts/Plugins/OperatorManagement/Gui/OperatorSettings/opm_settings_gui_plugin.cpp)
const int operatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
const QString &wsId_context = m_session->workspaceId(); // aka context
auto fltIfcPtr = m_fltAesIfc.lock();
auto fltParticipantIfc = m_fltParticipantIfc.lock();
auto fltBldgCmpntIfc = m_fltBuildingComponentIfc.lock();
if (fltParticipantIfc && fltIfcPtr)
{
//
// 1. AesFilter
aesFilter.id(0);
aesFilter.operatorId(operatorId);
aesFilter.sampleTime(0);
aesFilter.ctx(wsId_context.toStdString());
std::shared_ptr<FilterManagement::AesDisplayFilter> aesDisplayFilter
= fltIfcPtr->aesFilterForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), wsId_context);
aesDisplayFilter->setFilterFromData(aesFilter);
//
// 2. SymbolAppearance
symbolAppearance.id(0);
symbolAppearance.operatorId(operatorId);
symbolAppearance.sampleTime(0);
symbolAppearance.ctx(wsId_context.toStdString());
std::shared_ptr<FilterManagement::SymbolAppearanceSettings> appearanceSettings
= fltParticipantIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), wsId_context);
appearanceSettings->setSettingsFromData(symbolAppearance);
} else
WARNING_LOG(m_logger) << "cannot set filter as at least one filter ifc is missing (fltParticipantIfc|fltIfcPtr)";
// Nachtrag zu GUEZE-1769: since fltBuildingComponentIfc is optional:
if (fltBldgCmpntIfc)
{
// 3. BuildingComponentSettings
//
buildingComponentFilter.id(0);
buildingComponentFilter.operatorId(operatorId);
buildingComponentFilter.sampleTime(0);
buildingComponentFilter.ctx(wsId_context.toStdString());
std::shared_ptr<FilterManagement::BuildingComponentSettings> buildingComponentSettings
= fltBldgCmpntIfc->buildingComponentSettingsForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), wsId_context);
buildingComponentSettings->setBldCmpSettingsFromData(buildingComponentFilter);
}
else
WARNING_LOG(m_logger) << "cannot set filter as at least one filter ifc is missing (fltBldgCmpntIfc)";
return true;
}
bool MarkerManagementApplyFilter::applyMapSettings(const QByteArray &content)
{
auto spSitMapGuiIfc = m_sitMapGuiIfc.lock();
if (spSitMapGuiIfc)
{
spSitMapGuiIfc->setOperatorMapSettingsJson(content);
return true;
}
return false;
}
}
+43
View File
@@ -0,0 +1,43 @@
#pragma once
#include <MarkerManagement/logger.h>
#include <Plugins/MarkerManagement/Gui/Common/mrkcommon_export.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <FilterManagement/Data/flt_data_plugin.h>
#include <FilterManagement/flt_participant_plugin_interface.h>
#include <FilterManagement/flt_aes_plugin_interface.h>
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
namespace MarkerManagement
{
class MRKCOMMON_EXPORT MarkerManagementApplyFilter : public QObject
{
Q_OBJECT
public:
explicit MarkerManagementApplyFilter(LtsSession::LtsSession *session,
const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
const std::shared_ptr<FilterManagement::ForeignAesGuiInterface> &fltAesIfc,
const std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> &fltBuildingComponenIfc
);
bool applyFilter(const QJsonObject &filterContent);
bool applyFilter(const QByteArray &filterContent);
bool applyMapSettings(const QByteArray &content);
QByteArray getFilterParams() const;
const QJsonObject getFilterParamsJson() const;
private:
LtsSession::LtsSession *m_session;
// no hard dependency to avoid crash when app is closed before this dialog is closed
std::weak_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
std::weak_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
std::weak_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
std::weak_ptr<SituationMap::ForeignGuiInterface> m_sitMapGuiIfc;
LOGGER_T m_logger;
};
} // namespace MarkerManagement
@@ -0,0 +1,299 @@
/**
* @RDE_HEADER@
* HMI Plugin for MarkerManangement - Marker Overview Dialog Model
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#include "mrk_dialog_model.h"
#include <MarkerManagement/mrk_translation.h>
#include <OperatorManagement/opm_dtc.h>
#include <ngltools/ngltools_dtg.h>
#include <QBuffer>
#include <QSet>
#include <QTimer>
namespace MarkerManagement
{
//---------------------------------
// MarkerManagementDialogModel
//---------------------------------
MarkerManagementDialogModel::MarkerManagementDialogModel(QObject *parent)
: LtsWidgets::LtsAbstractTableModel<Marker>({tr("Note"),
tr("Operator"),
tr("Type"),
tr("Streams"),
tr("Time"),
tr("Offset [s]"),
tr("File Id"),
tr("Image")},
parent)
, m_logger(getLogger("MarkerManagementDialogModel"))
{}
bool MarkerManagementDialogModel::initModel(const std::shared_ptr<MarkerManagement::Interface::Dtc> &dtc,
const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc,
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmGui,
bool ignoreTimezone)
{
m_ignoreTimezone = ignoreTimezone;
if (!dtc)
return false;
m_flmGui = flmGui;
if (opmDtc)
{
auto cbUser = [this](const OperatorManagement::User &user)
{
m_operatorNames.insert(user.id(), QString::fromStdString(user.name()));
};
connect(opmDtc.get(), &OperatorManagement::Interface::Dtc::userChanged, this, cbUser);
opmDtc->users(cbUser);
}
connect(dtc.get(), &MarkerManagement::Interface::Dtc::markerChanged,
this, &MarkerManagementDialogModel::onDataChanged);
dtc->markers([this](const MarkerManagement::Marker &data) { insertRow(data); });
connect(this, &MarkerManagementDialogModel::rowsInserted, this, &MarkerManagementDialogModel::updateOperatorNames);
connect(this, &MarkerManagementDialogModel::rowsRemoved, this, &MarkerManagementDialogModel::updateOperatorNames);
updateOperatorNames();
return true;
}
void MarkerManagementDialogModel::setTimezoneHoursOffset(int timezoneHoursOffset)
{
m_timezoneHoursOffset = timezoneHoursOffset;
emit dataChanged(index(0, ColTime), index(rowCount()-1, ColTime), {Qt::DisplayRole});
}
void MarkerManagementDialogModel::loadPreview(int fileContentId, int rowId)
{
if (fileContentId <= 0 || m_previews.contains(fileContentId))
{
requestNextFileContent();
return;
}
// sadly m_flmGui->loadContent() is not async...
if (m_bFlmRequestInProgress)
{
m_requestedIds.push_back({fileContentId, rowId});
return;
}
m_bFlmRequestInProgress = true;
QByteArray byteArray;
if (m_flmGui->loadContent(fileContentId, byteArray, true) && byteArray.size() > 0)
{
DEBUG_LOG(m_logger) << "m_previews.insert fileContentId=" << fileContentId
<< " size Preview=" << byteArray.size();
QString str = QStringLiteral("<html><center><img src='data:image/png;base64,%1'></center></html>").arg(QString::fromLatin1(byteArray.toBase64()));
m_previews.insert(fileContentId, str);
emit dataChanged(index(rowId, 0), index(rowId, ColImage), {Qt::ToolTipRole});
}
else
m_previews.insert(fileContentId, QString());
m_bFlmRequestInProgress = false;
requestNextFileContent();
}
void MarkerManagementDialogModel::requestNextFileContent()
{
if (!m_bFlmRequestInProgress && !m_requestedIds.isEmpty())
{
auto next = m_requestedIds.takeLast();
QTimer::singleShot(0, this, [this, next] { loadPreview(next.first, next.second);});
}
}
QVariant MarkerManagementDialogModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (section == ColOperator && orientation == Qt::Horizontal && role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
return m_comboBoxFilterData;
return LtsWidgets::LtsAbstractTableModel<Marker>::headerData(section, orientation, role);
}
QVariant MarkerManagementDialogModel::data(const QModelIndex &index, int role) const
{
if (role != Qt::DisplayRole && role != LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole && role != Qt::ToolTipRole)
return QVariant();
if (!indexIsValid(index))
return QVariant();
const int row = index.row();
const MarkerManagement::Marker &marker = m_vecData.at(row);
if (role == LtsWidgets::LtsColumnFilterProxyModel::ComboboxFilterRole)
{
if (index.column() == ColOperator)
return marker.operatorId();
return QVariant();
}
if (role == Qt::ToolTipRole) // && index.column() == ColNote
{
const int fileContentId = marker.fileContentId();
if (fileContentId > 0)
{
auto it = m_previews.find(fileContentId);
if (it == m_previews.end())
{
auto that = const_cast<MarkerManagementDialogModel *>(this);
QTimer::singleShot(0, that, [that, fileContentId, row]() { that->loadPreview(fileContentId, row); });
return QVariant();
}
return it.value();
}
return QVariant();
}
if (role == Qt::DisplayRole)
{
switch (index.column())
{
case ColNote:
return QString::fromStdString(marker.note());
case ColOperator:
if (marker.operatorId() <= 0)
return tr("Global");
return m_operatorNames.value(marker.operatorId());
case ColType:
{
QStringList slTypes;
slTypes.reserve(marker.descriptions().size());
for (const MarkerManagement::MarkerDescription &desc : marker.descriptions())
slTypes.append(MarkerManagement::toString(desc.markerType()));
return slTypes.join(QStringLiteral(", "));
}
case ColStreams:
{
QString ret;
for (const MarkerManagement::MarkerDescription &desc : marker.descriptions())
{
if (desc.markerType() != MarkerManagement::MarkerType::Audio &&
desc.markerType() != MarkerManagement::MarkerType::Video)
continue;
if (!ret.isEmpty())
ret += QLatin1Char(',');
ret += QString::fromStdString(desc.content());
}
return ret;
}
case ColTime:
if (m_ignoreTimezone)
{
// TODO: ugly... (because returns the dt as string directly, breaking the MVC pattern) but if the A/V Topic Editor changes the timezone, this has to respond.... :( this (somewhat) breaks sorting for the A/V Topic Editor
// Not the job of the model (but for the view / delegate), but has to do it for now. \/
// \-------------------------------------/
return QDateTime::fromMSecsSinceEpoch(marker.timeStamp() + (m_timezoneHoursOffset * 3600 * 1000)).toString(QStringLiteral("dd.MM.yy HH:mm:ss"));
}
else
return QDateTime::fromMSecsSinceEpoch(marker.timeStamp() - marker.timeStampOffset());
case ColOffset:
return QVariant(marker.timeStampOffset() / 1000);
case ColFileId:
return marker.fileContentId();
case ColImage:
return m_previews.value(marker.fileContentId());
}
}
return QVariant();
}
void MarkerManagementDialogModel::updateOperatorNames()
{
QSet<int> operatorIds;
for (const auto &op : qAsConst(m_vecData))
operatorIds.insert(op.operatorId());
LtsWidgets::ComboboxFilterContent cfc;
LtsWidgets::ComboboxFilterData cfd;
cfc.data.reserve(operatorIds.size());
for (int operatorId : qAsConst(operatorIds))
{
cfd.data = operatorId;
cfd.text = m_operatorNames.value(operatorId);
cfc.data.push_back(cfd);
}
cfc.sortItems = true;
m_comboBoxFilterData = cfc.toVariant();
}
//
// MarkerSortFilterProxyModel
//
void MarkerSortFilterProxyModel::setSourceModel(QAbstractItemModel *model)
{
m_model = qobject_cast<MarkerManagementDialogModel*>(model);
LtsWidgets::LtsColumnFilterProxyModel::setSourceModel(model);
}
void MarkerSortFilterProxyModel::setOperatorId(int operatorId)
{
if (m_operatorId == operatorId)
return;
m_operatorId = operatorId;
invalidateFilter();
}
bool MarkerSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if (!m_model || m_operatorId < 0 || source_row < 0 || source_row >= m_model->rowCount(source_parent))
return LtsWidgets::LtsColumnFilterProxyModel::filterAcceptsRow(source_row, source_parent);
const MarkerManagement::Marker &marker = m_model->m_vecData.at(source_row);
if (!m_showOtherUsersMarkers)
{
bool bAccepted = marker.operatorId() == 0 ||
marker.operatorId() == m_operatorId;
if (!bAccepted)
return false;
}
return LtsWidgets::LtsColumnFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
bool MarkerSortFilterProxyModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (!m_model || source_left.column() != source_right.column())
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
const Marker &left = m_model->m_vecData.at(source_left.row());
const Marker &right = m_model->m_vecData.at(source_right.row());
switch (source_left.column())
{
case MarkerManagementDialogModel::ColTime:
return left.timeStamp() < right.timeStamp();
default:
break;
}
return LtsWidgets::LtsColumnFilterProxyModel::lessThan(source_left, source_right);
}
void MarkerSortFilterProxyModel::setShowOtherUsersMarkers(bool show)
{
if (show == m_showOtherUsersMarkers)
return;
m_showOtherUsersMarkers = show;
invalidateFilter();
}
} // namespace MarkerManagement
+97
View File
@@ -0,0 +1,97 @@
/**
* @RDE_HEADER@
* HMI Plugin for MarkerManangement - Marker Overview Dialog Model
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#pragma once
#include <MarkerManagement/mrk_dtc.h>
#include <MarkerManagement/logger.h>
#include <Plugins/MarkerManagement/Gui/Common/mrkcommon_export.h>
#include <FileManagement/flm_explorer_gui_plugin_interface.h>
#include <LtsWidgets/lts_abstract_table_model.h>
#include <LtsWidgets/lts_column_filter_proxy_model.h>
namespace OperatorManagement
{
namespace Interface
{
class Dtc;
}
}
namespace MarkerManagement
{
// --------------------------------------------------------
// MarkerManagementModel
// --------------------------------------------------------
class MRKCOMMON_EXPORT MarkerManagementDialogModel : public LtsWidgets::LtsAbstractTableModel<Marker>
{
Q_OBJECT
public:
enum Columns
{
ColNote,
ColOperator,
ColType,
ColStreams,
ColTime,
ColOffset,
ColFileId,
ColImage
};
explicit MarkerManagementDialogModel(QObject *parent = nullptr);
bool initModel(const std::shared_ptr<MarkerManagement::Interface::Dtc> &dtc,
const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc,
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmGui,
bool ignoreTimezone = false);
QVariant headerData(int section, Qt::Orientation orientation, int role) const override final;
QVariant data(const QModelIndex &index, int role = Qt::UserRole) const override final;
public slots:
void setTimezoneHoursOffset(int timezoneHoursOffset);
private slots:
void updateOperatorNames();
void loadPreview(int fileContentId, int rowId);
private:
void requestNextFileContent();
private:
QHash<int, QString> m_operatorNames;
QHash<int, QString> m_previews; // QString as base64 encoded image data
QVector<QPair<int, int>> m_requestedIds; // fileId, rowId
bool m_bFlmRequestInProgress {false};
QVariant m_comboBoxFilterData;
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
int m_timezoneHoursOffset {0};
bool m_ignoreTimezone {false};
LOGGER_T m_logger;
friend class MarkerSortFilterProxyModel;
};
class MRKCOMMON_EXPORT MarkerSortFilterProxyModel : public LtsWidgets::LtsColumnFilterProxyModel
{
Q_OBJECT
public:
using LtsWidgets::LtsColumnFilterProxyModel::LtsColumnFilterProxyModel;
void setSourceModel(QAbstractItemModel *model) override;
void setOperatorId(int operatorId);
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
void setShowOtherUsersMarkers(bool show);
private:
MarkerManagementDialogModel *m_model {nullptr};
int m_operatorId {-1};
bool m_showOtherUsersMarkers {false};
};
}