Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#
|
||||
# @RDE_HEADER@
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Christian Ehrlicher, SLSE, 2017-06-16
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(Data)
|
||||
ADD_SUBDIRECTORY(Gui/FilterChange)
|
||||
ADD_SUBDIRECTORY(Gui/Aes)
|
||||
ADD_SUBDIRECTORY(Gui/Participant)
|
||||
ADD_SUBDIRECTORY(Gui/BuildingComponents)
|
||||
|
||||
#
|
||||
# Data Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(
|
||||
FltDataPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_data_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
DataPluginInterface
|
||||
svcFltCommon
|
||||
svcAesCommon
|
||||
)
|
||||
add_dependencies(FltDataPluginInterface svcAesCommon)
|
||||
TARGET_SOURCES(FltDataPluginInterface
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_building_cmpnt_settings.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_data_plugin_aes_display_filter.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_symbol_appearance_settings.h
|
||||
)
|
||||
|
||||
#
|
||||
# Building-Component Filter Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(FltBldgCmpntGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_building_cmpnt_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
GuiPluginInterface
|
||||
FltDataPluginInterface
|
||||
)
|
||||
|
||||
#
|
||||
# Aes Filter Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(FltAesGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_aes_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
GuiPluginInterface
|
||||
FltDataPluginInterface
|
||||
)
|
||||
|
||||
#
|
||||
# Participant Filter Gui Plugin Interface
|
||||
#
|
||||
ADD_INTERFACE_LIBRARY(FltParticipantGuiPluginInterface
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/flt_participant_plugin_interface.h
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/..
|
||||
GuiPluginInterface
|
||||
)
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# @RDE_HEADER@
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Christian Ehrlicher, SLSE, 2017-06-19
|
||||
#
|
||||
|
||||
#
|
||||
# Data Plugin
|
||||
#
|
||||
SET(SRCS
|
||||
flt_data_plugin.cpp
|
||||
flt_data_plugin.h
|
||||
)
|
||||
NGL_ADD_LIBRARY(WS FltDataPlugin MODULE ${SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(FltDataPlugin
|
||||
Qt5::Core
|
||||
FltDataPluginInterface
|
||||
PpmDataPluginInterface
|
||||
svcFltClient
|
||||
svcAesCommon # generated header only ...
|
||||
NGLLogger
|
||||
LtsSessionData
|
||||
LtsSessionDataDds
|
||||
)
|
||||
NGL_INSTALL_TARGET(FltDataPlugin)
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#include "flt_data_plugin.h"
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
#include <LtsSession/lts_session_data_dds.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
//
|
||||
// DataPlugin
|
||||
//
|
||||
std::shared_ptr<DataPluginBase::Interface> DataPlugin::createDataInterface(LtsSession::LtsSessionDataDds *session)
|
||||
{
|
||||
std::shared_ptr<Interface::Dtc> dtc;
|
||||
std::shared_ptr<Interface::Ftc> ftc;
|
||||
if (!session->createTopicClient(dtc, ftc))
|
||||
return std::shared_ptr<DataPluginBase::Interface>();
|
||||
return std::make_shared<DataInterfaceImpl>(dtc, ftc);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// DataInterfaceImpl
|
||||
//
|
||||
DataInterfaceImpl::DataInterfaceImpl(const std::shared_ptr<FilterManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<FilterManagement::Interface::Ftc> &ftc)
|
||||
: DataInterface()
|
||||
, m_dtc(dtc)
|
||||
, m_ftc(ftc)
|
||||
{}
|
||||
|
||||
} // namespace FilterManagement
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PluginInterfaces/data_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
//
|
||||
// DataPlugin
|
||||
//
|
||||
class DataPlugin final : public QObject, public DataPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "data:3:flt")
|
||||
Q_INTERFACES(DataPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataPlugin() = default;
|
||||
~DataPlugin() = default;
|
||||
|
||||
QString pluginName() const override { return QStringLiteral("FilterManagement"); }
|
||||
std::shared_ptr<DataPluginBase::Interface> createDataInterface(LtsSession::LtsSessionDataDds *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return partition == IDL::PartitionType::Exercise ||
|
||||
partition == IDL::PartitionType::Global ||
|
||||
partition == IDL::PartitionType::Replay;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// DataInterfaceImpl
|
||||
//
|
||||
class DataInterfaceImpl final : public QObject, public DataInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DataInterfaceImpl(const std::shared_ptr<FilterManagement::Interface::Dtc> &dtc,
|
||||
const std::shared_ptr<FilterManagement::Interface::Ftc> &ftc);
|
||||
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> getDtc() override { return m_dtc; }
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> getFtc() override { return m_ftc; }
|
||||
private:
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_dtc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_ftc;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Christian Ehrlicher, SLSE, 2017-06-16
|
||||
#
|
||||
|
||||
ADD_SUBDIRECTORY(Common)
|
||||
|
||||
SET(flt_aes_widget_SRCS
|
||||
flt_aes_filter_widget.cpp
|
||||
flt_aes_filter_widget.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(flt_aes_widget_SRCS
|
||||
flt_aes_filter_widget.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS FltAesWidget STATIC ${flt_aes_widget_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(FltAesWidget
|
||||
PRIVATE
|
||||
svcFltCommon
|
||||
LtsProjectionWorkstation
|
||||
PUBLIC
|
||||
FltDataPluginInterface
|
||||
LtsSessionData
|
||||
PdmGuiPluginInterface
|
||||
PpmGuiComboboxPluginInterface
|
||||
Qt5::Widgets
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(FltAesWidget
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
||||
)
|
||||
|
||||
SET(flt_aes_gui_SRCS
|
||||
flt_aes_filter_dialog.cpp
|
||||
flt_aes_filter_dialog.h
|
||||
flt_aes_gui_plugin.cpp
|
||||
flt_aes_gui_plugin.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS FltAesGuiPlugin MODULE ${flt_aes_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(FltAesGuiPlugin
|
||||
FltAesGuiCommon
|
||||
FltAesGuiPluginInterface
|
||||
FltAesWidget
|
||||
FltFilterChange
|
||||
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
LtsWidgets
|
||||
Qt5::Widgets
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(FltAesGuiPlugin)
|
||||
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Mike Wille, SLSE, 2017-11-27
|
||||
#
|
||||
|
||||
SET(flt_aes_gui_common_SRCS
|
||||
common.h
|
||||
aes_display_filter_impl.h
|
||||
aes_display_filter_impl.cpp
|
||||
building_cmpnt_settings_impl.cpp
|
||||
building_cmpnt_settings_impl.h
|
||||
symbol_appearance_settings_impl.h
|
||||
symbol_appearance_settings_impl.cpp
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS FltAesGuiCommon SHARED ${flt_aes_gui_common_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(FltAesGuiCommon
|
||||
PRIVATE
|
||||
svcPpmCommon
|
||||
PUBLIC
|
||||
FltDataPluginInterface
|
||||
Qt5::Core
|
||||
Qt5::Widgets # ifdef LTS_DEBUG QMessageBox
|
||||
svcFltCommon
|
||||
svcAesCommon
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(FltAesGuiCommon)
|
||||
@@ -0,0 +1,480 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#include "aes_display_filter_impl.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
static inline std::vector<AreaEffectSimulation::AesType> aesTypes()
|
||||
{
|
||||
return { AreaEffectSimulation::AesType::AtNContamination,
|
||||
AreaEffectSimulation::AesType::AtBCContamination,
|
||||
AreaEffectSimulation::AesType::AtExplosionArea,
|
||||
AreaEffectSimulation::AesType::AtExplosionSingle,
|
||||
AreaEffectSimulation::AesType::AtMineArea,
|
||||
AreaEffectSimulation::AesType::AtMineCorridor,
|
||||
AreaEffectSimulation::AesType::AtDangerArea,
|
||||
AreaEffectSimulation::AesType::AtFunctionalArea,
|
||||
AreaEffectSimulation::AesType::AtBorderline,
|
||||
AreaEffectSimulation::AesType::AtMineAreaSingleMines, // Only IED-Filter
|
||||
AreaEffectSimulation::AesType::AtDusSingleMine,
|
||||
AreaEffectSimulation::AesType::AtGasPipe,
|
||||
AreaEffectSimulation::AesType::AtTechnicalArea,
|
||||
AreaEffectSimulation::AesType::AtAirSupportImpact
|
||||
};
|
||||
}
|
||||
//
|
||||
// AesDisplayFilterImpl
|
||||
//
|
||||
AesDisplayFilterImpl::AesDisplayFilterImpl()
|
||||
: AesDisplayFilter()
|
||||
, m_visiblePartiesCheck(nullptr)
|
||||
, m_logger(getLogger("AesDisplayFilterImpl"))
|
||||
{
|
||||
resetAesDisplayFilter();
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::resetAesDisplayFilter()
|
||||
{
|
||||
resetAesDisplayFilterInternal(true);
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::resetAesDisplayFilterInternal(bool executeCallback)
|
||||
{
|
||||
m_effectStateMap.clear();
|
||||
for (AreaEffectSimulation::AesType aesType : aesTypes())
|
||||
{
|
||||
m_effectStateMap.insert(aesType, EffectStateStruct());
|
||||
|
||||
// set default to false;
|
||||
if (AreaEffectSimulation::AesType::AtTechnicalArea == aesType.underlying())
|
||||
m_effectStateMap[AreaEffectSimulation::AesType::AtTechnicalArea].displayActivated = false;
|
||||
|
||||
if (executeCallback)
|
||||
callFilterChangedCb(aesType);
|
||||
}
|
||||
}
|
||||
|
||||
AesDisplayFilterImpl::~AesDisplayFilterImpl()
|
||||
{}
|
||||
|
||||
bool AesDisplayFilterImpl::setFilterFromData(const AesFilter &filterData)
|
||||
{
|
||||
if (m_ddsFilterContent.id() == 0)
|
||||
m_ddsFilterContent = filterData;
|
||||
else
|
||||
m_ddsFilterContent.content(filterData.content());
|
||||
|
||||
const QByteArray content(QByteArray::fromRawData(m_ddsFilterContent.content().c_str(), m_ddsFilterContent.content().size()));
|
||||
|
||||
if (content.isEmpty())
|
||||
return true;
|
||||
|
||||
QJsonParseError parserError;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
|
||||
if (parserError.error != QJsonParseError::NoError)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Error parsing json document: " << parserError.errorString();
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson(QJsonDocument::Compact);
|
||||
const QJsonObject obj(doc.object());
|
||||
|
||||
return setFilterFromData(obj);
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::setFilterFromData(const QJsonObject &filterData)
|
||||
{
|
||||
if (filterData.isEmpty())
|
||||
{
|
||||
resetAesDisplayFilterInternal(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto oldEffectStateMap(m_effectStateMap);
|
||||
|
||||
// GUEZE-3266 Playback Wirksimulationsfilter
|
||||
// clear after if(content.isEmpty()) or else we are deleting the default filter
|
||||
// Do not use clear() and remove all entries. Just clear/reset the values:
|
||||
// // m_effectStateMap.clear();
|
||||
resetAesDisplayFilterInternal(false);
|
||||
|
||||
// 1st: recognize which aesType has changes...
|
||||
std::vector<AreaEffectSimulation::AesType> aesTypesWithChanges;
|
||||
aesTypesWithChanges.reserve(aesTypes().size());
|
||||
|
||||
for (AreaEffectSimulation::AesType aesType : aesTypes())
|
||||
if (parseFilterData(filterData, aesType, oldEffectStateMap))
|
||||
aesTypesWithChanges.emplace_back(aesType);
|
||||
|
||||
// 2nd: AFTERWARDS call callbacks:
|
||||
// Benefit: (GUEZE-3266)
|
||||
// The callback (especially AesFilterWidget, AesFilterDialog)
|
||||
// gets updated with a _completed_ m_effectStateMap
|
||||
for (AreaEffectSimulation::AesType aesType : qAsConst(aesTypesWithChanges))
|
||||
callFilterChangedCb(aesType);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject AesDisplayFilterImpl::filterToJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
for (AreaEffectSimulation::AesType aesType : aesTypes())
|
||||
addFilterData(obj, aesType);
|
||||
return obj;
|
||||
}
|
||||
|
||||
AesFilter AesDisplayFilterImpl::filterToData() const
|
||||
{
|
||||
AesFilter ret(m_ddsFilterContent);
|
||||
const QJsonDocument doc(filterToJson());
|
||||
ret.content(doc.toJson(QJsonDocument::Compact).constData());
|
||||
return ret;
|
||||
}
|
||||
|
||||
// check isCentral:
|
||||
bool displayCentralPeripheralHelper(const AesDisplayFilter::EffectStateStruct &ess, const bool isCentral)
|
||||
{
|
||||
if (isCentral)
|
||||
return ess.displayCentral;
|
||||
else
|
||||
return ess.displayPeripheral;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AesDisplayFilterImpl::isVisible(AreaEffectSimulation::AesType aesType,
|
||||
AreaEffectSimulation::AesEffectState aesState,
|
||||
int chargeTypeId,
|
||||
int partyId,
|
||||
bool isCentral,
|
||||
qint64 effectStart,
|
||||
qint64 effectDuration,
|
||||
qint64 currentTimeMSec) const
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "visible check for " << aesType << " - state: " << aesState
|
||||
<< ", charge: " << chargeTypeId << ", party: " << partyId
|
||||
<< ", isCentral: " << isCentral
|
||||
<< ", effectstart: " << effectStart
|
||||
<< ", duration: " << effectDuration
|
||||
<< ", now: " << currentTimeMSec
|
||||
<< ", ==> age: " << currentTimeMSec - effectStart;
|
||||
|
||||
// check if party is visible to operator
|
||||
if ((partyId > -1) && (m_visiblePartiesCheck && !m_visiblePartiesCheck(partyId)))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Operator is not allowed to see aes for party " << partyId;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((partyId > -1) && (m_visiblePartiesCheck && !m_visiblePartiesCheck(partyId)))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Operator is not allowed to see aes for party " << partyId;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
// not found -> visible every time
|
||||
if (it == m_effectStateMap.end())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "No filter entry for " << aesType << " - always visible";
|
||||
return true;
|
||||
}
|
||||
|
||||
const EffectStateStruct &ess = *it;
|
||||
// filter auf chargeTypeId und chargeTypeId nicht in container -> nicht sichtbar
|
||||
if (ess.limitOnChargeTypes && chargeTypeId > 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "filtering for chargeType... ";
|
||||
if (!ess.visibleChargeTypeIds.contains(chargeTypeId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "... is NOT allowed";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "... is allowed";
|
||||
}
|
||||
|
||||
if (!displayCentralPeripheralHelper(ess, isCentral))
|
||||
return false;
|
||||
|
||||
if (ess.limitOnParties && partyId > 0)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "filtering for partyId... ";
|
||||
if (!ess.visiblePartyIds.contains(partyId))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "... is NOT allowed";
|
||||
return false;
|
||||
}
|
||||
else
|
||||
DEBUG_LOG(m_logger) << "... is allowed";
|
||||
}
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "filtering for state ... ";
|
||||
switch (aesState.underlying())
|
||||
{
|
||||
case AreaEffectSimulation::AesEffectState_def::EsCreated:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsReceived:
|
||||
DEBUG_LOG(m_logger) << "... created/received visible: " << ess.displayCreated;
|
||||
return ess.displayCreated;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsPrepared:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsFired:
|
||||
DEBUG_LOG(m_logger) << "... prepared/fired visible: " << ess.displayPrepared;
|
||||
return ess.displayPrepared;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsActivated:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsPaused:
|
||||
DEBUG_LOG(m_logger) << "... active/paused visible: " << ess.displayActivated;
|
||||
return ess.displayActivated;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsExpired:
|
||||
{
|
||||
// afterglow only supported for some types
|
||||
if (aesType != AreaEffectSimulation::AesType::AtAirSupportImpact &&
|
||||
aesType != AreaEffectSimulation::AesType::AtExplosionSingle &&
|
||||
aesType != AreaEffectSimulation::AesType::AtExplosionArea &&
|
||||
aesType != AreaEffectSimulation::AesType::AtMineCorridor &&
|
||||
aesType != AreaEffectSimulation::AesType::AtMineAreaSingleMines &&
|
||||
aesType != AreaEffectSimulation::AesType::AtDusSingleMine &&
|
||||
aesType != AreaEffectSimulation::AesType::AtGasPipe &&
|
||||
aesType != AreaEffectSimulation::AesType::AtMineArea
|
||||
)
|
||||
return false;
|
||||
|
||||
const auto displayEnd = effectStart + effectDuration + ess.expiredAfterglowDurationMSec;
|
||||
DEBUG_LOG(m_logger) << "... expired visible: " << (currentTimeMSec < displayEnd)
|
||||
<< ", calc expiry time: " << displayEnd
|
||||
<< ", return: " << (currentTimeMSec < displayEnd);
|
||||
return (currentTimeMSec < displayEnd);
|
||||
}
|
||||
case AreaEffectSimulation::AesEffectState_def::EsRemoved:
|
||||
DEBUG_LOG(m_logger) << "... removed - NOT visible";
|
||||
return false;
|
||||
case AreaEffectSimulation::AesEffectState_def::EsUnknown:
|
||||
case AreaEffectSimulation::AesEffectState_def::EsError:
|
||||
break; // unknown -> display
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << "... unknown - visible";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showDetails(AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
// not found -> visible every time
|
||||
if (it == m_effectStateMap.end())
|
||||
return true;
|
||||
|
||||
const EffectStateStruct &ess = *it;
|
||||
return ess.showDetails;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showDetails2(AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
// not found -> visible every time
|
||||
if (it == m_effectStateMap.end())
|
||||
return true;
|
||||
|
||||
const EffectStateStruct &ess = *it;
|
||||
return ess.showDetails2;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showDetails3(AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
// not found -> visible every time
|
||||
if (it == m_effectStateMap.end())
|
||||
return true;
|
||||
|
||||
const EffectStateStruct &ess = *it;
|
||||
return ess.showDetails3;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showDetails4(AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
// not found -> visible every time
|
||||
if (it == m_effectStateMap.end())
|
||||
return true;
|
||||
|
||||
const EffectStateStruct &ess = *it;
|
||||
return ess.showDetails4;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showDetails5(AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
// not found -> visible every time
|
||||
if (it == m_effectStateMap.end())
|
||||
return true;
|
||||
|
||||
const EffectStateStruct &ess = *it;
|
||||
return ess.showDetails5;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showExplosionClusterMeanHitPoint() const
|
||||
{
|
||||
return showDetails2(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showExplosionClusterGunToTargetLine() const
|
||||
{
|
||||
return showDetails3(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showExplosionClusterTrajectory() const
|
||||
{
|
||||
return showDetails4(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::showExplosionClusterDetonationSphere() const
|
||||
{
|
||||
return showDetails5(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
}
|
||||
bool AesDisplayFilterImpl::showNotTriggeredCDMine() const
|
||||
{
|
||||
return showDetails2(AreaEffectSimulation::AesType::AtMineArea);
|
||||
}
|
||||
|
||||
AesDisplayFilterImpl::EffectStateStruct AesDisplayFilterImpl::effectStateFilter(AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
// if (m_logger.isDebugEnabled())
|
||||
if (!m_effectStateMap.contains(aesType.underlying()))
|
||||
WARNING_LOG(m_logger) << "AesType not found!!! " << aesType;
|
||||
|
||||
return m_effectStateMap.value(aesType.underlying());
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::setEffectStateFilter(AreaEffectSimulation::AesType aesType, const EffectStateStruct &ess)
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
if (it != m_effectStateMap.end())
|
||||
{
|
||||
if (*it == ess)
|
||||
return;
|
||||
*it = ess;
|
||||
}
|
||||
else
|
||||
m_effectStateMap[aesType] = ess;
|
||||
|
||||
callFilterChangedCb(aesType);
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::addChangedCallback(FilterChangedCallback *cb)
|
||||
{
|
||||
m_filterChangedCb.removeAll(cb); // avoid duplicates
|
||||
m_filterChangedCb.push_back(cb);
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::removeChangedCallback(FilterChangedCallback *cb)
|
||||
{
|
||||
m_filterChangedCb.removeAll(cb);
|
||||
}
|
||||
|
||||
static inline QSet<int> fromJsonIntArray(const QJsonValue &obj)
|
||||
{
|
||||
QSet<int> ret;
|
||||
const QJsonArray arrayContent = obj.toArray();
|
||||
for (const auto &ele : arrayContent)
|
||||
ret.insert(ele.toInt());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QJsonArray toJsonIntArray(const QSet<int> &data)
|
||||
{
|
||||
QJsonArray ret;
|
||||
for (int i : data)
|
||||
ret += i;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool AesDisplayFilterImpl::parseFilterData(const QJsonObject &obj,
|
||||
AreaEffectSimulation::AesType aesType,
|
||||
const QMap<AreaEffectSimulation::AesType, EffectStateStruct> &orig)
|
||||
{
|
||||
const QString strType = QString::number(static_cast<int>(aesType.underlying()));
|
||||
const QJsonObject inner = obj.value(strType).toObject();
|
||||
if (inner.isEmpty())
|
||||
return false;
|
||||
DEBUG_LOG(m_logger) << "Parsing filter data for " << aesType
|
||||
<< ", json: " << QJsonDocument(inner).toJson();
|
||||
EffectStateStruct &ess = m_effectStateMap[aesType];
|
||||
ess.displayCreated = inner.value(QStringLiteral("created")).toBool(ess.displayCreated);
|
||||
ess.displayPrepared = inner.value(QStringLiteral("prepared")).toBool(ess.displayPrepared);
|
||||
ess.displayActivated = inner.value(QStringLiteral("activated")).toBool(ess.displayActivated);
|
||||
ess.displayCentral = inner.value(QStringLiteral("central")).toBool(ess.displayCentral);
|
||||
ess.displayPeripheral = inner.value(QStringLiteral("peripheral")).toBool(ess.displayPeripheral);
|
||||
ess.showDetails2 = inner.value(QStringLiteral("showDetails2")).toBool(ess.showDetails2);
|
||||
ess.showDetails3 = inner.value(QStringLiteral("showDetails3")).toBool(ess.showDetails3);
|
||||
ess.showDetails4 = inner.value(QStringLiteral("showDetails4")).toBool(ess.showDetails4);
|
||||
ess.showDetails5 = inner.value(QStringLiteral("showDetails5")).toBool(ess.showDetails5);
|
||||
ess.limitOnChargeTypes = inner.value(QStringLiteral("limitOnChargeTypes")).toBool(ess.limitOnChargeTypes);
|
||||
ess.limitOnParties = inner.value(QStringLiteral("limitOnParties")).toBool(ess.limitOnParties);
|
||||
ess.showDetails = inner.value(QStringLiteral("showDetails")).toBool(ess.showDetails);
|
||||
ess.expiredAfterglowDurationMSec = inner.value(QStringLiteral("afterglow")).toInt(ess.expiredAfterglowDurationMSec);
|
||||
if (ess.expiredAfterglowDurationMSec < 0)
|
||||
ess.expiredAfterglowDurationMSec = 10 * 1000;
|
||||
|
||||
ess.visibleChargeTypeIds = fromJsonIntArray(inner.value(QStringLiteral("chargeTypes")));
|
||||
ess.visiblePartyIds = fromJsonIntArray(inner.value(QStringLiteral("partyIds")));
|
||||
|
||||
return (ess != orig.value(aesType));
|
||||
|
||||
// if (ess != orig.value(aesType))
|
||||
// callFilterChangedCb(aesType);
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::addFilterData(QJsonObject &obj, AreaEffectSimulation::AesType aesType) const
|
||||
{
|
||||
auto it = m_effectStateMap.find(aesType);
|
||||
if (it == m_effectStateMap.end())
|
||||
return;
|
||||
const EffectStateStruct &ess = *it;
|
||||
|
||||
QJsonObject inner;
|
||||
inner[QStringLiteral("created")] = ess.displayCreated;
|
||||
inner[QStringLiteral("prepared")] = ess.displayPrepared;
|
||||
inner[QStringLiteral("activated")] = ess.displayActivated;
|
||||
inner[QStringLiteral("central")] = ess.displayCentral;
|
||||
inner[QStringLiteral("peripheral")] = ess.displayPeripheral;
|
||||
inner[QStringLiteral("showDetails2")] = ess.showDetails2;
|
||||
inner[QStringLiteral("showDetails3")] = ess.showDetails3;
|
||||
inner[QStringLiteral("showDetails4")] = ess.showDetails4;
|
||||
inner[QStringLiteral("showDetails5")] = ess.showDetails5;
|
||||
inner[QStringLiteral("limitOnChargeTypes")] = ess.limitOnChargeTypes;
|
||||
inner[QStringLiteral("limitOnParties")] = ess.limitOnParties;
|
||||
inner[QStringLiteral("showDetails")] = ess.showDetails;
|
||||
inner[QStringLiteral("afterglow")] = ess.expiredAfterglowDurationMSec;
|
||||
|
||||
if (!ess.visibleChargeTypeIds.isEmpty())
|
||||
inner[QStringLiteral("chargeTypes")] = toJsonIntArray(ess.visibleChargeTypeIds);
|
||||
if (!ess.visiblePartyIds.isEmpty())
|
||||
inner[QStringLiteral("partyIds")] = toJsonIntArray(ess.visiblePartyIds);
|
||||
|
||||
const QString strType = QString::number(static_cast<int>(aesType.underlying()));
|
||||
obj[strType] = inner;
|
||||
}
|
||||
|
||||
void AesDisplayFilterImpl::callFilterChangedCb(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", call cbs, START, size=" << m_filterChangedCb.size();
|
||||
for (auto *ptr : qAsConst(m_filterChangedCb)){
|
||||
ptr->onAesDisplayFilterChanged(aesType);
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", call cbs, END, size=" << m_filterChangedCb.size();
|
||||
}
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/fltaesguicommon_export.h>
|
||||
#include <FilterManagement/flt_data_plugin_aes_display_filter.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <QVector>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
//
|
||||
// AesDisplayFilterImpl
|
||||
//
|
||||
class FLTAESGUICOMMON_EXPORT AesDisplayFilterImpl final : public AesDisplayFilter
|
||||
{
|
||||
public:
|
||||
AesDisplayFilterImpl();
|
||||
~AesDisplayFilterImpl();
|
||||
|
||||
virtual void resetAesDisplayFilter() override;
|
||||
|
||||
bool setFilterFromData(const AesFilter &filterData) override;
|
||||
bool setFilterFromData(const QJsonObject &filterData) override;
|
||||
|
||||
QJsonObject filterToJson() const override;
|
||||
AesFilter filterToData() const override;
|
||||
|
||||
bool isVisible(AreaEffectSimulation::AesType aesType,
|
||||
AreaEffectSimulation::AesEffectState aesState,
|
||||
int chargeTypeId,
|
||||
int partyId,
|
||||
bool isCentral,
|
||||
qint64 effectStart,
|
||||
qint64 effectDuration,
|
||||
qint64 currentTimeMSec) const override;
|
||||
bool showDetails(AreaEffectSimulation::AesType aesType) const override;
|
||||
|
||||
|
||||
EffectStateStruct effectStateFilter(AreaEffectSimulation::AesType aesType) const override;
|
||||
void setEffectStateFilter(AreaEffectSimulation::AesType aesType,
|
||||
const EffectStateStruct &ess) override;
|
||||
int maxAfterglowDurationMSec() const override { return 4 * 60 * 1000; } // 1h -> 4min
|
||||
|
||||
void addChangedCallback(FilterChangedCallback *cb) override;
|
||||
void removeChangedCallback(FilterChangedCallback *cb) override;
|
||||
|
||||
void setVisiblePartiesCheck(const std::function<bool(int)> &cb) override
|
||||
{
|
||||
m_visiblePartiesCheck = cb;
|
||||
}
|
||||
|
||||
bool hasChangedCallbacks() { return !m_filterChangedCb.empty() ;}
|
||||
int changedCallbackCount() { return m_filterChangedCb.size() ;}
|
||||
|
||||
/*! ExplosionCluster */
|
||||
//@{
|
||||
bool showExplosionClusterGunToTargetLine() const override;
|
||||
bool showExplosionClusterMeanHitPoint() const override;
|
||||
bool showExplosionClusterTrajectory() const override;
|
||||
bool showExplosionClusterDetonationSphere() const override;
|
||||
bool showNotTriggeredCDMine() const override;
|
||||
protected:
|
||||
bool showDetails2(AreaEffectSimulation::AesType aesType) const;
|
||||
bool showDetails3(AreaEffectSimulation::AesType aesType) const;
|
||||
bool showDetails4(AreaEffectSimulation::AesType aesType) const;
|
||||
bool showDetails5(AreaEffectSimulation::AesType aesType) const;
|
||||
//@}
|
||||
private:
|
||||
// returns true if filter changed
|
||||
bool parseFilterData(const QJsonObject &obj,
|
||||
AreaEffectSimulation::AesType aesType,
|
||||
const QMap<AreaEffectSimulation::AesType, EffectStateStruct> &orig);
|
||||
void addFilterData(QJsonObject &obj, AreaEffectSimulation::AesType aesType) const;
|
||||
void callFilterChangedCb(AreaEffectSimulation::AesType aesType);
|
||||
|
||||
void resetAesDisplayFilterInternal(bool executeCallback);
|
||||
|
||||
private:
|
||||
QMap<AreaEffectSimulation::AesType, EffectStateStruct> m_effectStateMap;
|
||||
QVector<FilterChangedCallback *> m_filterChangedCb;
|
||||
AesFilter m_ddsFilterContent;
|
||||
std::function<bool(int)> m_visiblePartiesCheck;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#include "building_cmpnt_settings_impl.h"
|
||||
#include "common.h"
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
//
|
||||
// BuildingComponentSettingsImpl
|
||||
//
|
||||
BuildingComponentSettingsImpl::BuildingComponentSettingsImpl(const QString &workspaceId)
|
||||
: BuildingComponentSettings()
|
||||
, m_workspaceId(workspaceId)
|
||||
, m_logger(getLogger("BuildingComponentSettingsImpl"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
resetBuildingComponentSettings();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
}
|
||||
|
||||
BuildingComponentSettingsImpl::~BuildingComponentSettingsImpl()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsImpl::resetBuildingComponentSettings()
|
||||
{
|
||||
setBldCmpSettings(BldCmpSettings());
|
||||
}
|
||||
|
||||
bool BuildingComponentSettingsImpl::setBldCmpSettingsFromData(const BuildingComponentFilter &filterData)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
|
||||
m_ddsFilterContent = filterData;
|
||||
|
||||
const QByteArray content(QByteArray::fromRawData(m_ddsFilterContent.content().c_str(), m_ddsFilterContent.content().size()));
|
||||
|
||||
if (content.isEmpty())
|
||||
return true;
|
||||
|
||||
QJsonParseError parserError;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
|
||||
if (parserError.error != QJsonParseError::NoError)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Error parsing json document: " << parserError.errorString();
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
|
||||
const QJsonObject obj(doc.object());
|
||||
|
||||
if (obj.isEmpty())
|
||||
return false;
|
||||
|
||||
|
||||
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
|
||||
BldCmpSettings settings;
|
||||
if (!settingsFromJsonInternal(doc.object(), settings))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "json to parse: " << doc.toJson();
|
||||
return false;
|
||||
}
|
||||
|
||||
setBldCmpSettings(settings); // will update callbacks
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject BuildingComponentSettingsImpl::bldCmpSettingsToJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
const BuildingComponentSettings::BldCmpSettings::BuildingSettings &buildingSettings = m_bldCmpSettings.buildingSettings;
|
||||
|
||||
QJsonObject bldg;
|
||||
bldg[QStringLiteral("hiddenFloorIds")] = toJsonArray(buildingSettings.hiddenFloorIds);
|
||||
bldg[QStringLiteral("showBuildingOutline")] = buildingSettings.showBuildingOutline;
|
||||
bldg[QStringLiteral("showBuildingName")] = buildingSettings.showBuildingName;
|
||||
obj[QStringLiteral("BuildingSettings")] = bldg;
|
||||
|
||||
const BuildingComponentSettings::BldCmpSettings::ComponentSettings &componentSettings = m_bldCmpSettings.componentSettings;
|
||||
QJsonObject comp;
|
||||
comp[QStringLiteral("showBuildingSensorModule")] = componentSettings.showBuildingSensorModule;
|
||||
comp[QStringLiteral("showBuildingControlUnit")] = componentSettings.showBuildingControlUnit;
|
||||
comp[QStringLiteral("showOutdoorCamera")] = componentSettings.showOutdoorCamera;
|
||||
comp[QStringLiteral("showIndoorCamera")] = componentSettings.showIndoorCamera;
|
||||
comp[QStringLiteral("showOutdoorIPS")] = componentSettings.showOutdoorIPS;
|
||||
comp[QStringLiteral("showIndoorIPS")] = componentSettings.showIndoorIPS;
|
||||
comp[QStringLiteral("showMeteoDataUnit")] = componentSettings.showMeteoDataUnit;
|
||||
comp[QStringLiteral("showAnnouncementUnit")] = componentSettings.showAnnouncementUnit;
|
||||
comp[QStringLiteral("showVirtualIPS")] = componentSettings.showVirtualIPS;
|
||||
comp[QStringLiteral("showEffectGenerationControlUnit")] = componentSettings.showEffectGenerationControlUnit;
|
||||
comp[QStringLiteral("showOutdoorControlUnit")] = componentSettings.showOutdoorControlUnit;
|
||||
comp[QStringLiteral("showBuildingNetworkSwitch")] = componentSettings.showBuildingNetworkSwitch;
|
||||
obj[QStringLiteral("ComponentSettings")] = comp;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
BuildingComponentFilter BuildingComponentSettingsImpl::bldCmpSettingsToData() const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
BuildingComponentFilter ret(m_ddsFilterContent);
|
||||
const QJsonDocument doc(bldCmpSettingsToJson());
|
||||
ret.content(doc.toJson(QJsonDocument::Compact).constData());
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool BuildingComponentSettingsImpl::settingsFromJsonInternal(const QJsonObject &obj, BuildingComponentSettings::BldCmpSettings &settings)
|
||||
{
|
||||
// BuildingSettings
|
||||
BuildingComponentSettings::BldCmpSettings::BuildingSettings &buildingSettings = settings.buildingSettings;
|
||||
QJsonObject bldg = obj[QStringLiteral("BuildingSettings")].toObject();
|
||||
buildingSettings.hiddenFloorIds = fromJsonArray(bldg.value(QStringLiteral("hiddenFloorIds")).toArray());
|
||||
buildingSettings.showBuildingOutline = bldg[QStringLiteral("showBuildingOutline")].toBool();
|
||||
buildingSettings.showBuildingName = bldg[QStringLiteral("showBuildingName")].toBool();
|
||||
|
||||
// ComponentSettings
|
||||
BuildingComponentSettings::BldCmpSettings::ComponentSettings &componentSettings = settings.componentSettings;
|
||||
QJsonObject comp = obj[QStringLiteral("ComponentSettings")].toObject();
|
||||
componentSettings.showBuildingSensorModule = comp[QStringLiteral("showBuildingSensorModule")].toBool();
|
||||
componentSettings.showBuildingControlUnit = comp[QStringLiteral("showBuildingControlUnit")].toBool();
|
||||
componentSettings.showOutdoorCamera = comp[QStringLiteral("showOutdoorCamera")].toBool();
|
||||
componentSettings.showIndoorCamera = comp[QStringLiteral("showIndoorCamera")].toBool();
|
||||
componentSettings.showOutdoorIPS = comp[QStringLiteral("showOutdoorIPS")].toBool();
|
||||
componentSettings.showIndoorIPS = comp[QStringLiteral("showIndoorIPS")].toBool();
|
||||
componentSettings.showMeteoDataUnit = comp[QStringLiteral("showMeteoDataUnit")].toBool();
|
||||
componentSettings.showAnnouncementUnit = comp[QStringLiteral("showAnnouncementUnit")].toBool();
|
||||
componentSettings.showVirtualIPS = comp[QStringLiteral("showVirtualIPS")].toBool();
|
||||
componentSettings.showEffectGenerationControlUnit = comp[QStringLiteral("showEffectGenerationControlUnit")].toBool();
|
||||
componentSettings.showOutdoorControlUnit = comp[QStringLiteral("showOutdoorControlUnit")].toBool();
|
||||
componentSettings.showBuildingNetworkSwitch = comp[QStringLiteral("showBuildingNetworkSwitch")].toBool();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BuildingComponentSettingsImpl::setBldCmpSettings(const QJsonObject &obj)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
BldCmpSettings settings;
|
||||
if (!settingsFromJsonInternal(obj, settings))
|
||||
return false;
|
||||
return setBldCmpSettings(settings);
|
||||
}
|
||||
|
||||
bool BuildingComponentSettingsImpl::setBldCmpSettings(const BuildingComponentSettings::BldCmpSettings &s)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this << "; workspace " << m_workspaceId << "'";
|
||||
|
||||
if (s == m_bldCmpSettings)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " Settings 's' and m_bldCmpSettings are equal -> return (workspace " << m_workspaceId << ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << " Settings 's' and m_bldCmpSettings are different -> update (workspace " << m_workspaceId << ")";
|
||||
|
||||
// update data...
|
||||
m_bldCmpSettings = s; // <<< ------------ !!! JUST HERE!!!
|
||||
|
||||
// call callbacks
|
||||
callSettingsChangedCb();
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsImpl::addChangedCallback(SettingsChangedCallback *cb)
|
||||
{
|
||||
m_settingsChangedCb.removeAll(cb); // avoid duplicates
|
||||
m_settingsChangedCb.push_back(cb);
|
||||
}
|
||||
void BuildingComponentSettingsImpl::removeChangedCallback(SettingsChangedCallback *cb)
|
||||
{
|
||||
m_settingsChangedCb.removeAll(cb);
|
||||
}
|
||||
bool BuildingComponentSettingsImpl::isChangedCallbackRegistered(BuildingComponentSettings::SettingsChangedCallback *cb) const
|
||||
{
|
||||
return m_settingsChangedCb.contains(cb);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsImpl::callSettingsChangedCb()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this << "; workspace " << m_workspaceId << "'"
|
||||
<< " call cbs now: size=" << m_settingsChangedCb.size();
|
||||
|
||||
for (auto *ptr : qAsConst(m_settingsChangedCb))
|
||||
ptr->onBuildingComponentSettingsChanged();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this << "; workspace " << m_workspaceId << "'"
|
||||
<< " call cbs now: size=" << m_settingsChangedCb.size();
|
||||
}
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/fltaesguicommon_export.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <QVector>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
//
|
||||
// BuildingComponentSettingsImpl
|
||||
//
|
||||
class FLTAESGUICOMMON_EXPORT BuildingComponentSettingsImpl final : public BuildingComponentSettings
|
||||
{
|
||||
public:
|
||||
BuildingComponentSettingsImpl(const QString &workspaceId = QString());
|
||||
~BuildingComponentSettingsImpl();
|
||||
|
||||
virtual void resetBuildingComponentSettings() override;
|
||||
|
||||
//DDS == BuildingComponentFilter
|
||||
bool setBldCmpSettingsFromData(const BuildingComponentFilter &filterData) override;
|
||||
QJsonObject bldCmpSettingsToJson() const override;
|
||||
BuildingComponentFilter bldCmpSettingsToData() const override;
|
||||
static bool settingsFromJsonInternal(const QJsonObject &obj, BldCmpSettings &settings);
|
||||
|
||||
// C++struct
|
||||
bool setBldCmpSettings(const QJsonObject &obj) override;
|
||||
bool setBldCmpSettings(const BldCmpSettings &s) override; // calls callbacks
|
||||
const BldCmpSettings &bldCmpSettings() const override { return m_bldCmpSettings; }
|
||||
|
||||
void addChangedCallback(SettingsChangedCallback *cb) override;
|
||||
void removeChangedCallback(SettingsChangedCallback *cb) override;
|
||||
|
||||
bool hasChangedCallbacks() { return !m_settingsChangedCb.empty() ;}
|
||||
int changedCallbackCount() { return m_settingsChangedCb.size() ;}
|
||||
bool isChangedCallbackRegistered(SettingsChangedCallback *cb) const override;
|
||||
|
||||
private:
|
||||
void callSettingsChangedCb();
|
||||
|
||||
private:
|
||||
BuildingComponentFilter m_ddsFilterContent;
|
||||
BldCmpSettings m_bldCmpSettings;
|
||||
|
||||
QVector<SettingsChangedCallback *> m_settingsChangedCb;
|
||||
|
||||
QString m_workspaceId;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <QSet>
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
static inline QSet<int> fromJsonArray(const QJsonArray &arr)
|
||||
{
|
||||
QSet<int> ret;
|
||||
ret.reserve(arr.size());
|
||||
for (const auto &elem : arr)
|
||||
ret.insert(elem.toInt());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QJsonArray toJsonArray(const QSet<int> &ids)
|
||||
{
|
||||
QJsonArray arr;
|
||||
for (int id : ids)
|
||||
arr.push_back(id);
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
+462
@@ -0,0 +1,462 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#include "symbol_appearance_settings_impl.h"
|
||||
#include "common.h"
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QTimer>
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
|
||||
SymbolAppearanceSettingsImpl::SymbolAppearanceSettingsImpl(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtcPpm, const QString &workspaceId)
|
||||
: m_colExpandDirtyTimer(new QTimer(this))
|
||||
, m_dtcPpm(dtcPpm)
|
||||
, m_workspaceId(workspaceId)
|
||||
, m_logger(getLogger("SymbolAppearanceSettings"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
if (m_dtcPpm)
|
||||
{
|
||||
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
|
||||
this, &SymbolAppearanceSettingsImpl::onParticipantChanged);
|
||||
m_colExpandDirtyTimer->setSingleShot(true);
|
||||
m_colExpandDirtyTimer->setInterval(10);
|
||||
connect(m_colExpandDirtyTimer, &QTimer::timeout,
|
||||
this, &SymbolAppearanceSettingsImpl::onRebuildCollapsExpandFilter);
|
||||
m_dtcPpm->participants([this](const ParticipantManagement::Participant &p) {onParticipantChanged(p, DataModification::eAdded);});
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
}
|
||||
|
||||
SymbolAppearanceSettingsImpl::~SymbolAppearanceSettingsImpl()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
}
|
||||
|
||||
void SymbolAppearanceSettingsImpl::resetSymbolAppearanceSettings()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
setSettings(Settings(), Part::All);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
}
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::setSettingsFromData(const SymbolAppearance &data)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this
|
||||
<< ", m_settingsChangedCb.size()=" << m_settingsChangedCb.size();
|
||||
|
||||
DEBUG_LOG(m_logger) << " old symbolTransparency is " << m_settings.symbolSettings.symbolTransparency;
|
||||
|
||||
// Maybe data contains values which are equal to "Settings()"
|
||||
// In that case the following operations lead to setSettings()
|
||||
// and there the identity will be checked and callCallbacks will be skipped :-(
|
||||
// To avoid this, set a single value to invalid: symbolTransparency
|
||||
// Szenario: Create Snap with default filter setting; show snap; modify filter settings (like transparency); show snap again
|
||||
m_ddsSettings = data;
|
||||
m_settings = Settings();
|
||||
// // m_settings.symbolSettings.symbolTransparency = -1.23; // invalid value (avoid "QColor::setAlpha": invalid value 568)
|
||||
m_filteredParticipantsColExp.clear(); // NLDEVCTRL-805; m_filteredParticipantsColExp depends on m_settings -> clear also
|
||||
|
||||
const QByteArray content(QByteArray::fromRawData(m_ddsSettings.content().c_str(), m_ddsSettings.content().size()));
|
||||
|
||||
if (content.isEmpty())
|
||||
return true;
|
||||
|
||||
QJsonParseError parserError;
|
||||
const QJsonDocument doc(QJsonDocument::fromJson(content, &parserError));
|
||||
if (parserError.error != QJsonParseError::NoError)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Error parsing json document: " << parserError.errorString();
|
||||
return false;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << "json to parse: " << doc.toJson();
|
||||
Settings settings;
|
||||
if (!settingsFromJsonInternal(doc.object(), settings))
|
||||
return false;
|
||||
|
||||
m_settings.symbolSettings.symbolTransparency = -1.23; // invalid value (avoid "QColor::setAlpha": invalid value 568)
|
||||
setSettings(settings, Part::All);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::settingsFromJsonInternal(const QJsonObject &obj, Settings &settings) const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
auto &sym = settings.symbolSettings;
|
||||
|
||||
// Part::Symbol
|
||||
QJsonObject symApp = obj[QStringLiteral("SymbolAppearances")].toObject();
|
||||
|
||||
sym.symbolScale = symApp[QStringLiteral("scale")].toDouble(sym.symbolScale);
|
||||
DEBUG_LOG(m_logger) << "set symbolScale to " << sym.symbolScale << " for workspace " << m_workspaceId;
|
||||
|
||||
sym.symbolTransparency = symApp[QStringLiteral("transparency")].toDouble(sym.symbolTransparency);
|
||||
DEBUG_LOG(m_logger) << "set symbolTransparency to " << sym.symbolTransparency << " for workspace " << m_workspaceId;
|
||||
|
||||
sym.symbolFireEventFlashingMSec = symApp[QStringLiteral("fireEventFlashing")].toDouble(sym.symbolFireEventFlashingMSec);
|
||||
sym.hitLineDisplayLengthMSec = symApp[QStringLiteral("hitLineDisplayLength")].toDouble(sym.hitLineDisplayLengthMSec);
|
||||
sym.lrfLineDisplayLengthMSec = symApp[QStringLiteral("lrfLineDisplayLength")].toDouble(sym.lrfLineDisplayLengthMSec);
|
||||
sym.ltdLineDisplayLengthMSec = symApp[QStringLiteral("ltdLineDisplayLength")].toDouble(sym.ltdLineDisplayLengthMSec);
|
||||
sym.movementTrackLengthMSec = symApp[QStringLiteral("movementTrackLengthMSec")].toInt(sym.movementTrackLengthMSec);
|
||||
sym.showBuildingOutline = symApp[QStringLiteral("showBuildingOutline")].toBool(sym.showBuildingOutline);
|
||||
sym.showBuildingIdentifier = symApp[QStringLiteral("showBuildingIdentifier")].toBool(sym.showBuildingIdentifier);
|
||||
sym.showTrainingAreaBorder = symApp[QStringLiteral("showTrainingAreaBorder")].toBool(sym.showTrainingAreaBorder);
|
||||
sym.showSpecialAreas = symApp[QStringLiteral("showSpecialAreas")].toBool(sym.showSpecialAreas);
|
||||
sym.showFiringUnits = symApp[QStringLiteral("showFiringUnits")].toBool(sym.showFiringUnits);
|
||||
sym.nasatNineLinerDisplayLengthMSec = symApp[QStringLiteral("nasatNineLinerDisplayLength")].toInt(sym.nasatNineLinerDisplayLengthMSec);
|
||||
sym.bitErrorVisibility = readSymbolVisibility(symApp, QStringLiteral("bitErrorVisibility"), sym.bitErrorVisibility);
|
||||
sym.manipulationVisibility = readSymbolVisibility(symApp, QStringLiteral("manipulationVisibility"), sym.manipulationVisibility);
|
||||
sym.positionOutOfDateVisibility = readSymbolVisibility(symApp, QStringLiteral("positionOutOfDateVisibility"), sym.positionOutOfDateVisibility);
|
||||
sym.simulatedPositionVisibility = readSymbolVisibility(symApp, QStringLiteral("simulatedPositionVisibility"), sym.simulatedPositionVisibility);
|
||||
sym.unitSymbolPosition = readUnitSymbolPosition(symApp, QStringLiteral("unitSymbolPosition"), sym.unitSymbolPosition);
|
||||
|
||||
const QJsonArray arr(obj.value(QStringLiteral("SymbolTeamAppearances")).toArray());
|
||||
for (const auto &ele : arr)
|
||||
parseSymbolTeamAppearance(settings, ele.toObject());
|
||||
|
||||
// Part::Types
|
||||
settings.hiddenTypeFilter.clear();
|
||||
const auto hiddenTypeFilter(obj.value(QStringLiteral("hiddenTypeFilter")).toArray());
|
||||
for(const QJsonValue &party : hiddenTypeFilter)
|
||||
{
|
||||
const QJsonObject obj(party.toObject());
|
||||
settings.hiddenTypeFilter.insert(obj.value(QStringLiteral("partyId")).toInt(),
|
||||
fromJsonArray(obj.value(QStringLiteral("filter")).toArray()));
|
||||
}
|
||||
|
||||
settings.hiddenStateFilter.clear();
|
||||
const auto hiddenStateFilter(obj.value(QStringLiteral("hiddenStateFilter")).toArray());
|
||||
for(const QJsonValue &party : hiddenStateFilter)
|
||||
{
|
||||
const QJsonObject obj(party.toObject());
|
||||
settings.hiddenStateFilter.insert(obj.value(QStringLiteral("partyId")).toInt(),
|
||||
fromJsonArray(obj.value(QStringLiteral("stateId")).toArray()));
|
||||
}
|
||||
|
||||
// Part::CollapseExpand
|
||||
settings.colExpand.collapsedParticipantIds = fromJsonArray(obj.value(QStringLiteral("colExpCollapsed")).toArray());
|
||||
settings.colExpand.hiddenParticipantIds = fromJsonArray(obj.value(QStringLiteral("colExpHidden")).toArray());
|
||||
|
||||
settings.bIsValid = true;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
return true;
|
||||
}
|
||||
|
||||
QJsonObject SymbolAppearanceSettingsImpl::settingsToJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
const auto &sym = m_settings.symbolSettings;
|
||||
|
||||
QJsonObject symApp;
|
||||
symApp[QStringLiteral("scale")] = sym.symbolScale;
|
||||
symApp[QStringLiteral("transparency")] = sym.symbolTransparency;
|
||||
symApp[QStringLiteral("fireEventFlashing")] = sym.symbolFireEventFlashingMSec;
|
||||
symApp[QStringLiteral("hitLineDisplayLength")] = sym.hitLineDisplayLengthMSec;
|
||||
symApp[QStringLiteral("lrfLineDisplayLength")] = sym.lrfLineDisplayLengthMSec;
|
||||
symApp[QStringLiteral("ltdLineDisplayLength")] = sym.ltdLineDisplayLengthMSec;
|
||||
symApp[QStringLiteral("movementTrackLengthMSec")] = sym.movementTrackLengthMSec;
|
||||
symApp[QStringLiteral("showBuildingOutline")] = sym.showBuildingOutline;
|
||||
symApp[QStringLiteral("showBuildingIdentifier")] = sym.showBuildingIdentifier;
|
||||
symApp[QStringLiteral("showTrainingAreaBorder")] = sym.showTrainingAreaBorder;
|
||||
symApp[QStringLiteral("showSpecialAreas")] = sym.showSpecialAreas;
|
||||
symApp[QStringLiteral("showFiringUnits")] = sym.showFiringUnits;
|
||||
symApp[QStringLiteral("nasatNineLinerDisplayLength")] = sym.nasatNineLinerDisplayLengthMSec;
|
||||
symApp[QStringLiteral("bitErrorVisibility")] = static_cast<int>(sym.bitErrorVisibility);
|
||||
symApp[QStringLiteral("manipulationVisibility")] = static_cast<int>(sym.manipulationVisibility);
|
||||
symApp[QStringLiteral("positionOutOfDateVisibility")] = static_cast<int>(sym.positionOutOfDateVisibility);
|
||||
symApp[QStringLiteral("simulatedPositionVisibility")] = static_cast<int>(sym.simulatedPositionVisibility);
|
||||
symApp[QStringLiteral("unitSymbolPosition")] = static_cast<int>(sym.unitSymbolPosition);
|
||||
obj[QStringLiteral("SymbolAppearances")] = symApp;
|
||||
|
||||
QJsonArray arr;
|
||||
for (auto it = sym.symbolPartyAppearance.begin(); it != sym.symbolPartyAppearance.end(); ++it)
|
||||
{
|
||||
QJsonObject inner;
|
||||
const SymbolPartyAppearance &sta = it.value();
|
||||
inner[QStringLiteral("id")] = it.key();
|
||||
inner[QStringLiteral("isVisible")] = sta.isVisible;
|
||||
inner[QStringLiteral("showDesignator")] = sta.showDesignator;
|
||||
inner[QStringLiteral("showTacticalIdentifier")] = sta.showTacticalIdentifier;
|
||||
arr += inner;
|
||||
}
|
||||
obj[QStringLiteral("SymbolTeamAppearances")] = arr;
|
||||
|
||||
QJsonArray typeArr;
|
||||
for (auto it = m_settings.hiddenTypeFilter.constBegin(); it != m_settings.hiddenTypeFilter.constEnd(); ++it)
|
||||
{
|
||||
QJsonObject inner;
|
||||
inner[QStringLiteral("partyId")] = it.key();
|
||||
inner[QStringLiteral("filter")] = toJsonArray(it.value());
|
||||
typeArr += inner;
|
||||
}
|
||||
obj[QStringLiteral("hiddenTypeFilter")] = typeArr;
|
||||
|
||||
QJsonArray stateArr;
|
||||
for (auto it = m_settings.hiddenStateFilter.begin(); it != m_settings.hiddenStateFilter.end(); ++it)
|
||||
{
|
||||
QJsonObject inner;
|
||||
inner[QStringLiteral("partyId")] = it.key();
|
||||
inner[QStringLiteral("stateId")] = toJsonArray(it.value());
|
||||
stateArr += inner;
|
||||
}
|
||||
obj[QStringLiteral("hiddenStateFilter")] = stateArr;
|
||||
|
||||
obj[QStringLiteral("colExpCollapsed")] = toJsonArray(m_settings.colExpand.collapsedParticipantIds);
|
||||
obj[QStringLiteral("colExpHidden")] = toJsonArray(m_settings.colExpand.hiddenParticipantIds);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
SymbolAppearance SymbolAppearanceSettingsImpl::settingsToData() const
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
SymbolAppearance ret(m_ddsSettings);
|
||||
const QJsonDocument doc(settingsToJson());
|
||||
ret.content(doc.toJson(QJsonDocument::Compact).constData());
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::setSettings(const QJsonObject &obj, Part part)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
Settings settings;
|
||||
if (!settingsFromJsonInternal(obj, settings))
|
||||
return false;
|
||||
return setSettings(settings, part);
|
||||
}
|
||||
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::setSettings(const Settings &s, Part part)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this << ", part=" << (int)part;
|
||||
|
||||
bool bNeedRebuildCollapsExpandFilter = false;
|
||||
switch (part)
|
||||
{
|
||||
case Part::All:
|
||||
if (s == m_settings)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " Settings 's' and m_settings are equal -> return (workspace " << m_workspaceId << ")";
|
||||
return true;
|
||||
}
|
||||
bNeedRebuildCollapsExpandFilter = s.colExpand != m_settings.colExpand;
|
||||
m_settings = s;
|
||||
INFO_LOG(m_logger) << "set symbol scale (?) of " << s.symbolSettings.symbolScale << " in workspace " << m_workspaceId;
|
||||
break;
|
||||
case Part::Symbol:
|
||||
if (s.symbolSettings == m_settings.symbolSettings)
|
||||
return true;
|
||||
m_settings.symbolSettings = s.symbolSettings;
|
||||
INFO_LOG(m_logger) << "set symbol scale of " << s.symbolSettings.symbolScale << " in workspace " << m_workspaceId;
|
||||
break;
|
||||
case Part::Types:
|
||||
if (s.hiddenTypeFilter == m_settings.hiddenTypeFilter &&
|
||||
s.hiddenStateFilter == m_settings.hiddenStateFilter)
|
||||
return true;
|
||||
m_settings.hiddenTypeFilter = s.hiddenTypeFilter;
|
||||
m_settings.hiddenStateFilter = s.hiddenStateFilter;
|
||||
break;
|
||||
case Part::CollapseExpand:
|
||||
if (s.colExpand == m_settings.colExpand)
|
||||
return true;
|
||||
bNeedRebuildCollapsExpandFilter = true;
|
||||
m_settings.colExpand = s.colExpand;
|
||||
break;
|
||||
}
|
||||
if (bNeedRebuildCollapsExpandFilter)
|
||||
onRebuildCollapsExpandFilter();
|
||||
|
||||
callSettingsChangedCb(part);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::isParticipantVisibileCollapseExpand(int participantId) const
|
||||
{
|
||||
return m_filteredParticipantsColExp.contains(participantId);
|
||||
}
|
||||
|
||||
void SymbolAppearanceSettingsImpl::addChangedCallback(SettingsChangedCallback *cb)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", add cb=" << cb;
|
||||
m_settingsChangedCb.removeAll(cb); // avoid duplicates
|
||||
m_settingsChangedCb.push_back(cb);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", add cb=" << cb << " done";
|
||||
}
|
||||
|
||||
|
||||
void SymbolAppearanceSettingsImpl::removeChangedCallback(SettingsChangedCallback *cb)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", remove cb=" << cb << " current size=" << m_settingsChangedCb.size();
|
||||
m_settingsChangedCb.removeAll(cb);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", remove cb=" << cb << " done, current size=" << m_settingsChangedCb.size();
|
||||
}
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::isChangedCallbackRegistered(SymbolAppearanceSettings::SettingsChangedCallback *cb) const
|
||||
{
|
||||
return m_settingsChangedCb.contains(cb);
|
||||
}
|
||||
|
||||
void SymbolAppearanceSettingsImpl::callSettingsChangedCb(Part part)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", call cbs, START , part=" << (int)part << ", size=" << m_settingsChangedCb.size();
|
||||
for (auto *ptr : qAsConst(m_settingsChangedCb))
|
||||
ptr->onSymbolAppearanceSettingsChanged(part);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << ", call cbs, END , part=" << (int)part << ", size=" << m_settingsChangedCb.size();
|
||||
}
|
||||
|
||||
SymbolAppearanceSettingsImpl::SymbolVisibility SymbolAppearanceSettingsImpl::readSymbolVisibility(const QJsonObject &obj,
|
||||
const QString &val,
|
||||
SymbolVisibility def)
|
||||
{
|
||||
if (!obj.contains(val))
|
||||
return def;
|
||||
int r = obj[val].toInt();
|
||||
if (r < static_cast<int>(SymbolVisibility::Standard) ||
|
||||
r > static_cast<int>(SymbolVisibility::AdditionalSymbol))
|
||||
return def;
|
||||
return static_cast<SymbolVisibility>(r);
|
||||
}
|
||||
|
||||
SymbolAppearanceSettingsImpl::UnitSymbolPosition SymbolAppearanceSettingsImpl::readUnitSymbolPosition(const QJsonObject &obj,
|
||||
const QString &val,
|
||||
UnitSymbolPosition def)
|
||||
{
|
||||
if (!obj.contains(val))
|
||||
return def;
|
||||
int r = obj[val].toInt();
|
||||
if (r < static_cast<int>(UnitSymbolPosition::Center) ||
|
||||
r > static_cast<int>(UnitSymbolPosition::Leader))
|
||||
return def;
|
||||
return static_cast<UnitSymbolPosition>(r);
|
||||
}
|
||||
|
||||
void SymbolAppearanceSettingsImpl::parseSymbolTeamAppearance(Settings &settings, const QJsonObject &obj)
|
||||
{
|
||||
int id = obj.value(QStringLiteral("id")).toInt();
|
||||
SymbolPartyAppearance sta;
|
||||
sta.isVisible = obj.value(QStringLiteral("isVisible")).toBool(sta.isVisible);
|
||||
sta.showDesignator = obj.value(QStringLiteral("showDesignator")).toBool(sta.showDesignator);
|
||||
sta.showTacticalIdentifier = obj.value(QStringLiteral("showTacticalIdentifier")).toBool(sta.showTacticalIdentifier);
|
||||
settings.symbolSettings.symbolPartyAppearance.insert(id, sta);
|
||||
}
|
||||
|
||||
void SymbolAppearanceSettingsImpl::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification mod)
|
||||
{
|
||||
switch (mod)
|
||||
{
|
||||
case DataModification::eAdded:
|
||||
case DataModification::eModified:
|
||||
{
|
||||
auto it = m_participantId2SuperiorId.find(data.id());
|
||||
if (it != m_participantId2SuperiorId.end())
|
||||
{
|
||||
if (it.value() != data.superiorId())
|
||||
{
|
||||
it.value() = data.superiorId();
|
||||
m_colExpandDirtyTimer->start();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_participantId2SuperiorId[data.id()] = data.superiorId();
|
||||
// Starte SituationReplay (leere Map, NOCH kein Orbat in der ReplayPartition)
|
||||
// Doppelklick auf eine Marke (in der eingeklappten Tlns hinterlegt sind)
|
||||
// -> Filter (SymbolAppearanceSettingsImpl) wird geladen
|
||||
// Orbat ist allerdings noch leer!!!
|
||||
// (KEIN onParticipantChanged -> m_participantId2SuperiorId ist leer)
|
||||
// Race Condition: wird erst hier 'onParticipantChanged' aufgerufen
|
||||
// ODER im participant2Map???
|
||||
// Daher nutzen wird den dirtyTimer auch hier.
|
||||
// Sollte also dieses onParticipantChanged zuletzt aufgerufen werden,
|
||||
// werden die Callbacks via 'onRebuildCollapsExpandFilter' aufgerufen :-)
|
||||
m_colExpandDirtyTimer->start();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DataModification::eRemoved:
|
||||
{
|
||||
auto it = m_participantId2SuperiorId.constFind(data.id());
|
||||
if (it != m_participantId2SuperiorId.constEnd())
|
||||
{
|
||||
m_participantId2SuperiorId.erase(it);
|
||||
//m_colExpandDirtyTimer->start(); // really needed?
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolAppearanceSettingsImpl::onRebuildCollapsExpandFilter()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Rebuilding CollapseExpand filter, participant2Superior size: " << m_participantId2SuperiorId.size();
|
||||
|
||||
QSet<int> filteredParticipantsColExp = m_settings.colExpand.hiddenParticipantIds;
|
||||
for (auto it = m_participantId2SuperiorId.begin(); it != m_participantId2SuperiorId.end(); ++it)
|
||||
{
|
||||
const int participantId = it.key();
|
||||
if (filteredParticipantsColExp.contains(participantId))
|
||||
continue;
|
||||
const int superiorId = it.value();
|
||||
QSet<int> visitedIds;
|
||||
if (isInCollapsedTree(superiorId, visitedIds))
|
||||
filteredParticipantsColExp += participantId;
|
||||
}
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
{
|
||||
QStringList sl;
|
||||
sl.reserve(20);
|
||||
for(int i : qAsConst(m_settings.colExpand.hiddenParticipantIds))
|
||||
sl += QString::number(i);
|
||||
DEBUG_LOG(m_logger) << "Hidden participant ids: " << sl.join(QLatin1Char(' '));
|
||||
sl.clear();
|
||||
for(int i : qAsConst(m_settings.colExpand.collapsedParticipantIds))
|
||||
sl += QString::number(i);
|
||||
DEBUG_LOG(m_logger) << "Collapsed participant ids: " << sl.join(QLatin1Char(' '));
|
||||
sl.clear();
|
||||
for(int i : qAsConst(filteredParticipantsColExp))
|
||||
sl += QString::number(i);
|
||||
DEBUG_LOG(m_logger) << "Result: " << sl.join(QLatin1Char(' '));
|
||||
}
|
||||
|
||||
if (m_filteredParticipantsColExp == filteredParticipantsColExp)
|
||||
return;
|
||||
|
||||
m_filteredParticipantsColExp = filteredParticipantsColExp;
|
||||
|
||||
callSettingsChangedCb(Part::Types);
|
||||
}
|
||||
|
||||
bool SymbolAppearanceSettingsImpl::isInCollapsedTree(int participantId, QSet<int> &visitedIds) const
|
||||
{
|
||||
if (participantId == 0)
|
||||
return false;
|
||||
if (m_settings.colExpand.collapsedParticipantIds.contains(participantId))
|
||||
return true;
|
||||
const int superiorId = m_participantId2SuperiorId.value(participantId);
|
||||
if (visitedIds.contains(superiorId))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Recursion detected - participant with id " << participantId << ", superiorId: " << superiorId;
|
||||
return false;
|
||||
}
|
||||
visitedIds.insert(superiorId);
|
||||
return isInCollapsedTree(superiorId, visitedIds);
|
||||
}
|
||||
|
||||
|
||||
} // namespace FilterManagement
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Data Plugin for FilterManangement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Mike Wille, SLSE, 2017-03-31
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/fltaesguicommon_export.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QHash>
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
//
|
||||
// SymbolAppearanceSettingsImpl
|
||||
//
|
||||
class FLTAESGUICOMMON_EXPORT SymbolAppearanceSettingsImpl final : public QObject, public SymbolAppearanceSettings
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SymbolAppearanceSettingsImpl(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &dtcPpm, const QString &workspaceId = QString());
|
||||
~SymbolAppearanceSettingsImpl();
|
||||
|
||||
void resetSymbolAppearanceSettings() override;
|
||||
|
||||
bool setSettingsFromData(const SymbolAppearance &data) override;
|
||||
QJsonObject settingsToJson() const override;
|
||||
SymbolAppearance settingsToData() const override;
|
||||
bool settingsFromJsonInternal(const QJsonObject &obj, Settings &settings) const;
|
||||
|
||||
bool setSettings(const QJsonObject &obj, Part part) override;
|
||||
bool setSettings(const Settings &s, Part part) override;
|
||||
const Settings &settings() const override { return m_settings; }
|
||||
|
||||
bool isParticipantVisibileCollapseExpand(int participantId) const override;
|
||||
|
||||
void addChangedCallback(SettingsChangedCallback *cb) override;
|
||||
void removeChangedCallback(SettingsChangedCallback *cb) override;
|
||||
bool isChangedCallbackRegistered(SettingsChangedCallback *cb) const override;
|
||||
|
||||
bool hasChangedCallbacks() { return !m_settingsChangedCb.empty() ;}
|
||||
int changedCallbackCount() { return m_settingsChangedCb.size() ;}
|
||||
|
||||
private:
|
||||
void callSettingsChangedCb(Part part);
|
||||
static SymbolVisibility readSymbolVisibility(const QJsonObject &obj,
|
||||
const QString &val,
|
||||
SymbolVisibility def);
|
||||
static UnitSymbolPosition readUnitSymbolPosition(const QJsonObject &obj,
|
||||
const QString &val,
|
||||
UnitSymbolPosition def);
|
||||
static void parseSymbolTeamAppearance(Settings &settings, const QJsonObject &obj);
|
||||
private Q_SLOTS:
|
||||
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification mod);
|
||||
void onRebuildCollapsExpandFilter();
|
||||
private:
|
||||
bool isInCollapsedTree(int participantId, QSet<int> &visitedIds) const;
|
||||
private:
|
||||
QVector<SettingsChangedCallback *> m_settingsChangedCb;
|
||||
// <participantId, superiorParticipantId>
|
||||
QHash<int, int> m_participantId2SuperiorId;
|
||||
QTimer *m_colExpandDirtyTimer;
|
||||
Settings m_settings;
|
||||
SymbolAppearance m_ddsSettings;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtcPpm;
|
||||
QSet<int> m_filteredParticipantsColExp;
|
||||
QString m_workspaceId;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "flt_aes_filter_dialog.h"
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <FilterManagement/Gui/FilterChange/flt_filter_change.h>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QTimer>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
//
|
||||
// AesFilterDialog
|
||||
//
|
||||
AesFilterDialog::AesFilterDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_widget(new AesFilterWidget(this))
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_session(nullptr)
|
||||
, m_unknowChangesNotifiyTimer(new QTimer(this))
|
||||
, m_logger(getLogger("AesFilterDialog"))
|
||||
{
|
||||
connect(m_widget, &AesFilterWidget::changesMade, this, &AesFilterDialog::slotChangesMade);
|
||||
QGridLayout *gl = new QGridLayout(this);
|
||||
gl->setMargin(0);
|
||||
gl->addWidget(m_widget, 0, 0);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Situation_Filter"));
|
||||
|
||||
// prepare notifiyTimer: (GUEZE-3266)
|
||||
m_unknowChangesNotifiyTimer->setInterval(50);
|
||||
m_unknowChangesNotifiyTimer->setSingleShot(true);
|
||||
connect(m_unknowChangesNotifiyTimer, &QTimer::timeout,
|
||||
this, &AesFilterDialog::onProcessUnknownChanges);
|
||||
}
|
||||
|
||||
AesFilterDialog::~AesFilterDialog()
|
||||
{}
|
||||
|
||||
bool AesFilterDialog::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
m_session = session;
|
||||
if (!session->getForeignGuiInterface(m_fltIfc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign data interface for FilterManagement";
|
||||
return false;
|
||||
}
|
||||
if (!session->getFtc<FilterManagement::DataInterface>(m_fltFtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign data interface for FilterManagement";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> ifcPpmCbx;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> ifcPdmCbx;
|
||||
std::shared_ptr<AesDisplayFilter> filter;
|
||||
|
||||
if (!session->getForeignGuiInterface(ifcPpmCbx))
|
||||
return false;
|
||||
if (!session->getForeignGuiInterface(ifcPdmCbx))
|
||||
return false;
|
||||
filter = m_fltIfc->aesFilterForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), m_session->workspaceId());
|
||||
|
||||
bool success = m_widget->init(ifcPpmCbx, ifcPdmCbx, filter, m_session->app() == LtsAppDescriptor::App::OC);
|
||||
|
||||
// In case of LoadingFilter or user selects another replay (and therefore other filter):
|
||||
connect(m_widget, &AesFilterWidget::unknownChangesRecognized, this, &AesFilterDialog::onUnknownChangesRecognized, Qt::UniqueConnection);
|
||||
|
||||
if (FilterChangeDialog::isAvailableAtApp(m_session->app()))
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Load filter"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load,
|
||||
this, &AesFilterDialog::onLoadButtonClicked);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void AesFilterDialog::retranslate()
|
||||
{
|
||||
// lupdate doesn't like translate(tr("foo")) ...
|
||||
const QString txt(tr("Filter Area Effect Simulation"));
|
||||
translate(txt);
|
||||
|
||||
m_widget->retranslate();
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
bool AesFilterDialog::apply()
|
||||
{
|
||||
m_widget->apply();
|
||||
return m_requestHelper->startSingleRequest([this]()
|
||||
{
|
||||
const AesFilter &filterData = m_widget->filter()->filterToData();
|
||||
return m_fltFtc->aesFilterUpdateRequest(filterData, this);
|
||||
});
|
||||
}
|
||||
|
||||
void AesFilterDialog::dialogCanceled()
|
||||
{
|
||||
m_widget->dialogCanceled();
|
||||
}
|
||||
|
||||
void AesFilterDialog::onAesFilterUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void AesFilterDialog::onUnknownChangesRecognized()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_unknowChangesNotifiyTimer->start();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void AesFilterDialog::onProcessUnknownChanges()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
m_widget->updateGuiToFilter();
|
||||
|
||||
// the data can be changed if another replay is selected or filter are loaded.
|
||||
// So our widget has to be updated:
|
||||
__unchange__();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void AesFilterDialog::onLoadButtonClicked()
|
||||
{
|
||||
FilterChangeDialog *dialog = new FilterChangeDialog(this);
|
||||
if (!dialog->init(m_session, SymbolAppearanceSettings::Part::All, true, false, false))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QObject::connect(dialog, &FilterChangeDialog::rejected, dialog, &FilterChangeDialog::deleteLater);
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flt_aes_filter_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_aes_plugin_interface.h>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class DataInterface;
|
||||
// --------------------------------------------------------
|
||||
// AesFilterDialog
|
||||
// --------------------------------------------------------
|
||||
class AesFilterDialog final : public LtsWidgets::LtsDialog
|
||||
, private FilterManagement::Interface::Ftc::AesFilterUpdateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AesFilterDialog(QWidget *parent = nullptr);
|
||||
~AesFilterDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session);
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
bool apply() override;
|
||||
void dialogCanceled() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onAesFilterUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onUnknownChangesRecognized();
|
||||
void onProcessUnknownChanges();
|
||||
void onLoadButtonClicked();
|
||||
|
||||
private:
|
||||
AesFilterWidget *m_widget{nullptr};
|
||||
LtsUtils::RequestHelper *m_requestHelper{nullptr};
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
QTimer *m_unknowChangesNotifiyTimer{nullptr};
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltIfc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,704 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "flt_aes_filter_widget.h"
|
||||
#include "ui_flt_aes_filter_widget.h"
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
static inline void setFixedWidthForWidgetHelper(QWidget *w)
|
||||
{
|
||||
int width = w->sizeHint().width();
|
||||
w->setMinimumWidth(width);
|
||||
w->setMaximumWidth(width);
|
||||
}
|
||||
|
||||
static inline void setConditional(QCheckBox *chb, bool bChecked)
|
||||
{
|
||||
if (chb->isEnabled())
|
||||
chb->setChecked(bChecked);
|
||||
else
|
||||
chb->setChecked(false);
|
||||
}
|
||||
|
||||
class UpdateGuard
|
||||
{
|
||||
public:
|
||||
explicit UpdateGuard(AesFilterWidget *w)
|
||||
: m_w(w)
|
||||
{
|
||||
if (m_w)
|
||||
m_w->m_doUpdateViaCallback = false;
|
||||
}
|
||||
~UpdateGuard()
|
||||
{
|
||||
if (m_w)
|
||||
m_w->m_doUpdateViaCallback = true;
|
||||
}
|
||||
private:
|
||||
AesFilterWidget *m_w;
|
||||
};
|
||||
|
||||
|
||||
AesFilterWidget::AesFilterWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_doUpdateViaCallback(true)
|
||||
, m_ui(new Ui::AesFilterWidget)
|
||||
, m_logger(getLogger("AesFilterDialog"))
|
||||
{
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
|
||||
const bool enableGasPipes = ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableGasPipes")).toBool();
|
||||
const bool enableAirSupport = ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableAirSupport")).toBool();
|
||||
|
||||
const bool enableTechnicalAreas = ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableTechnicalAreas")).toBool();
|
||||
|
||||
const bool enableDusSingleMine = ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableDusSingleMine")).toBool();
|
||||
|
||||
const bool enableSingleExplosionArtillery = ps->value(QStringLiteral("aes"),
|
||||
QStringLiteral("enableSingleExplosionArtillery")).toBool();
|
||||
m_ui->setupUi(this);
|
||||
|
||||
if (!enableSingleExplosionArtillery)
|
||||
{
|
||||
m_ui->chbCreatedExplosionSingle->hide();
|
||||
m_ui->chbPreparedExplosionSingle->hide();
|
||||
m_ui->chbActiveExplosionSingle->hide();
|
||||
m_ui->sldAfterglowSingleFire->hide();
|
||||
m_ui->lbSingleFire->hide();
|
||||
m_ui->lbAfterGlowSingleFire->hide();
|
||||
m_ui->lblAfterglowSingleFire->hide();
|
||||
}
|
||||
if (!enableGasPipes)
|
||||
{
|
||||
m_ui->lb_GasPipes->hide();
|
||||
m_ui->chbCreatedGasPipes->hide();
|
||||
m_ui->chbActiveGasPipes->hide();
|
||||
m_ui->chbPreparedGasPipes->hide();
|
||||
m_ui->label_GasPipes->hide();
|
||||
m_ui->sldAfterglowGasPipes->hide();
|
||||
m_ui->lblAfterglowGasPipes->hide();
|
||||
}
|
||||
if (!enableAirSupport)
|
||||
{
|
||||
m_ui->lb_AirSupport->hide();
|
||||
m_ui->chbCreatedAirSupport->hide();
|
||||
m_ui->chbPreparedAirSupport->hide();
|
||||
m_ui->chbActiveAirSupport->hide();
|
||||
|
||||
m_ui->sldAfterglowAirSupport->hide();
|
||||
m_ui->lblAfterglowAirSupport->hide();
|
||||
}
|
||||
if (!enableTechnicalAreas)
|
||||
{
|
||||
m_ui->lb_TechnicalAreas->hide();
|
||||
m_ui->chbCreatedTechnicalArea->hide();
|
||||
m_ui->chbPreparedTechnicalArea->hide();
|
||||
m_ui->chbActiveTechnicalArea->hide();
|
||||
}
|
||||
|
||||
m_checkBoxes =
|
||||
{
|
||||
{AreaEffectSimulation::AesType::AtBCContamination, Checkboxes(m_ui->chbCreatedBCContamination, m_ui->chbPreparedBCContamination, m_ui->chbActiveBCContamination)},
|
||||
{AreaEffectSimulation::AesType::AtNContamination, Checkboxes(m_ui->chbCreatedNContamination, m_ui->chbPreparedNContamination, m_ui->chbActiveNContamination)},
|
||||
{AreaEffectSimulation::AesType::AtDangerArea, Checkboxes(m_ui->chbCreatedDangerArea, m_ui->chbPreparedDangerArea, m_ui->chbActiveDangerArea)},
|
||||
{AreaEffectSimulation::AesType::AtMineArea, Checkboxes(m_ui->chbCreatedMineArea, m_ui->chbPreparedMineArea, m_ui->chbActiveMineArea)},
|
||||
{AreaEffectSimulation::AesType::AtMineCorridor, Checkboxes(m_ui->chbCreatedMineCorridor, m_ui->chbPreparedMineCorridor, m_ui->chbActiveMineCorridor)},
|
||||
{AreaEffectSimulation::AesType::AtExplosionSingle, Checkboxes(m_ui->chbCreatedExplosionSingle, m_ui->chbPreparedExplosionSingle, m_ui->chbActiveExplosionSingle)},
|
||||
{AreaEffectSimulation::AesType::AtExplosionArea, Checkboxes(m_ui->chbCreatedExplosionArea, m_ui->chbPreparedExplosionArea, m_ui->chbActiveExplosionArea)},
|
||||
{AreaEffectSimulation::AesType::AtFunctionalArea, Checkboxes(m_ui->chbCreatedFunctionalArea, m_ui->chbPreparedFunctionalArea, m_ui->chbActiveFunctionalArea)},
|
||||
{AreaEffectSimulation::AesType::AtBorderline, Checkboxes(m_ui->chbCreatedBorderline, m_ui->chbPreparedBorderline, m_ui->chbActiveBorderline)},
|
||||
{AreaEffectSimulation::AesType::AtMineAreaSingleMines, Checkboxes(m_ui->chbCreatedIed, m_ui->chbPreparedIed, m_ui->chbActiveIed)},
|
||||
{AreaEffectSimulation::AesType::AtDusSingleMine, Checkboxes(m_ui->chbCreatedDusSingleMine, m_ui->chbPreparedDusSingleMine, m_ui->chbActiveDusSingleMine)},
|
||||
{AreaEffectSimulation::AesType::AtGasPipe, Checkboxes(m_ui->chbCreatedGasPipes, m_ui->chbPreparedGasPipes, m_ui->chbActiveGasPipes)},
|
||||
{AreaEffectSimulation::AesType::AtTechnicalArea, Checkboxes(m_ui->chbCreatedTechnicalArea, m_ui->chbPreparedTechnicalArea, m_ui->chbActiveTechnicalArea)},
|
||||
{AreaEffectSimulation::AesType::AtAirSupportImpact, Checkboxes(m_ui->chbCreatedAirSupport, m_ui->chbPreparedAirSupport, m_ui->chbActiveAirSupport)}
|
||||
};
|
||||
m_ui->chbCreatedIed->hide();
|
||||
m_ui->chbPreparedDusSingleMine->hide();
|
||||
m_ui->chbCreatedDusSingleMine->hide();
|
||||
|
||||
if (!enableDusSingleMine)
|
||||
{
|
||||
m_ui->label_19->hide();
|
||||
m_ui->label_21->hide();
|
||||
m_ui->chbPreparedDusSingleMine->hide();
|
||||
m_ui->chbCreatedDusSingleMine->hide();
|
||||
m_ui->chbActiveDusSingleMine->hide();
|
||||
m_ui->sldAfterglowDusSingleMine->hide();
|
||||
m_ui->lblAfterglowDusSingleMine->hide();
|
||||
}
|
||||
|
||||
for (const auto &p : m_checkBoxes)
|
||||
{
|
||||
const auto type = p.first;
|
||||
const Checkboxes *chb = &p.second;
|
||||
connect(chb->chbCreated, &QCheckBox::clicked, this, [this, type]() { onCheckboxChanged(type);});
|
||||
connect(chb->chbPrepared, &QCheckBox::clicked, this, [this, type]() { onCheckboxChanged(type);});
|
||||
connect(chb->chbActive, &QCheckBox::clicked, this, [this, type]() { onCheckboxChanged(type);});
|
||||
|
||||
}
|
||||
|
||||
// don't know why this was added in the first place - there is no ongoing filtering for it
|
||||
// and danger areas don't have a party atm
|
||||
m_ui->chbPartiesDangerArea->hide();
|
||||
m_ui->pbPartiesDangerArea->hide();
|
||||
connect(m_ui->chbPartiesDangerArea, &QCheckBox::clicked,
|
||||
this, &AesFilterWidget::onChbPartiesDangerAreaClicked);
|
||||
connect(m_ui->pbPartiesDangerArea, &QPushButton::clicked,
|
||||
this, &AesFilterWidget::onPbPartiesDangerAreaClicked);
|
||||
|
||||
connect(m_ui->chbChargeTypesMineArea, &QCheckBox::clicked,
|
||||
this, &AesFilterWidget::onChbMineAreaChargeTypesClicked);
|
||||
connect(m_ui->pbChargeTypesMineArea, &QPushButton::clicked,
|
||||
this, &AesFilterWidget::onPbChargTypesMineAreaClicked);
|
||||
connect(m_ui->chbSingleMinesMineArea, &QCheckBox::clicked,
|
||||
this, &AesFilterWidget::onChbMineAreSingleMinesClicked);
|
||||
connect(m_ui->chbCDMineArea, &QCheckBox::clicked,
|
||||
this, &AesFilterWidget::onChbMineAreSingleMinesClicked);
|
||||
|
||||
connect(m_ui->sldAfterglowMineCorridor, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldMineCorridorChanged);
|
||||
connect(m_ui->sldAfterglowSingleFire, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldSingleFireChanged);
|
||||
connect(m_ui->sldAfterglowMineArea, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldMineAreaChanged);
|
||||
connect(m_ui->sldAfterglowMineAreaSingleMines_IED, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldMineAreaSingleMinesChanged);
|
||||
connect(m_ui->sldAfterglowDusSingleMine, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldDusSingleMineChanged);
|
||||
connect(m_ui->sldAfterglowGasPipes, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldGasPipesChanged);
|
||||
connect(m_ui->sldAfterglowAirSupport, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldAirSupportChanged);
|
||||
connect(m_ui->sldAfterglowAreaFire, &QSlider::valueChanged,
|
||||
this, &AesFilterWidget::onSldAreaFireChanged);
|
||||
|
||||
connect(m_ui->chbCentral, &QCheckBox::clicked, this, &AesFilterWidget::onChCentralClicked);
|
||||
connect(m_ui->chbPeripheral, &QCheckBox::clicked, this, &AesFilterWidget::onChPeripheralClicked);
|
||||
|
||||
connect(m_ui->chbMeanHitPointAreaFire, &QCheckBox::clicked, this, &AesFilterWidget::onChbMeanHitPointAreaFireClicked);
|
||||
connect(m_ui->chbGunToTargetLineAreaFire, &QCheckBox::clicked, this, &AesFilterWidget::onChbGunToTargetLineAreaFireClicked);
|
||||
connect(m_ui->chbTrajectoryAreaFire, &QCheckBox::clicked, this, &AesFilterWidget::onChbTrajectoryAreaFireClicked);
|
||||
connect(m_ui->chbDetonationSphereAreaFire, &QCheckBox::clicked, this, &AesFilterWidget::onChbDetonationSphereAreaFireClicked);
|
||||
|
||||
// after connect so the slots for setting the labels are executed
|
||||
m_ui->sldAfterglowSingleFire->setValue(m_ui->sldAfterglowSingleFire->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowSingleFire);
|
||||
m_ui->sldAfterglowMineArea->setValue(m_ui->sldAfterglowMineArea->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowMineArea);
|
||||
m_ui->sldAfterglowMineCorridor->setValue(m_ui->sldAfterglowMineCorridor->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowMineCorridor);
|
||||
m_ui->sldAfterglowMineAreaSingleMines_IED->setValue(m_ui->sldAfterglowMineAreaSingleMines_IED->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowMineAreaSingleMines);
|
||||
m_ui->sldAfterglowDusSingleMine->setValue(m_ui->sldAfterglowDusSingleMine->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowDusSingleMine);
|
||||
m_ui->sldAfterglowGasPipes->setValue(m_ui->sldAfterglowGasPipes->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowGasPipes);
|
||||
m_ui->sldAfterglowAirSupport->setValue(m_ui->sldAfterglowAirSupport->maximum());
|
||||
setFixedWidthForWidgetHelper(m_ui->lblAfterglowAirSupport);
|
||||
}
|
||||
|
||||
AesFilterWidget::~AesFilterWidget()
|
||||
{
|
||||
m_filter->removeChangedCallback(this);
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool AesFilterWidget::init(const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ifcPpmCbx,
|
||||
const std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> &ifcPdmCbx,
|
||||
const std::shared_ptr<AesDisplayFilter> &filter,
|
||||
bool isOc)
|
||||
{
|
||||
m_ifcPpmCbx = ifcPpmCbx;
|
||||
m_ifcPdmCbx = ifcPdmCbx;
|
||||
m_filter = filter;
|
||||
|
||||
m_originalFilterSettings = m_filter->filterToData();
|
||||
|
||||
setFilter();
|
||||
if (isOc)
|
||||
{
|
||||
m_ui->pbChargeTypesMineArea->setVisible(false);
|
||||
m_ui->chbChargeTypesMineArea->setVisible(false);
|
||||
m_ui->lblCreated->setVisible(false);
|
||||
m_ui->chbCreatedFunctionalArea->setVisible(false);
|
||||
|
||||
m_ui->chbCreatedBCContamination->setVisible(false);
|
||||
m_ui->chbCreatedDusSingleMine->setVisible(false);
|
||||
m_ui->chbCreatedExplosionArea->setVisible(false);
|
||||
m_ui->chbCreatedExplosionSingle->setVisible(false);
|
||||
m_ui->chbCreatedDangerArea->setVisible(false);
|
||||
m_ui->chbCreatedGasPipes->setVisible(false);
|
||||
m_ui->chbCreatedMineArea->setVisible(false);
|
||||
m_ui->chbCreatedNContamination->setVisible(false);
|
||||
m_ui->chbCreatedTechnicalArea->setVisible(false);
|
||||
//no mine corridor at all!
|
||||
m_ui->label_17->setVisible(false);
|
||||
m_ui->chbCreatedMineCorridor->setVisible(false);
|
||||
m_ui->chbPreparedMineCorridor->setVisible(false);
|
||||
m_ui->chbActiveMineCorridor->setVisible(false);
|
||||
m_ui->sldAfterglowMineCorridor->setVisible(false);
|
||||
m_ui->label_18->setVisible(false);
|
||||
m_ui->lblAfterglowMineCorridor->setVisible(false);
|
||||
// No Air support at all
|
||||
m_ui->chbCreatedAirSupport->setVisible(false);
|
||||
m_ui->chbPreparedAirSupport->setVisible(false);
|
||||
m_ui->chbActiveAirSupport->setVisible(false);
|
||||
m_ui->lblAfterglowAirSupport->setVisible(false);
|
||||
m_ui->sldAfterglowAirSupport->setVisible(false);
|
||||
m_ui->label_23->setVisible(false);
|
||||
m_ui->lb_AirSupport->setVisible(false);
|
||||
// no IED at all
|
||||
m_ui->chbCreatedIed->setVisible(false);
|
||||
m_ui->chbPreparedIed->setVisible(false);
|
||||
m_ui->chbActiveIed->setVisible(false);
|
||||
m_ui->sldAfterglowMineAreaSingleMines_IED->setVisible(false);
|
||||
m_ui->lblAfterglowMineAreaSingleMines->setVisible(false);
|
||||
m_ui->label_13->setVisible(false);
|
||||
m_ui->label_14->setVisible(false);
|
||||
m_ui->label_15->setVisible(false);
|
||||
m_ui->label_16->setVisible(false);
|
||||
m_ui->label_21->setVisible(false);
|
||||
//no Borderline at all?
|
||||
m_ui->chbCreatedBorderline->setVisible(false);
|
||||
m_ui->chbPreparedBorderline->setVisible(false);
|
||||
m_ui->chbActiveBorderline->setVisible(false);
|
||||
m_ui->lblBorderLine->setVisible(false);
|
||||
}
|
||||
m_filter->addChangedCallback(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AesFilterWidget::retranslate()
|
||||
{
|
||||
m_ui->retranslateUi(this);
|
||||
onUpdateSliderTextSingleFire();
|
||||
onUpdateSliderTextMineCorridor();
|
||||
onUpdateSliderTextMineAreaSingleMines();
|
||||
onUpdateSliderTextDusSingleMine();
|
||||
onUpdateSliderTextGasPipes();
|
||||
onUpdateSliderTextAirSupport();
|
||||
onUpdateSliderTextMineArea();
|
||||
onUpdateSliderTextAreaFire();
|
||||
}
|
||||
|
||||
void AesFilterWidget::apply()
|
||||
{
|
||||
// nothing to do here atm
|
||||
}
|
||||
|
||||
void AesFilterWidget::dialogCanceled()
|
||||
{
|
||||
m_filter->setFilterFromData(m_originalFilterSettings);
|
||||
}
|
||||
|
||||
void AesFilterWidget::setFilter()
|
||||
{
|
||||
m_ui->chbChargeTypesMineArea->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtMineArea).limitOnChargeTypes);
|
||||
m_ui->chbPartiesDangerArea->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtDangerArea).limitOnParties);
|
||||
m_ui->chbSingleMinesMineArea->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtMineArea).showDetails);
|
||||
m_ui->chbCDMineArea->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtMineArea).showDetails2);
|
||||
m_ui->chbMeanHitPointAreaFire->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtExplosionArea).showDetails2);
|
||||
m_ui->chbGunToTargetLineAreaFire->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtExplosionArea).showDetails3);
|
||||
m_ui->chbTrajectoryAreaFire->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtExplosionArea).showDetails4);
|
||||
m_ui->chbDetonationSphereAreaFire->setChecked(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtExplosionArea).showDetails5);
|
||||
|
||||
|
||||
QSignalBlocker b(this);
|
||||
for (const auto &p : m_checkBoxes)
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct ess(m_filter->effectStateFilter(p.first));
|
||||
DEBUG_LOG(m_logger) << "Set Filter for " << p.first << ": "
|
||||
<< ess.displayCreated << ", "
|
||||
<< ess.displayPrepared << ", "
|
||||
<< ess.displayActivated;
|
||||
const Checkboxes *chb = &p.second;
|
||||
setConditional(chb->chbCreated, ess.displayCreated);
|
||||
setConditional(chb->chbPrepared, ess.displayPrepared);
|
||||
setConditional(chb->chbActive, ess.displayActivated);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essMineArea(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtMineArea));
|
||||
m_ui->sldAfterglowMineArea->setValue(essMineArea.expiredAfterglowDurationMSec / 1000);
|
||||
|
||||
m_ui->chbCentral->setChecked(essMineArea.displayCentral);
|
||||
m_ui->chbPeripheral->setChecked(essMineArea.displayPeripheral);
|
||||
}
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essMc(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtMineCorridor));
|
||||
m_ui->sldAfterglowMineCorridor->setValue(essMc.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essEs(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtExplosionSingle));
|
||||
m_ui->sldAfterglowSingleFire->setValue(essEs.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essAreaFire(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtExplosionArea));
|
||||
m_ui->sldAfterglowAreaFire->setValue(essAreaFire.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essGP(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtGasPipe));
|
||||
m_ui->sldAfterglowGasPipes->setValue(essGP.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essAS(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtAirSupportImpact));
|
||||
m_ui->sldAfterglowAirSupport->setValue(essAS.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
{ // IED
|
||||
const AesDisplayFilter::EffectStateStruct essMa(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtMineAreaSingleMines));
|
||||
m_ui->sldAfterglowMineAreaSingleMines_IED->setValue(essMa.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
{
|
||||
const AesDisplayFilter::EffectStateStruct essDsm(m_filter->effectStateFilter(AreaEffectSimulation::AesType::AtDusSingleMine));
|
||||
m_ui->sldAfterglowDusSingleMine->setValue(essDsm.expiredAfterglowDurationMSec / 1000);
|
||||
}
|
||||
|
||||
onSldSingleFireChanged();
|
||||
onSldMineCorridorChanged();
|
||||
onSldMineAreaSingleMinesChanged();
|
||||
onSldDusSingleMineChanged();
|
||||
onSldGasPipesChanged();
|
||||
onSldAirSupportChanged();
|
||||
onChbMineAreaChargeTypesClicked();
|
||||
onChbPartiesDangerAreaClicked();
|
||||
onChbGunToTargetLineAreaFireClicked();
|
||||
onChbMeanHitPointAreaFireClicked();
|
||||
onChbTrajectoryAreaFireClicked();
|
||||
onChbDetonationSphereAreaFireClicked();
|
||||
}
|
||||
|
||||
void AesFilterWidget::onCheckboxChanged(AreaEffectSimulation::AesType t)
|
||||
{
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
auto it = m_checkBoxes.find(t);
|
||||
if (it == m_checkBoxes.end())
|
||||
return;
|
||||
|
||||
const Checkboxes *chb = &it->second;
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.displayCreated = chb->chbCreated->isChecked();
|
||||
ess.displayPrepared = chb->chbPrepared->isChecked();
|
||||
ess.displayActivated = chb->chbActive->isChecked();
|
||||
ess.displayCentral = m_ui->chbCentral->isChecked();
|
||||
ess.displayPeripheral = m_ui->chbPeripheral->isChecked();
|
||||
ess.showDetails2 = m_ui->chbMeanHitPointAreaFire->isChecked();
|
||||
ess.showDetails3 = m_ui->chbGunToTargetLineAreaFire->isChecked();
|
||||
ess.showDetails4 = m_ui->chbTrajectoryAreaFire->isChecked();
|
||||
ess.showDetails5 = m_ui->chbDetonationSphereAreaFire->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onPbPartiesDangerAreaClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtDangerArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
auto cb = [this, t](const QSet<int> &selectedParties)
|
||||
{
|
||||
if (!this->m_filter)
|
||||
return;
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
if (ess.visiblePartyIds == selectedParties)
|
||||
return;
|
||||
ess.visiblePartyIds = selectedParties;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
emit changesMade();
|
||||
};
|
||||
|
||||
m_ifcPpmCbx->partySelector(ess.visiblePartyIds, cb, this);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onPbChargTypesMineAreaClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
auto cb = [this, t](const QSet<int> &selectedCharges)
|
||||
{
|
||||
if (!this->m_filter)
|
||||
return;
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
if (ess.visibleChargeTypeIds == selectedCharges)
|
||||
return;
|
||||
ess.visibleChargeTypeIds = selectedCharges;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
emit changesMade();
|
||||
};
|
||||
|
||||
m_ifcPdmCbx->chargeSelector(ess.visibleChargeTypeIds, ProjectDataManagement::GearClass::MineArea, cb, this);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbMineAreSingleMinesClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.displayPeripheral = m_ui->chbPeripheral->isChecked();
|
||||
ess.displayCentral = m_ui->chbCentral->isChecked();
|
||||
ess.showDetails = m_ui->chbSingleMinesMineArea->isChecked();
|
||||
ess.showDetails2 = m_ui->chbCDMineArea->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
emit changesMade();
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextMineArea()
|
||||
{
|
||||
m_ui->lblAfterglowMineArea->setText(tr("%1 [s]").arg(m_ui->sldAfterglowMineArea->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextAreaFire()
|
||||
{
|
||||
m_ui->lblAfterglowAreaFire->setText(tr("%1 [s]").arg(m_ui->sldAfterglowAreaFire->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextSingleFire()
|
||||
{
|
||||
m_ui->lblAfterglowSingleFire->setText(tr("%1 [s]").arg(m_ui->sldAfterglowSingleFire->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextMineCorridor()
|
||||
{
|
||||
m_ui->lblAfterglowMineCorridor->setText(tr("%1 [s]").arg(m_ui->sldAfterglowMineCorridor->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextMineAreaSingleMines()
|
||||
{
|
||||
m_ui->lblAfterglowMineAreaSingleMines->setText(tr("%1 [s]").arg(m_ui->sldAfterglowMineAreaSingleMines_IED->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextDusSingleMine()
|
||||
{
|
||||
m_ui->lblAfterglowDusSingleMine->setText(tr("%1 [s]").arg(m_ui->sldAfterglowDusSingleMine->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextGasPipes()
|
||||
{
|
||||
m_ui->lblAfterglowGasPipes->setText(tr("%1 [s]").arg(m_ui->sldAfterglowGasPipes->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onUpdateSliderTextAirSupport()
|
||||
{
|
||||
m_ui->lblAfterglowAirSupport->setText(tr("%1 [s]").arg(m_ui->sldAfterglowAirSupport->value()));
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldSingleFireChanged()
|
||||
{
|
||||
onUpdateSliderTextSingleFire();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionSingle);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowSingleFire->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldMineAreaChanged()
|
||||
{
|
||||
onUpdateSliderTextMineArea();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowMineArea->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldAreaFireChanged()
|
||||
{
|
||||
onUpdateSliderTextAreaFire();
|
||||
DEBUG_LOG(m_logger)<<">> slider area fire changed";
|
||||
if(!m_filter)
|
||||
return;
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.showDetails2 = m_ui->chbMeanHitPointAreaFire->isChecked();
|
||||
ess.showDetails3 = m_ui->chbGunToTargetLineAreaFire->isChecked();
|
||||
ess.showDetails4 = m_ui->chbTrajectoryAreaFire->isChecked();
|
||||
ess.showDetails5 = m_ui->chbDetonationSphereAreaFire->isChecked();
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowAreaFire->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldMineCorridorChanged()
|
||||
{
|
||||
onUpdateSliderTextMineCorridor();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineCorridor);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowMineCorridor->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldMineAreaSingleMinesChanged()
|
||||
{
|
||||
onUpdateSliderTextMineAreaSingleMines();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineAreaSingleMines);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowMineAreaSingleMines_IED->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldDusSingleMineChanged()
|
||||
{
|
||||
onUpdateSliderTextDusSingleMine();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtDusSingleMine);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowDusSingleMine->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldGasPipesChanged()
|
||||
{
|
||||
onUpdateSliderTextGasPipes();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtGasPipe);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowGasPipes->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onSldAirSupportChanged()
|
||||
{
|
||||
onUpdateSliderTextAirSupport();
|
||||
if (!m_filter)
|
||||
return;
|
||||
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtAirSupportImpact);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.expiredAfterglowDurationMSec = m_ui->sldAfterglowAirSupport->value() * 1000;
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbMeanHitPointAreaFireClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.showDetails2 = m_ui->chbMeanHitPointAreaFire->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbGunToTargetLineAreaFireClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.showDetails3 = m_ui->chbGunToTargetLineAreaFire->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbTrajectoryAreaFireClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.showDetails4 = m_ui->chbTrajectoryAreaFire->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbDetonationSphereAreaFireClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtExplosionArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.showDetails5 = m_ui->chbDetonationSphereAreaFire->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbMineAreaChargeTypesClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.limitOnChargeTypes = m_ui->chbChargeTypesMineArea->isChecked();
|
||||
m_ui->pbChargeTypesMineArea->setEnabled(ess.limitOnChargeTypes);
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChbPartiesDangerAreaClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtDangerArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.limitOnParties = m_ui->chbPartiesDangerArea->isChecked();
|
||||
m_ui->pbPartiesDangerArea->setEnabled(ess.limitOnParties);
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onChCentralClicked()
|
||||
{
|
||||
for (const auto &p : m_checkBoxes)
|
||||
{
|
||||
const auto type = p.first;
|
||||
onCheckboxChanged(type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AesFilterWidget::onChPeripheralClicked()
|
||||
{
|
||||
for (const auto &p : m_checkBoxes)
|
||||
{
|
||||
const auto type = p.first;
|
||||
onCheckboxChanged(type);
|
||||
}
|
||||
}
|
||||
void AesFilterWidget::onChbTriggeredCDMineAreaClicked()
|
||||
{
|
||||
const AreaEffectSimulation::AesType t(AreaEffectSimulation::AesType::AtMineArea);
|
||||
AesDisplayFilter::EffectStateStruct ess = m_filter->effectStateFilter(t);
|
||||
ess.showDetails2 = m_ui->chbCDMineArea->isChecked();
|
||||
UpdateGuard guard(this);
|
||||
m_filter->setEffectStateFilter(t, ess);
|
||||
}
|
||||
|
||||
void AesFilterWidget::onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType)
|
||||
{
|
||||
Q_UNUSED(aesType);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, m_doUpdateViaCallback=" << m_doUpdateViaCallback;
|
||||
if (m_doUpdateViaCallback)
|
||||
emit unknownChangesRecognized();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, m_doUpdateViaCallback=" << m_doUpdateViaCallback;
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_aes_display_filter.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
#include <Plugins/ProjectDataManagement/pdm_gui_plugin_interface.h>
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class INGLLogger;
|
||||
}
|
||||
namespace Ui
|
||||
{
|
||||
class AesFilterWidget;
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class AesFilterWidget : public QWidget,
|
||||
protected AesDisplayFilter::FilterChangedCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AesFilterWidget(QWidget *parent = nullptr);
|
||||
~AesFilterWidget();
|
||||
|
||||
bool init(const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ifcPpmCbx,
|
||||
const std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> &ifcPdmCbx,
|
||||
const std::shared_ptr<AesDisplayFilter> &filter, bool isOc = false);
|
||||
|
||||
void retranslate();
|
||||
void apply();
|
||||
void dialogCanceled();
|
||||
std::shared_ptr<AesDisplayFilter> filter() const { return m_filter; }
|
||||
void updateGuiToFilter() { setFilter(); }
|
||||
|
||||
signals:
|
||||
void changesMade();
|
||||
void unknownChangesRecognized();
|
||||
|
||||
private:
|
||||
void setFilter();
|
||||
|
||||
private slots:
|
||||
void onCheckboxChanged(AreaEffectSimulation::AesType t);
|
||||
void onPbPartiesDangerAreaClicked();
|
||||
void onPbChargTypesMineAreaClicked();
|
||||
void onChbMineAreSingleMinesClicked();
|
||||
void onUpdateSliderTextMineArea();
|
||||
void onUpdateSliderTextAreaFire();
|
||||
void onUpdateSliderTextSingleFire();
|
||||
void onUpdateSliderTextMineCorridor();
|
||||
void onUpdateSliderTextMineAreaSingleMines();
|
||||
void onUpdateSliderTextDusSingleMine();
|
||||
void onUpdateSliderTextGasPipes();
|
||||
void onUpdateSliderTextAirSupport();
|
||||
void onSldSingleFireChanged();
|
||||
void onSldMineAreaChanged();
|
||||
void onSldAreaFireChanged();
|
||||
void onSldMineCorridorChanged();
|
||||
void onSldMineAreaSingleMinesChanged();
|
||||
void onSldDusSingleMineChanged();
|
||||
void onSldGasPipesChanged();
|
||||
void onSldAirSupportChanged();
|
||||
void onChbMineAreaChargeTypesClicked();
|
||||
void onChbPartiesDangerAreaClicked();
|
||||
void onChCentralClicked();
|
||||
void onChbGunToTargetLineAreaFireClicked();
|
||||
void onChbMeanHitPointAreaFireClicked();
|
||||
void onChbTrajectoryAreaFireClicked();
|
||||
void onChbDetonationSphereAreaFireClicked();
|
||||
void onChPeripheralClicked();
|
||||
void onChbTriggeredCDMineAreaClicked();
|
||||
|
||||
void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) override;
|
||||
|
||||
private:
|
||||
struct Checkboxes
|
||||
{
|
||||
QCheckBox *chbCreated = nullptr;
|
||||
QCheckBox *chbPrepared = nullptr;
|
||||
QCheckBox *chbActive = nullptr;
|
||||
Checkboxes(QCheckBox *_creat, QCheckBox *_prep, QCheckBox *_act)
|
||||
: chbCreated(_creat)
|
||||
, chbPrepared(_prep)
|
||||
, chbActive(_act)
|
||||
{}
|
||||
};
|
||||
std::map<AreaEffectSimulation::AesType, Checkboxes> m_checkBoxes;
|
||||
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ifcPpmCbx;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> m_ifcPdmCbx;
|
||||
std::shared_ptr<AesDisplayFilter> m_filter;
|
||||
AesFilter m_originalFilterSettings;
|
||||
friend class UpdateGuard;
|
||||
bool m_doUpdateViaCallback;
|
||||
|
||||
Ui::AesFilterWidget *m_ui;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
+1231
File diff suppressed because it is too large.
Load diff
+181
@@ -0,0 +1,181 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for FilterManagement (AES)
|
||||
* $Id: flt_aes_plugin.cpp 50305 2020-03-10 08:30:39Z ehrlicher $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/FilterManagement/Gui/Aes/flt_aes_plugin.cpp $
|
||||
* $Author: ehrlicher $
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "flt_aes_gui_plugin.h"
|
||||
#include "flt_aes_filter_dialog.h"
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsProjectionWorkstation/lts_projection_workstation.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <FilterManagement/flt_operator_rights.h>
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/symbol_appearance_settings_impl.h>
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/aes_display_filter_impl.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Interface"))
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> ifcPpmCbx;
|
||||
std::shared_ptr<ProjectDataManagement::ForeignGuiInterface> ifcPdmCbx;
|
||||
if (!m_session->getForeignGuiInterface(ifcPpmCbx) ||
|
||||
!m_session->getForeignGuiInterface(ifcPdmCbx) ||
|
||||
!m_session->getDtc<FilterManagement::DataInterface>(m_fltDtc))
|
||||
return false;
|
||||
|
||||
connect(m_fltDtc.get(), &FilterManagement::Interface::Dtc::aesFilterChanged,
|
||||
this, &InterfaceImpl::onAesFilterChanged, Qt::UniqueConnection);
|
||||
|
||||
// NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// filterPresetLoadUnsaved at PWS leads to race condition
|
||||
// (create dtc and update data via request)
|
||||
// enable AesFilter and SymbolAppearance already here
|
||||
|
||||
// 22.01.2025, Thoden: Nachtrag zu NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// GUEZE-3459: Hannas OPW: Hänger beim Login
|
||||
// 1. waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// gehört eingentlich VOR fltDtc->{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// 2. Da diese aber auf der PWS wohl wichtig waren, wird fetchInterfaces jeweils
|
||||
// angepasst:
|
||||
// waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters} wird
|
||||
// nicht mehr grundsätzlich, sondern nur auf der PWS ausgeführt:
|
||||
// if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
// m_fltDtc->waitForHistoricalDataXXX(1000);
|
||||
|
||||
if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
m_fltDtc->waitForHistoricalDataAesFilter(1000);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableAES_FilterEdit = ps->value(QStringLiteral("flt"),
|
||||
QStringLiteral("enableAES_FilterEdit")).toBool();
|
||||
// GUEZE-1624: not in ResourceManagerApp:
|
||||
const bool bResourceManager = m_session->app() == LtsAppDescriptor::App::ResourceManager;
|
||||
if (enableAES_FilterEdit && !bResourceManager)
|
||||
{
|
||||
LtsWidgets::PluginData plData;
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Filter Area Effect Simulation");
|
||||
plData.identifier = QLatin1String("fltAesFilter");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:filter_effect_simulation.svg"));
|
||||
plData.operatorRight = OperatorRights::FilterManagement::AesFilterEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
return onShowAesFilterDialog(parent);
|
||||
};
|
||||
ret.append(plData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<AesDisplayFilter> InterfaceImpl::aesFilterForOperator(int operatorId, const QString &context)
|
||||
{
|
||||
std::shared_ptr<AesDisplayFilterImpl> ret;
|
||||
|
||||
auto it = m_aesFilterMap.find({operatorId, context.toStdString()});
|
||||
if (it != m_aesFilterMap.end())
|
||||
ret = it->second.lock();
|
||||
if (!ret)
|
||||
{
|
||||
FilterManagement::AesFilter filterData;
|
||||
// it's 0 when there is not yet a filter for this operator, so set it here and use it for comparision
|
||||
filterData.operatorId(operatorId);
|
||||
filterData.ctx(context.toStdString());
|
||||
|
||||
std::function<bool(const FilterManagement::AesFilter &)> func = [&filterData](const FilterManagement::AesFilter &f)
|
||||
{
|
||||
if (f.operatorId() == filterData.operatorId() &&
|
||||
f.ctx() == filterData.ctx())
|
||||
{
|
||||
filterData = f;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// 22.01.2025, Thoden: Nachtrag zu NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// GUEZE-3459: Hannas OPW: Hänger beim Login
|
||||
// 1. waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// gehört eingentlich VOR fltDtc->{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// 2. Da diese aber auf der PWS wohl wichtig waren, wird fetchInterfaces jeweils
|
||||
// angepasst:
|
||||
// waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters} wird
|
||||
// nicht mehr grundsätzlich, sondern nur auf der PWS ausgeführt:
|
||||
// if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
// m_fltDtc->waitForHistoricalDataXXX(1000);
|
||||
|
||||
m_fltDtc->waitForHistoricalDataAesFilter(1000);
|
||||
|
||||
m_fltDtc->aesFilters(func);
|
||||
|
||||
ret = std::make_shared<AesDisplayFilterImpl>();
|
||||
ret->setFilterFromData(filterData);
|
||||
ret->setVisiblePartiesCheck([this](int id) -> bool { return LtsSessionData::LtsSessionData::getInstance()->isVisibleParty(m_session->exerciseId(), id); });
|
||||
|
||||
m_aesFilterMap[FilterKey(operatorId, context.toStdString())] = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InterfaceImpl::onAesFilterChanged(const FilterManagement::AesFilter &data, DataModification mod)
|
||||
{
|
||||
auto it = m_aesFilterMap.find(FilterKey{data.operatorId(), data.ctx()});
|
||||
if (it != m_aesFilterMap.end())
|
||||
{
|
||||
std::shared_ptr<AesDisplayFilterImpl> ret = it->second.lock();
|
||||
if (ret && mod != DataModification::eRemoved)
|
||||
ret->setFilterFromData(data);
|
||||
else
|
||||
{
|
||||
// Maybe the scvFilterManagement (hosted at svcExerciseEventManagement)
|
||||
// is restarted. In that case the topics are removed from DDS.
|
||||
// But when the svc is starting again, the data is inserted into this
|
||||
// map again - but the callbacks are lost!! So some related dialog do
|
||||
// not work anymore... :-(
|
||||
// To avoid this, prevent 'used' AesDisplayFilterImpl from
|
||||
// being removed:
|
||||
if (!(ret && ret->hasChangedCallbacks()))
|
||||
m_aesFilterMap.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//private
|
||||
LtsWidgets::LtsDialog *InterfaceImpl::onShowAesFilterDialog(QWidget *parent)
|
||||
{
|
||||
return LtsWidgets::initDialog(new AesFilterDialog(parent),
|
||||
m_session);
|
||||
}
|
||||
|
||||
} //namespace FilterManagement
|
||||
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for FilterManagement (AES)
|
||||
* $Id: flt_aes_plugin.h 46043 2019-03-14 14:07:28Z hjl $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/FilterManagement/Gui/Aes/flt_aes_plugin.h $
|
||||
* $Author: hjl $
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_aes_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
|
||||
//#include <Services/FilterManagement/logger.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class FilterKey;
|
||||
class SymbolAppearanceSettingsImpl;
|
||||
class AesDisplayFilterImpl;
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:flt.aes")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("FilterManagementAesGuiPlugin"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Global) ||
|
||||
(partition == IDL::PartitionType::Exercise) ||
|
||||
(partition == IDL::PartitionType::Replay);
|
||||
}
|
||||
};
|
||||
|
||||
class InterfaceImpl final : public QObject, public ForeignAesGuiInterface, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
QString menuGroup() const override { return tr("Situation Map"); }
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
// std::shared_ptr<SymbolAppearanceSettings> symbolAppearanceForOperator(int operatorId, const QString &context) override final;
|
||||
std::shared_ptr<AesDisplayFilter> aesFilterForOperator(int operatorId, const QString &context) override;
|
||||
|
||||
|
||||
private slots:
|
||||
void onAesFilterChanged(const FilterManagement::AesFilter &data, DataModification mod);
|
||||
// void onSymbolAppearanceChanged(const SymbolAppearance &data, DataModification mod);
|
||||
|
||||
private:
|
||||
// <operatorId, filter>
|
||||
struct FilterKey
|
||||
{
|
||||
int operatorId = 0;
|
||||
std::string context;
|
||||
FilterKey() = default;
|
||||
FilterKey(int _operatorId, const std::string &_context)
|
||||
: operatorId(_operatorId)
|
||||
, context(_context)
|
||||
{}
|
||||
bool operator<(const FilterKey &o) const
|
||||
{
|
||||
if (operatorId != o.operatorId)
|
||||
return operatorId < o.operatorId;
|
||||
return context < o.context;
|
||||
}
|
||||
};
|
||||
|
||||
// std::map<FilterKey, std::weak_ptr<SymbolAppearanceSettingsImpl>> m_symbolAppearanceMap;
|
||||
std::map<FilterKey, std::weak_ptr<AesDisplayFilterImpl>> m_aesFilterMap;
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
// std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
|
||||
LtsWidgets::LtsDialog *onShowAesFilterDialog(QWidget *parent);
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,58 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Christian Ehrlicher, SLSE, 2017-06-16
|
||||
#
|
||||
|
||||
SET(flt_bldg_cmpnt_widget_SRCS
|
||||
flt_building_component_settings_widget.cpp
|
||||
flt_building_component_settings_widget.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(flt_bldg_cmpnt_widget_SRCS
|
||||
flt_building_component_settings_widget.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS FltBldgCmpntWidget STATIC ${flt_bldg_cmpnt_widget_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(FltBldgCmpntWidget
|
||||
PRIVATE
|
||||
svcFltCommon
|
||||
IsmDataPluginInterface
|
||||
LtsProjectionWorkstation
|
||||
PUBLIC
|
||||
FltDataPluginInterface
|
||||
LtsSessionData
|
||||
PdmGuiPluginInterface
|
||||
PpmGuiComboboxPluginInterface
|
||||
Qt5::Widgets
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(FltBldgCmpntWidget
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
||||
)
|
||||
|
||||
SET(flt_bldg_cmpnt_gui_SRCS
|
||||
flt_building_component_filter_dialog.cpp
|
||||
flt_building_component_filter_dialog.h
|
||||
|
||||
flt_building_components_gui_plugin.cpp
|
||||
flt_building_components_gui_plugin.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS Fltbldg_cmpntGuiPlugin MODULE ${flt_bldg_cmpnt_gui_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(Fltbldg_cmpntGuiPlugin
|
||||
FltAesGuiCommon
|
||||
FltBldgCmpntGuiPluginInterface
|
||||
FltBldgCmpntWidget
|
||||
FltFilterChange
|
||||
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
LtsWidgets
|
||||
Qt5::Widgets
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(Fltbldg_cmpntGuiPlugin)
|
||||
Executable
+145
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "flt_building_component_filter_dialog.h"
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <QGridLayout>
|
||||
#include <FilterManagement/Gui/FilterChange/flt_filter_change.h>
|
||||
#include <InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
//
|
||||
// BuildingComponentFilterDialog
|
||||
//
|
||||
BuildingComponentFilterDialog::BuildingComponentFilterDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_widget(new BuildingComponentSettingsWidget(this))
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_session(nullptr)
|
||||
, m_logger(getLogger("BuildingComponentFilterDialog"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
connect(m_widget, &BuildingComponentSettingsWidget::changesMade, this, &BuildingComponentFilterDialog::slotChangesMade);
|
||||
QGridLayout *gl = new QGridLayout(this);
|
||||
gl->setMargin(0);
|
||||
gl->addWidget(m_widget, 0, 0);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Situation_Filter"));
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
BuildingComponentFilterDialog::~BuildingComponentFilterDialog()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingComponentFilterDialog::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
m_session = session;
|
||||
if (!session->getForeignGuiInterface(m_fltIfc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign data interface for FilterManagement";
|
||||
return false;
|
||||
}
|
||||
if (!session->getFtc<FilterManagement::DataInterface>(m_fltFtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign data interface for FilterManagement";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<BuildingComponentSettings> filter;
|
||||
filter = m_fltIfc->buildingComponentSettingsForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), m_session->workspaceId());
|
||||
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_ismDtc;
|
||||
if (!session->getDtc<InfrastructureManagement::DataInterface>(m_ismDtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign data interface for FilterManagement";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = m_widget->init(filter, m_ismDtc /*, m_session->app() == LtsAppDescriptor::App::OC*/);
|
||||
|
||||
// In case of LoadingFilter or user selects another replay (and therefore other filter):
|
||||
connect(m_widget, &BuildingComponentSettingsWidget::unknownChangesRecognized,
|
||||
this, &BuildingComponentFilterDialog::onUnknownChangesRecognized, Qt::UniqueConnection);
|
||||
|
||||
if (FilterChangeDialog::isAvailableAtApp(m_session->app()))
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Load filter"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load,
|
||||
this, &BuildingComponentFilterDialog::onLoadButtonClicked);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void BuildingComponentFilterDialog::retranslate()
|
||||
{
|
||||
// lupdate doesn't like translate(tr("foo")) ...
|
||||
const QString txt(tr("Filter Building/Components"));
|
||||
translate(txt);
|
||||
|
||||
m_widget->retranslate();
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
bool BuildingComponentFilterDialog::apply()
|
||||
{
|
||||
m_widget->apply();
|
||||
return m_requestHelper->startSingleRequest([this]()
|
||||
{
|
||||
const BuildingComponentFilter filterData = m_widget->filter()->bldCmpSettingsToData();
|
||||
return m_fltFtc->buildingComponentFilterUpdateRequest(filterData, this);
|
||||
});
|
||||
}
|
||||
|
||||
void BuildingComponentFilterDialog::dialogCanceled()
|
||||
{
|
||||
m_widget->dialogCanceled();
|
||||
}
|
||||
|
||||
void BuildingComponentFilterDialog::onBuildingComponentFilterUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void BuildingComponentFilterDialog::onUnknownChangesRecognized()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
m_widget->updateGuiToFilter();
|
||||
|
||||
// the data can be changed if another replay is selected or filter are loaded.
|
||||
// So our widget has to be updated:
|
||||
__unchange__();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
void BuildingComponentFilterDialog::onLoadButtonClicked()
|
||||
{
|
||||
FilterChangeDialog *dialog = new FilterChangeDialog(this);
|
||||
if (!dialog->init(m_session, SymbolAppearanceSettings::Part::All, false, true, false))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QObject::connect(dialog, &FilterChangeDialog::rejected, dialog, &FilterChangeDialog::deleteLater);
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flt_building_component_settings_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class DataInterface;
|
||||
// --------------------------------------------------------
|
||||
// BuildingComponentFilterDialog
|
||||
// --------------------------------------------------------
|
||||
class BuildingComponentFilterDialog final : public LtsWidgets::LtsDialog
|
||||
, private FilterManagement::Interface::Ftc::BuildingComponentFilterUpdateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BuildingComponentFilterDialog(QWidget *parent = nullptr);
|
||||
~BuildingComponentFilterDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session);
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
bool apply() override;
|
||||
void dialogCanceled() override;
|
||||
void onBuildingComponentFilterUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onUnknownChangesRecognized();
|
||||
void onLoadButtonClicked();
|
||||
|
||||
private:
|
||||
BuildingComponentSettingsWidget *m_widget{nullptr};
|
||||
LtsUtils::RequestHelper *m_requestHelper{nullptr};
|
||||
LtsSession::LtsSession *m_session{nullptr};
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltIfc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
Executable
+412
@@ -0,0 +1,412 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "flt_building_component_settings_widget.h"
|
||||
#include "ui_flt_building_component_settings_widget.h"
|
||||
|
||||
#include <ParticipantManagement/ppm.hpp>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMenu>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
#include <Plugins/InfrastructureManagement/ism_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const char FloorIdProperty[] = "floorId";
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class BoolLocker
|
||||
{
|
||||
public:
|
||||
explicit BoolLocker(bool &b)
|
||||
: m_b(b)
|
||||
{
|
||||
m_b = true;
|
||||
}
|
||||
~BoolLocker()
|
||||
{
|
||||
m_b = false;
|
||||
}
|
||||
private:
|
||||
bool &m_b;
|
||||
};
|
||||
|
||||
BuildingComponentSettingsWidget::BuildingComponentSettingsWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_bIgnoreUiSignals(false)
|
||||
, m_ui(new Ui::BuildingComponentSettingsWidget)
|
||||
, m_doUpdateViaCallback(true)
|
||||
, m_logger(getLogger("BuildingComponentSettingsWidget"))
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
m_ui->setupUi(this);
|
||||
|
||||
// Today following should be hidden bc not useful for any project:
|
||||
m_ui->lblComponent_BuildingControlUnit->hide();
|
||||
m_ui->cbshowBuildingControlUnit->hide();
|
||||
m_ui->lblComponent_VirtualIPS->hide();
|
||||
m_ui->cbshowVirtualIPS->hide();
|
||||
m_ui->lblComponent_MeteoDataUnit->hide();
|
||||
m_ui->cbshowMeteoDataUnit->hide();
|
||||
|
||||
#ifdef GUEZ_MODE
|
||||
// SWPÄ 2/22 - Hannes: BuildingNetworkSwitch werden ignoriert: GUEZE-1548
|
||||
m_ui->cbshowBuildingNetworkSwitch->hide();
|
||||
m_ui->lblComponent_BuildingNetworkSwitch->hide();
|
||||
m_ui->cbshowAnnouncementUnit->hide();
|
||||
m_ui->lblComponent_AnnouncementUnit->hide();
|
||||
m_ui->cbshowOutdoorControlUnit->hide();
|
||||
m_ui->lblComponent_OutdoorControlUnit->hide();
|
||||
// : Today following should be hidden bc not useful for any project
|
||||
#endif
|
||||
m_checkBoxesComponents = findChildren<QCheckBox*>();
|
||||
|
||||
// for every component CheckBox
|
||||
for (QCheckBox* cb : qAsConst(m_checkBoxesComponents))
|
||||
{
|
||||
// evaluate every component QCheckBox immediatly:
|
||||
connect(cb , &QCheckBox::clicked, this, &BuildingComponentSettingsWidget::readUpdateFilterFromUi);
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " STARTXXXX";
|
||||
|
||||
// enable ContextMenu - if (cb->isVisible()) does not work since whole gui is not visible yet:
|
||||
cb->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(cb, &QCheckBox::customContextMenuRequested, this, &BuildingComponentSettingsWidget::onContextMenuComponentRequested);
|
||||
} // for
|
||||
|
||||
// for every component Label
|
||||
// use findChildren from widget, from gridLayout will not work
|
||||
const QList<QLabel*> labelComponents = findChildren<QLabel*>();
|
||||
for (QLabel* lbl : qAsConst(labelComponents))
|
||||
{
|
||||
// hopefully better maintainance:
|
||||
if (lbl->objectName().startsWith(QStringLiteral("lblComponent_")))
|
||||
{
|
||||
lbl->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(lbl, &QLabel::customContextMenuRequested, this, &BuildingComponentSettingsWidget::onContextMenuComponentRequested);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, m_checkBoxesComponents.size = " << m_checkBoxesComponents.size()
|
||||
<< ", labelComponents.size()=" << labelComponents.size();
|
||||
}
|
||||
|
||||
BuildingComponentSettingsWidget::~BuildingComponentSettingsWidget()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (m_buildingComponentSettings)
|
||||
m_buildingComponentSettings->removeChangedCallback(this);
|
||||
delete m_ui;
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool BuildingComponentSettingsWidget::init(const std::shared_ptr<BuildingComponentSettings> &filter,
|
||||
const std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc)
|
||||
{
|
||||
if (!ismDtc)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign data interface for InfrastructureManagement";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_buildingComponentSettings = filter;
|
||||
m_originalBldCmp = m_buildingComponentSettings->bldCmpSettings();
|
||||
|
||||
// FloorIds :
|
||||
|
||||
// build floorIds via MainStructureElements and those StructureElements:
|
||||
QSet<int> floorIds;
|
||||
if (ismDtc)
|
||||
{
|
||||
const QMap<int, InfrastructureManagement::MainStructureElement> &mses = ismDtc->mainStructureElements();
|
||||
|
||||
for (const InfrastructureManagement::MainStructureElement &mse : mses)
|
||||
{
|
||||
// only buildings
|
||||
if (mse.structureElementTypeId() != InfrastructureManagement::StructureElementType::Building)
|
||||
continue;
|
||||
|
||||
for (const InfrastructureManagement::StructureElement ¤tElement : mse.elements())
|
||||
{
|
||||
if (currentElement.structureElementTypeId() != InfrastructureManagement::StructureElementType::Floor)
|
||||
continue;
|
||||
|
||||
// just floors now:
|
||||
int floorInt = QString::fromStdString(currentElement.name()).split(QStringLiteral("_")).value(1, QStringLiteral("-10")).toInt();
|
||||
floorIds += floorInt;
|
||||
} //
|
||||
} // for
|
||||
}
|
||||
QVector<int> floorIdsVec = floorIds.values().toVector();
|
||||
floorIdsVec.append(-10); // -10 -> Outdoor/Exterior
|
||||
std::sort(floorIdsVec.begin(), floorIdsVec.end());
|
||||
|
||||
// : FloorIds
|
||||
|
||||
setupFloorUi(floorIdsVec);
|
||||
|
||||
setBuildingComponentSettings();
|
||||
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " isChangedCallbackRegistered 1 =" << m_buildingComponentSettings->isChangedCallbackRegistered(this);
|
||||
m_buildingComponentSettings->addChangedCallback(this); // callback: onBuildingComponentSettingsChanged
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " isChangedCallbackRegistered 2 =" << m_buildingComponentSettings->isChangedCallbackRegistered(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::retranslate()
|
||||
{
|
||||
BoolLocker l(m_bIgnoreUiSignals);
|
||||
m_ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::setBuildingComponentSettings()
|
||||
{
|
||||
BoolLocker l(m_bIgnoreUiSignals);
|
||||
const BuildingComponentSettings::BldCmpSettings &settingsRef = m_buildingComponentSettings->bldCmpSettings();
|
||||
|
||||
// BuildingSettings
|
||||
const BuildingComponentSettings::BldCmpSettings::BuildingSettings &bldg = settingsRef.buildingSettings;
|
||||
const QSet<int> &hiddenFloorIdsRef = bldg.hiddenFloorIds;
|
||||
for (QCheckBox *cb : qAsConst(m_checkBoxesFloors))
|
||||
{
|
||||
int floor = cb->property(FloorIdProperty).toInt();
|
||||
cb->setChecked(!hiddenFloorIdsRef.contains(floor));
|
||||
}
|
||||
|
||||
|
||||
// ComponentSettings
|
||||
const BuildingComponentSettings::BldCmpSettings::ComponentSettings &comp = settingsRef.componentSettings;
|
||||
m_ui->cbshowAnnouncementUnit->setChecked(comp.showAnnouncementUnit);
|
||||
m_ui->cbshowBuildingControlUnit->setChecked(comp.showBuildingControlUnit);
|
||||
m_ui->cbshowBuildingNetworkSwitch->setChecked(comp.showBuildingNetworkSwitch);
|
||||
m_ui->cbshowBuildingSensorModule->setChecked(comp.showBuildingSensorModule);
|
||||
m_ui->cbshowEffectGenerationControlUnit->setChecked(comp.showEffectGenerationControlUnit);
|
||||
m_ui->cbshowIndoorCamera->setChecked(comp.showIndoorCamera);
|
||||
m_ui->cbshowMeteoDataUnit->setChecked(comp.showMeteoDataUnit);
|
||||
m_ui->cbshowOutdoorCamera->setChecked(comp.showOutdoorCamera);
|
||||
m_ui->cbshowOutdoorControlUnit->setChecked(comp.showOutdoorControlUnit);
|
||||
m_ui->cbshowVirtualIPS->setChecked(comp.showVirtualIPS);
|
||||
|
||||
// In und Out werden zusammengefasst (GUEZE-1478)
|
||||
// m_ui->cbshowIndoorIPS->setChecked(comp.showIndoorIPS);
|
||||
// m_ui->cbshowOutdoorIPS->setChecked(comp.showOutdoorIPS);
|
||||
m_ui->cbshowIPS->setChecked(comp.showIndoorIPS);
|
||||
}
|
||||
|
||||
BuildingComponentSettings::BldCmpSettings BuildingComponentSettingsWidget::getCurrentUiSettings() const
|
||||
{
|
||||
BuildingComponentSettings::BldCmpSettings settings = m_buildingComponentSettings->bldCmpSettings();
|
||||
|
||||
// BldCmpSettings
|
||||
BuildingComponentSettings::BldCmpSettings::BuildingSettings &bldg = settings.buildingSettings;
|
||||
|
||||
QSet<int> hiddenFloorIdsTemp;
|
||||
for (QCheckBox *cb : m_checkBoxesFloors)
|
||||
{
|
||||
if (!cb->isChecked())
|
||||
{
|
||||
int floor = cb->property(FloorIdProperty).toInt();
|
||||
hiddenFloorIdsTemp.insert(floor);
|
||||
}
|
||||
}
|
||||
bldg.hiddenFloorIds = hiddenFloorIdsTemp;
|
||||
|
||||
|
||||
// ComponentSettings
|
||||
BuildingComponentSettings::BldCmpSettings::ComponentSettings &comp = settings.componentSettings;
|
||||
comp.showAnnouncementUnit = m_ui->cbshowAnnouncementUnit->isChecked();
|
||||
comp.showBuildingControlUnit = m_ui->cbshowBuildingControlUnit->isChecked();
|
||||
comp.showBuildingNetworkSwitch = m_ui->cbshowBuildingNetworkSwitch->isChecked();
|
||||
comp.showBuildingSensorModule = m_ui->cbshowBuildingSensorModule->isChecked();
|
||||
comp.showEffectGenerationControlUnit = m_ui->cbshowEffectGenerationControlUnit->isChecked();
|
||||
comp.showIndoorCamera = m_ui->cbshowIndoorCamera->isChecked();
|
||||
comp.showMeteoDataUnit = m_ui->cbshowMeteoDataUnit->isChecked();
|
||||
comp.showOutdoorCamera = m_ui->cbshowOutdoorCamera->isChecked();
|
||||
comp.showOutdoorControlUnit = m_ui->cbshowOutdoorControlUnit->isChecked();
|
||||
comp.showVirtualIPS = m_ui->cbshowVirtualIPS->isChecked();
|
||||
|
||||
// In und Out werden zusammengefasst (GUEZE-1478)
|
||||
comp.showIndoorIPS = m_ui->cbshowIPS->isChecked();
|
||||
comp.showOutdoorIPS = m_ui->cbshowIPS->isChecked();
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onBuildingComponentSettingsChanged()
|
||||
{
|
||||
// callback from m_buildingComponentSettings / BuildingComponentSettings
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, m_doUpdateViaCallback=" << m_doUpdateViaCallback;
|
||||
if (m_doUpdateViaCallback)
|
||||
{
|
||||
updateGuiToFilter();
|
||||
emit unknownChangesRecognized();
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, m_doUpdateViaCallback=" << m_doUpdateViaCallback;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::updateGuiToFilter()
|
||||
{
|
||||
this->onDataChanged(m_buildingComponentSettings);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::readUpdateFilterFromUi()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
if (!m_buildingComponentSettings || m_bIgnoreUiSignals)
|
||||
return;
|
||||
|
||||
m_doUpdateViaCallback = false;
|
||||
const BuildingComponentSettings::BldCmpSettings &settings = getCurrentUiSettings();
|
||||
m_buildingComponentSettings->setBldCmpSettings(settings);
|
||||
m_doUpdateViaCallback = true;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onContextMenuFloorRequested(const QPoint &position)
|
||||
{
|
||||
QWidget *widget = qobject_cast<QWidget *>(sender());
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
QMenu menu(widget);
|
||||
menu.addAction(tr("Select All"), this, &BuildingComponentSettingsWidget::onFloorSelectAll);
|
||||
menu.addAction(tr("Unselect All"), this, &BuildingComponentSettingsWidget::onFloorUnselectAll);
|
||||
menu.exec(widget->mapToGlobal(position));
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onContextMenuComponentRequested(const QPoint &position)
|
||||
{
|
||||
QWidget *widget = qobject_cast<QWidget *>(sender());
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
QMenu menu(widget);
|
||||
menu.addAction(tr("Select All"), this, &BuildingComponentSettingsWidget::onComponentSelectAll);
|
||||
menu.addAction(tr("Unselect All"), this, &BuildingComponentSettingsWidget::onComponentUnselectAll);
|
||||
menu.exec(widget->mapToGlobal(position));
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onFloorSelectAll()
|
||||
{
|
||||
onFloorSelection(true);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onFloorUnselectAll()
|
||||
{
|
||||
onFloorSelection(false);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onFloorSelection(bool onOff)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, m_checkBoxesFloors.size()=" << m_checkBoxesFloors.size();
|
||||
|
||||
for (QCheckBox *cb : qAsConst(m_checkBoxesFloors))
|
||||
{
|
||||
if (cb->isVisible())
|
||||
cb->setChecked(onOff); // signal 'QCheckBox::clicked' will NOT be emitted...
|
||||
} // for
|
||||
|
||||
// ... call once:
|
||||
readUpdateFilterFromUi();
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onComponentSelectAll()
|
||||
{
|
||||
onComponentSelection(true);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onComponentUnselectAll()
|
||||
{
|
||||
onComponentSelection(false);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onComponentSelection(bool onOff)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, m_checkBoxesComponents.size()=" << m_checkBoxesComponents.size();
|
||||
|
||||
// evaluate every QCheckBox immediatly:
|
||||
for (QCheckBox* cb : qAsConst(m_checkBoxesComponents))
|
||||
{
|
||||
if (cb->isVisible())
|
||||
{
|
||||
cb->setChecked(onOff); // signal 'QCheckBox::clicked' will NOT be emitted...
|
||||
}
|
||||
} // for
|
||||
|
||||
// ... call once:
|
||||
readUpdateFilterFromUi();
|
||||
}
|
||||
|
||||
bool BuildingComponentSettingsWidget::setupFloorUi(const QVector<int> &floorIds)
|
||||
{
|
||||
if (!m_ui)
|
||||
return false;
|
||||
|
||||
m_checkBoxesFloors.clear();
|
||||
|
||||
int row = floorIds.size();
|
||||
for (auto floorId : floorIds)
|
||||
{
|
||||
QLabel *lbl = new QLabel(this);
|
||||
QCheckBox *cb = new QCheckBox(this);
|
||||
|
||||
if (floorId == -10)
|
||||
lbl->setText(tr("Exterior:"));
|
||||
else
|
||||
lbl->setText(tr("Floor") + QString(QStringLiteral(" %1:")).arg(floorId));
|
||||
|
||||
cb->setObjectName(lbl->text());
|
||||
cb->setProperty(FloorIdProperty, floorId);
|
||||
connect(cb , &QCheckBox::clicked, this, &BuildingComponentSettingsWidget::readUpdateFilterFromUi);
|
||||
|
||||
{
|
||||
lbl->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(lbl, &QLabel::customContextMenuRequested, this, &BuildingComponentSettingsWidget::onContextMenuFloorRequested);
|
||||
cb->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(cb, &QCheckBox::customContextMenuRequested, this, &BuildingComponentSettingsWidget::onContextMenuFloorRequested);
|
||||
}
|
||||
|
||||
m_checkBoxesFloors.append(cb);
|
||||
|
||||
m_ui->gridLayoutFloor->addWidget(lbl, row, 0);
|
||||
m_ui->gridLayoutFloor->addWidget(cb, row, 1);
|
||||
--row;
|
||||
} // for
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::apply()
|
||||
{
|
||||
readUpdateFilterFromUi();
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::dialogCanceled()
|
||||
{
|
||||
m_buildingComponentSettings->setBldCmpSettings(m_originalBldCmp);
|
||||
}
|
||||
|
||||
void BuildingComponentSettingsWidget::onDataChanged(const std::shared_ptr<BuildingComponentSettings> &newFilter)
|
||||
{
|
||||
m_buildingComponentSettings = newFilter;
|
||||
m_originalBldCmp = newFilter->bldCmpSettings();
|
||||
DEBUG_LOG(m_logger) << "onDataChanged ... " << QJsonDocument(newFilter->bldCmpSettingsToJson()).toJson();
|
||||
setBuildingComponentSettings();
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
Executable
+95
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Participant Symbol Appearance Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVector>
|
||||
#include <QCheckBox>
|
||||
|
||||
class QComboBox;
|
||||
class QTimer;
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class BuildingComponentSettingsWidget;
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class DataInterface;
|
||||
// --------------------------------------------------------
|
||||
//
|
||||
// --------------------------------------------------------
|
||||
class BuildingComponentSettingsWidget final : public QWidget, public BuildingComponentSettings::SettingsChangedCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BuildingComponentSettingsWidget(QWidget *parent = nullptr);
|
||||
~BuildingComponentSettingsWidget();
|
||||
|
||||
void retranslate();
|
||||
bool init(const std::shared_ptr<BuildingComponentSettings> &filter, const std::shared_ptr<InfrastructureManagement::Interface::Dtc> ismDtc);
|
||||
|
||||
void apply();
|
||||
void dialogCanceled();
|
||||
|
||||
std::shared_ptr<BuildingComponentSettings> filter() const { return m_buildingComponentSettings; }
|
||||
void onDataChanged(const std::shared_ptr<BuildingComponentSettings> &newFilter);
|
||||
|
||||
BuildingComponentSettings::BldCmpSettings getCurrentUiSettings() const;
|
||||
|
||||
void onBuildingComponentSettingsChanged(); // callback function
|
||||
void updateGuiToFilter();
|
||||
|
||||
signals:
|
||||
void changesMade();
|
||||
void unknownChangesRecognized();
|
||||
|
||||
private slots:
|
||||
void readUpdateFilterFromUi();
|
||||
void onContextMenuFloorRequested(const QPoint &position);
|
||||
void onContextMenuComponentRequested(const QPoint &position);
|
||||
void onFloorSelectAll();
|
||||
void onFloorUnselectAll();
|
||||
void onFloorSelection(bool onOff);
|
||||
void onComponentSelectAll();
|
||||
void onComponentUnselectAll();
|
||||
void onComponentSelection(bool onOff);
|
||||
|
||||
private:
|
||||
bool setupFloorUi(const QVector<int> &floorIds);
|
||||
void setBuildingComponentSettings();
|
||||
|
||||
private:
|
||||
QList<QCheckBox*> m_checkBoxesComponents;
|
||||
QList<QCheckBox*> m_checkBoxesFloors;
|
||||
|
||||
std::shared_ptr<BuildingComponentSettings> m_buildingComponentSettings;
|
||||
BuildingComponentSettings::BldCmpSettings m_originalBldCmp;
|
||||
bool m_bIgnoreUiSignals;
|
||||
|
||||
Ui::BuildingComponentSettingsWidget *m_ui;
|
||||
bool m_doUpdateViaCallback;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
Executable
+232
@@ -0,0 +1,232 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BuildingComponentSettingsWidget</class>
|
||||
<widget class="QWidget" name="BuildingComponentSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>792</width>
|
||||
<height>370</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Building Component Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_6">
|
||||
<item row="0" column="0" rowspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="0">
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>185</width>
|
||||
<height>148</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayoutFloor"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<layout class="QGridLayout" name="gridLayoutComponents">
|
||||
<item row="10" column="1">
|
||||
<widget class="QCheckBox" name="cbshowBuildingNetworkSwitch">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="cbshowBuildingSensorModule">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="cbshowIPS">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QCheckBox" name="cbshowOutdoorCamera">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="lblComponent_MeteoDataUnit">
|
||||
<property name="text">
|
||||
<string>showMeteoDataUnit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QCheckBox" name="cbshowAnnouncementUnit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblComponent_OutdoorCamera">
|
||||
<property name="text">
|
||||
<string>showOutdoorCamera:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblComponent_BuildingControlUnit">
|
||||
<property name="text">
|
||||
<string>showBuildingControlUnit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lblComponent_VirtualIPS">
|
||||
<property name="text">
|
||||
<string>showVirtualIPS:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="lblComponent_BuildingNetworkSwitch">
|
||||
<property name="text">
|
||||
<string>showBuildingNetworkSwitch:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="cbshowOutdoorControlUnit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="lblComponent_AnnouncementUnit">
|
||||
<property name="text">
|
||||
<string>showAnnouncementUnit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QCheckBox" name="cbshowIndoorCamera">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblComponent_BuildingSensorModule">
|
||||
<property name="text">
|
||||
<string>showBuildingSensorModule:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="cbshowBuildingControlUnit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblComponent_OutdoorControlUnit">
|
||||
<property name="text">
|
||||
<string>showOutdoorControlUnit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="cbshowVirtualIPS">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="cbshowEffectGenerationControlUnit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblComponent_EffectGenerationControlUnit">
|
||||
<property name="text">
|
||||
<string>showEffectGenerationControlUnit:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QCheckBox" name="cbshowMeteoDataUnit">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblComponent_IPS">
|
||||
<property name="text">
|
||||
<string>showIPS:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="lblComponent_IndoorCamera">
|
||||
<property name="text">
|
||||
<string>showIndoorCamera:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>356</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>41</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Executable
+176
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for FilterManagement (Participant)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "flt_building_components_gui_plugin.h"
|
||||
#include "flt_building_component_filter_dialog.h"
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/building_cmpnt_settings_impl.h>
|
||||
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <LtsProjectionWorkstation/lts_projection_workstation.h>
|
||||
#include <FilterManagement/flt_operator_rights.h>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Interface"))
|
||||
, m_logger(getLogger("BuildingComponentInterfaceImpl"))
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<FilterManagement::DataInterface>(m_fltDtc))
|
||||
return false;
|
||||
|
||||
connect(m_fltDtc.get(), &FilterManagement::Interface::Dtc::buildingComponentFilterChanged,
|
||||
this, &InterfaceImpl::onBuildingComponentFilterChanged, Qt::UniqueConnection);
|
||||
|
||||
// NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// filterPresetLoadUnsaved at PWS leads to race condition
|
||||
// (create dtc and update data via request)
|
||||
// enable AesFilter and SymbolAppearance already here
|
||||
|
||||
// 22.01.2025, Thoden: Nachtrag zu NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// GUEZE-3459: Hannas OPW: Hänger beim Login
|
||||
// 1. waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// gehört eingentlich VOR fltDtc->{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// 2. Da diese aber auf der PWS wohl wichtig waren, wird fetchInterfaces jeweils
|
||||
// angepasst:
|
||||
// waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters} wird
|
||||
// nicht mehr grundsätzlich, sondern nur auf der PWS ausgeführt:
|
||||
// if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
// m_fltDtc->waitForHistoricalDataXXX(1000);
|
||||
|
||||
if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
m_fltDtc->waitForHistoricalDataBuildingComponentFilter(1000); // wait... contains enable
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
LtsWidgets::PluginData plData;
|
||||
|
||||
// this plugin 'flt.building_cmpnt' has to be add to apps.json to get 'getActions' be executed.
|
||||
// But the filterFlaf "BuildingName" is also in the SymbolAppearance.
|
||||
// To ensure not to show both, use ProjectSettings: 'enableBuildingComponentFilterEdit'
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableBuildingComponentFilterEdit = ps->value(QStringLiteral("flt"),
|
||||
QStringLiteral("enableBuildingComponentFilterEdit"), false).toBool();
|
||||
if (enableBuildingComponentFilterEdit)
|
||||
{
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Building/Components");
|
||||
plData.identifier = QLatin1String("fltBuildingComponentFilter");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:filter_map_settings.svg")); // ToDo: passendes Icon erstellen
|
||||
plData.operatorRight = OperatorRights::FilterManagement::SymbolAppearanceEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
return LtsWidgets::initDialog(new BuildingComponentFilterDialog(parent), m_session);
|
||||
};
|
||||
ret.append(plData);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InterfaceImpl::onBuildingComponentFilterChanged(const FilterManagement::BuildingComponentFilter &data, DataModification mod)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
auto it = m_buildingComponentFilterMap.find(FilterKey{data.operatorId(), data.ctx()});
|
||||
if (it != m_buildingComponentFilterMap.end())
|
||||
{
|
||||
std::shared_ptr<BuildingComponentSettingsImpl> ret = it->second.lock();
|
||||
if (ret && mod != DataModification::eRemoved)
|
||||
ret->setBldCmpSettingsFromData(data);
|
||||
else
|
||||
{
|
||||
// Maybe the scvFilterManagement (hosted at svcExerciseEventManagement)
|
||||
// is restarted. In that case the topics are removed from DDS.
|
||||
// But when the svc is starting again, the data is inserted into this
|
||||
// map again - but the callbacks are lost!! So some related dialog do
|
||||
// not work anymore... :-(
|
||||
// To avoid this, prevent 'used' SymbolAppearanceSettingsImpl from
|
||||
// being removed:
|
||||
if (!(ret && ret->hasChangedCallbacks()))
|
||||
m_buildingComponentFilterMap.erase(it);
|
||||
}
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<BuildingComponentSettings> InterfaceImpl::buildingComponentSettingsForOperator(int operatorId, const QString &context)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", operatorId=" << operatorId
|
||||
<< ", context=" << context;
|
||||
std::shared_ptr<BuildingComponentSettingsImpl> ret;
|
||||
|
||||
auto it = m_buildingComponentFilterMap.find({operatorId, context.toStdString()});
|
||||
if (it != m_buildingComponentFilterMap.end())
|
||||
ret = it->second.lock();
|
||||
if (!ret)
|
||||
{
|
||||
FilterManagement::BuildingComponentFilter filterData;
|
||||
// it's 0 when there is not yet a filter for this operator, so set it here and use it for comparision
|
||||
filterData.operatorId(operatorId);
|
||||
filterData.ctx(context.toStdString());
|
||||
|
||||
std::function<bool(const FilterManagement::BuildingComponentFilter &)> func = [&filterData](const FilterManagement::BuildingComponentFilter &f)
|
||||
{
|
||||
if (f.operatorId() == filterData.operatorId() &&
|
||||
f.ctx() == filterData.ctx())
|
||||
{
|
||||
filterData = f;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// 22.01.2025, Thoden: Nachtrag zu NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// GUEZE-3459: Hannas OPW: Hänger beim Login
|
||||
// 1. waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// gehört eingentlich VOR fltDtc->{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// 2. Da diese aber auf der PWS wohl wichtig waren, wird fetchInterfaces jeweils
|
||||
// angepasst:
|
||||
// waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters} wird
|
||||
// nicht mehr grundsätzlich, sondern nur auf der PWS ausgeführt:
|
||||
// if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
// m_fltDtc->waitForHistoricalDataXXX(1000);
|
||||
m_fltDtc->waitForHistoricalDataBuildingComponentFilter(1000); // wait... contains enable
|
||||
|
||||
m_fltDtc->buildingComponentFilters(func);
|
||||
|
||||
ret = std::make_shared<BuildingComponentSettingsImpl>(m_session->workspaceId());
|
||||
ret->setBldCmpSettingsFromData(filterData);
|
||||
|
||||
m_buildingComponentFilterMap[FilterKey(operatorId, context.toStdString())] = ret;
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< ", operatorId=" << operatorId
|
||||
<< ", context=" << context;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} //namespace FilterManagement
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for FilterManagement (Participant)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class BuildingComponentSettingsImpl;
|
||||
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:flt.building_cmpnt")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("FilterManagementBuildingComponentGuiPlugin"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
// GUEZE-1769: Schnappschuss und ABT: Entfernen Filter für Etagen / Komponenten
|
||||
// Nachtrag zu r 59394 (branch 23_1_guez_bugfixing)
|
||||
// Wenn das Plugin flt.building_cmpnt nur in Global geladen wird (ResourceApp),
|
||||
// dann muss es im plugin_provider_lts_session.cpp optional sein.
|
||||
return (partition == IDL::PartitionType::Global);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ...
|
||||
class InterfaceImpl final : public QObject, public ForeignFltBuildingComponentGuiInterface, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
QString menuGroup() const override { return tr("Situation Map"); }
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
std::shared_ptr<BuildingComponentSettings> buildingComponentSettingsForOperator(int operatorId, const QString &context) override;
|
||||
|
||||
private slots:
|
||||
void onBuildingComponentFilterChanged(const BuildingComponentFilter &data, DataModification mod);
|
||||
|
||||
private:
|
||||
// <operatorId, filter>
|
||||
struct FilterKey
|
||||
{
|
||||
int operatorId = 0;
|
||||
std::string context;
|
||||
FilterKey() = default;
|
||||
FilterKey(int _operatorId, const std::string &_context)
|
||||
: operatorId(_operatorId)
|
||||
, context(_context)
|
||||
{}
|
||||
bool operator<(const FilterKey &o) const
|
||||
{
|
||||
if (operatorId != o.operatorId)
|
||||
return operatorId < o.operatorId;
|
||||
return context < o.context;
|
||||
}
|
||||
};
|
||||
|
||||
std::map<FilterKey, std::weak_ptr<BuildingComponentSettingsImpl>> m_buildingComponentFilterMap;
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,42 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# Created by Norbert Thoden, NLE, 2019-02-25
|
||||
#
|
||||
|
||||
SET(flt_filter_change_SRCS
|
||||
flt_filter_change.cpp
|
||||
flt_filter_change.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(flt_filter_change_SRCS
|
||||
flt_filter_change.ui
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY2(WS FltFilterChange SHARED ${flt_filter_change_SRCS})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(FltFilterChange
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
${CMAKE_CURRENT_BINARY_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(FltFilterChange
|
||||
PRIVATE
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsUtilsGuiDds # requestHelper
|
||||
FltAesGuiCommon
|
||||
LtsMultiMonitor
|
||||
LtsUtilsSettings
|
||||
PUBLIC
|
||||
LtsWidgets
|
||||
FltDataPluginInterface
|
||||
FltAesGuiPluginInterface
|
||||
FltBldgCmpntGuiPluginInterface
|
||||
OpmGuiPluginInterface
|
||||
Qt5::Core
|
||||
Qt5::Widgets
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(FltFilterChange)
|
||||
@@ -0,0 +1,586 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Select filter settings from other operator
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna Rathje, SLSE, 2017-11-20
|
||||
*/
|
||||
|
||||
#include "flt_filter_change.h"
|
||||
#include "ui_flt_filter_change.h"
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsMultiMonitor/lts_multi_monitor.h>
|
||||
#include <LtsMultiMonitor/lts_screen_base.h>
|
||||
#include <LtsMultiMonitor/lts_screen_normal.h>
|
||||
#include <LtsMultiMonitor/lts_screen_wide.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_aes_display_filter.h>
|
||||
#include <Plugins/SituationMapPlugin/situation_map_gui_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/symbol_appearance_settings_impl.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
FilterChangeDialog::FilterChangeDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Modal)
|
||||
, m_session(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_ui(new Ui::FilterChangeDialog)
|
||||
, m_logger(getLogger("FilterChangeDialog"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &FilterChangeDialog::apply);
|
||||
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &FilterChangeDialog::close);
|
||||
|
||||
// Since FilterChange is only available for App:Situation
|
||||
// and within this app, BuildingComponentFilter gui ist not added to accordeonMenue,
|
||||
// suppress in any case:
|
||||
// LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
// const bool enableBuildingComponentFilterEdit = ps->value(QStringLiteral("flt"),
|
||||
// QStringLiteral("enableBuildingComponentFilterEdit"), false).toBool();
|
||||
|
||||
// m_ui->line_overBuildingComponentFilter->setVisible(enableBuildingComponentFilterEdit);
|
||||
// m_ui->cbBuildingComponentFilter->setVisible(enableBuildingComponentFilterEdit);
|
||||
m_ui->line_overBuildingComponentFilter->hide();
|
||||
m_ui->cbBuildingComponentFilter->hide();
|
||||
|
||||
// GUEZE-1586: Guez hat derzeit per Definition keine ScreenContainer (WideScreenMonitore)
|
||||
if (strcmp(PROJECTBUILD, "guez") == 0)
|
||||
{
|
||||
#ifndef DEBUGGING
|
||||
m_ui->label_ScreenContainer->hide();
|
||||
m_ui->cbxScreenContainer->hide();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
FilterChangeDialog::~FilterChangeDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
bool FilterChangeDialog::init(LtsSession::LtsSession *session,
|
||||
SymbolAppearanceSettings::Part preSelectSymbolAppearanceSettings,
|
||||
bool preSelectAesFilter,
|
||||
bool preSelectBuildingComponentSettings,
|
||||
bool preSelectOperatorMapSettings)
|
||||
{
|
||||
m_session = session;
|
||||
|
||||
if (!m_session)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no session";
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
int myOperatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
int myScreenId = m_session->screenId();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " my operatorId=" << myOperatorId << " my screenId=" << myScreenId;
|
||||
}
|
||||
|
||||
|
||||
if (!m_session->getForeignGuiInterface(m_fltParticipantGuiIfc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign gui interface for FilterManagement/Participant";
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getForeignGuiInterface(m_fltAesIfc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign gui interface for FilterManagement/AES";
|
||||
return false;
|
||||
}
|
||||
if (!m_session->getForeignGuiInterface(m_fltBuildingComponentIfc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get Foreign gui interface for FilterManagement/BuildingComponent";
|
||||
// return false; // since GUEZE-1769: it´s optional
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!m_session->getForeignGuiInterface<OperatorManagement::ForeignGuiComboboxInterface>(m_opmCbxDtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getForeignGuiInterface for OperatorManagement failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_session->getFtc<FilterManagement::DataInterface>(m_fltFtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getFtc for FilterManagement failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_session->getDtc<FilterManagement::DataInterface>(m_fltDtc))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "getDtc for FilterManagement failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fltDtc->enableFilterData();
|
||||
connect(m_fltDtc.get(), &FilterManagement::Interface::Dtc::filterDataChanged,
|
||||
this, &FilterChangeDialog::onFilterDataChanged, Qt::UniqueConnection);
|
||||
|
||||
|
||||
// PreSelection:
|
||||
switch (preSelectSymbolAppearanceSettings)
|
||||
{
|
||||
case SymbolAppearanceSettings::Part::Symbol:
|
||||
m_ui->cbSymbolappear->setChecked(true);
|
||||
break;
|
||||
case SymbolAppearanceSettings::Part::Types:
|
||||
m_ui->cbTypeFilter->setChecked(true);
|
||||
break;
|
||||
case SymbolAppearanceSettings::Part::CollapseExpand:
|
||||
m_ui->cbCollapseExpand->setChecked(true);
|
||||
break;
|
||||
case SymbolAppearanceSettings::Part::All:
|
||||
// All is used as 'nothing'
|
||||
break;
|
||||
} // switch
|
||||
|
||||
m_ui->cbAesFilter->setChecked(preSelectAesFilter);
|
||||
m_ui->cbBuildingComponentFilter->setChecked(preSelectBuildingComponentSettings);
|
||||
m_ui->cbOperatorMapSettings->setChecked(preSelectOperatorMapSettings);
|
||||
|
||||
|
||||
// Operator:
|
||||
// focus on LtsAppDescriptor::App::Situation and ...:
|
||||
// Check: take OC into account?
|
||||
const int currentAppId = static_cast<int>(m_session->app());
|
||||
|
||||
|
||||
|
||||
|
||||
connect(m_ui->cbxOperator, &LtsWidgets::LtsComboBox::currentTextChanged,
|
||||
this, &FilterChangeDialog::onOperatorChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_ui->cbxScreen, &LtsWidgets::LtsComboBox::currentTextChanged,
|
||||
this, &FilterChangeDialog::onScreenChanged, Qt::UniqueConnection);
|
||||
|
||||
connect(m_ui->cbxScreenContainer, &LtsWidgets::LtsComboBox::currentTextChanged,
|
||||
this, &FilterChangeDialog::onScreenContainerChanged, Qt::UniqueConnection);
|
||||
|
||||
onOperatorChanged();
|
||||
enableDisable();
|
||||
|
||||
m_symbolAppearanceSettings = m_fltParticipantGuiIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), m_session->workspaceId());
|
||||
m_aesDisplayFilter = m_fltAesIfc->aesFilterForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), m_session->workspaceId());
|
||||
|
||||
// Nachtrag zu GUEZE-1769: since fltBuildingComponentIfc is optional:
|
||||
if (m_fltBuildingComponentIfc)
|
||||
m_buildingComponentSettings = m_fltBuildingComponentIfc->buildingComponentSettingsForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), m_session->workspaceId());
|
||||
|
||||
if (!m_opmCbxDtc->fillActiveAppOperatorComboBox(m_ui->cbxOperator,
|
||||
currentAppId,
|
||||
m_session->exerciseId(),
|
||||
LtsSessionData::LtsSessionData::getInstance()->getOperatorId()))
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " fillActiveAppOperatorComboBox failed";
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterChangeDialog::onOperatorChanged()
|
||||
{
|
||||
const int operatorId = m_ui->cbxOperator->currentData().toInt();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, change to operatorId=" << operatorId
|
||||
<< ", m_session->exerciseId()=" << m_session->exerciseId();
|
||||
if (!m_opmCbxDtc)
|
||||
return;
|
||||
|
||||
m_filterDataPerScreen.clear();
|
||||
enableDisable();
|
||||
|
||||
// focus on LtsAppDescriptor::App::Situation and...:
|
||||
const int currentAppId = static_cast<int>(m_session->app());
|
||||
m_opmCbxDtc->fillActiveAppScreenComboBox(m_ui->cbxScreen,
|
||||
currentAppId,
|
||||
operatorId,
|
||||
m_session->exerciseId(),
|
||||
true); // preSelectTopmost
|
||||
|
||||
//It´s me?
|
||||
if (operatorId == LtsSessionData::LtsSessionData::getInstance()->getOperatorId())
|
||||
{
|
||||
// disable our/current screenId:
|
||||
const int ourScreenId = m_session->screenId();
|
||||
int idx = m_ui->cbxScreen->findData(ourScreenId);
|
||||
if (idx >= 0)
|
||||
m_ui->cbxScreen->removeItem(idx);
|
||||
}
|
||||
|
||||
|
||||
// publish FLT to trigger updating the FilterData of the selected User/WS:
|
||||
auto cb = [this, operatorId]() -> bool
|
||||
{
|
||||
FilterManagement::TriggerFilterData req;
|
||||
req.operatorId(operatorId);
|
||||
req.requestTime(m_session->partitionTime());
|
||||
INFO_LOG(m_logger) << LOGFUNCTION << "TriggerFilterData: " << req;
|
||||
return m_fltFtc->triggerFilterDataUpdateRequest(req, this);
|
||||
};
|
||||
m_requestHelper->startSingleRequest(cb);
|
||||
|
||||
// req 'TriggerFilterData' will trigger call of 'onFilterDataChanged'
|
||||
// which will fill m_filterDataPerScreen
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, change to operatorId=" << operatorId;
|
||||
}
|
||||
|
||||
|
||||
void FilterChangeDialog::onScreenChanged()
|
||||
{
|
||||
m_ui->cbxScreenContainer->clear();
|
||||
|
||||
const int screenId = m_ui->cbxScreen->currentData().toInt();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, change to ScreenId=" << screenId;
|
||||
|
||||
if (!m_opmCbxDtc)
|
||||
return;
|
||||
|
||||
|
||||
|
||||
QMapIterator<QPair<int /*ScreenId*/, int /*ScreenContainerId*/>, FilterData> it(m_filterDataPerScreen);
|
||||
QSet<int> containers;
|
||||
int screenTypeId = -1; // FIXME: super ugly - determining screen type id
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
|
||||
if (it.key().first != screenId)
|
||||
continue;
|
||||
|
||||
screenTypeId = it.value().screenTypeId();
|
||||
|
||||
containers.insert(it.key().second);
|
||||
}
|
||||
|
||||
if (containers.contains(0))
|
||||
m_ui->cbxScreenContainer->addItem(tr("Fullscreen"), 0);
|
||||
|
||||
// FIXME: un-static.....
|
||||
switch (screenTypeId)
|
||||
{
|
||||
case 0: // normal
|
||||
break;
|
||||
|
||||
case 1: // wide
|
||||
{
|
||||
if (containers.contains(1))
|
||||
m_ui->cbxScreenContainer->addItem(tr("Left side"), 1);
|
||||
if (containers.contains(2))
|
||||
m_ui->cbxScreenContainer->addItem(tr("Right side"), 2);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUGGING
|
||||
if (m_ui->cbxScreenContainer->count() == 0)
|
||||
{
|
||||
m_ui->cbxScreenContainer->addItem(QString(QStringLiteral("Container'-2'")), -2);
|
||||
m_ui->cbxScreenContainer->addItem(QString(QStringLiteral("Container'-1'")), -1);
|
||||
m_ui->cbxScreenContainer->addItem(QString(QStringLiteral("Container'0'")), 0);
|
||||
}
|
||||
#endif // DEBUGGING
|
||||
|
||||
|
||||
enableDisable();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, change to ScreenId=" << screenId;
|
||||
}
|
||||
|
||||
|
||||
void FilterChangeDialog::onScreenContainerChanged()
|
||||
{
|
||||
const int screenContainerId = m_ui->cbxScreen->currentData().toInt();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, change to ScreenContainerId=" << screenContainerId;
|
||||
if (!m_opmCbxDtc)
|
||||
return;
|
||||
enableDisable();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, change to ScreenContainerId=" << screenContainerId;
|
||||
}
|
||||
|
||||
void FilterChangeDialog::onFilterDataChanged(const FilterData &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, we got FilterData " << data
|
||||
<< ", modType " << modType;
|
||||
|
||||
if ((modType != DataModification::eAdded) && (modType != DataModification::eModified))
|
||||
return;
|
||||
if (data.operatorId() <= 0)
|
||||
return;
|
||||
|
||||
const int requestedOperatorId = m_ui->cbxOperator->currentData().toInt();
|
||||
if (requestedOperatorId <= 0)
|
||||
return;
|
||||
|
||||
if (data.operatorId() != requestedOperatorId)
|
||||
return;
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, we got new FilterData for 'our' operator: " << data;
|
||||
|
||||
// check age here???
|
||||
|
||||
// FIXME: hack: we need to know what screen is of which type (normal, wide) to determine what containers are selectable
|
||||
//m_screenTypes.insert(data.screenId(), data.screenTypeId());
|
||||
|
||||
const int screenId = data.screenId();
|
||||
const int screenContainerId = data.screenContainerId();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION
|
||||
<< " insert " << " QPair<> "
|
||||
<< "(screenId, " << screenId
|
||||
<< "(screenContainerId, " << screenContainerId << ")"
|
||||
<< " -> dara " << data;
|
||||
m_filterDataPerScreen[QPair<int,int>(screenId, screenContainerId)] = data;
|
||||
|
||||
enableDisable();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
bool FilterChangeDialog::apply()
|
||||
{
|
||||
const int screenId = m_ui->cbxScreen->currentData().toInt();
|
||||
const int screenContainerId = m_ui->cbxScreenContainer->currentData().toInt();
|
||||
|
||||
if (!m_filterDataPerScreen.contains(QPair<int,int>(screenId, screenContainerId)))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " not found: "
|
||||
<< " screenId=" << screenId
|
||||
<< ", screenContainerId=" << screenContainerId
|
||||
<< "; available screenId count = " << m_filterDataPerScreen.count();
|
||||
return false;
|
||||
}
|
||||
|
||||
const FilterData &fData = m_filterDataPerScreen[QPair<int,int>(screenId, screenContainerId)];
|
||||
|
||||
//
|
||||
// SymbolAppearance
|
||||
//
|
||||
if (m_ui->cbSymbolappear->isChecked() ||
|
||||
m_ui->cbTypeFilter->isChecked() ||
|
||||
m_ui->cbCollapseExpand->isChecked())
|
||||
{
|
||||
if (fData.symbolAppearanceContent().size() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " FilterData (SymbolAppearance) is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
// N. Thoden, Aug 2021:
|
||||
// Beim Laden der Filter aus einer anderen App wurden auch die nicht
|
||||
// angewählten Anteil aus der entfernten App übernommen :-(
|
||||
// Ablauf ist vereinacht:
|
||||
|
||||
// merge a) checked part of other/remote settings into b) own:
|
||||
// fData into symbolAppearanceUpdateRequest
|
||||
SymbolAppearanceSettings::Settings s;
|
||||
{
|
||||
SymbolAppearance symbolAppearanceDDS;
|
||||
symbolAppearanceDDS.content(fData.symbolAppearanceContent());
|
||||
|
||||
// convert content to settings:
|
||||
FilterManagement::SymbolAppearanceSettingsImpl impl(nullptr);
|
||||
impl.setSettingsFromData(symbolAppearanceDDS); // will trransfer content to m_settings
|
||||
s = impl.settings(); // retrive settings
|
||||
}
|
||||
|
||||
DEBUG_LOG(m_logger) << " set SymbolAppearance..."
|
||||
<< " m_ui->cbSymbolappear->isChecked()=" << m_ui->cbSymbolappear->isChecked()
|
||||
<< " m_ui->cbTypeFilter->isChecked()=" << m_ui->cbTypeFilter->isChecked()
|
||||
<< " m_ui->cbCollapseExpand->isChecked()=" << m_ui->cbCollapseExpand->isChecked();
|
||||
if (m_ui->cbSymbolappear->isChecked())
|
||||
m_symbolAppearanceSettings->setSettings(s, FilterManagement::SymbolAppearanceSettings::Part::Symbol);
|
||||
if (m_ui->cbTypeFilter->isChecked())
|
||||
m_symbolAppearanceSettings->setSettings(s, FilterManagement::SymbolAppearanceSettings::Part::Types);
|
||||
if (m_ui->cbCollapseExpand->isChecked())
|
||||
m_symbolAppearanceSettings->setSettings(s, FilterManagement::SymbolAppearanceSettings::Part::CollapseExpand);
|
||||
|
||||
auto cb = [this]() -> bool
|
||||
{
|
||||
const SymbolAppearance &symbolAppearance = m_symbolAppearanceSettings->settingsToData();
|
||||
INFO_LOG(m_logger) << "symbolAppearance content " << symbolAppearance.content();
|
||||
return m_fltFtc->symbolAppearanceUpdateRequest(symbolAppearance, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
}
|
||||
|
||||
//
|
||||
// AesFilter
|
||||
//
|
||||
if (m_ui->cbAesFilter->isChecked())
|
||||
{
|
||||
if (fData.aesFilterContent().size() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " FilterData (AesFilter) is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
// get current:
|
||||
AesFilter aesFilter = m_aesDisplayFilter->filterToData();
|
||||
|
||||
// update content:
|
||||
aesFilter.content(fData.aesFilterContent());
|
||||
|
||||
// write back:
|
||||
m_aesDisplayFilter->setFilterFromData(aesFilter);
|
||||
|
||||
auto cb = [this]() -> bool
|
||||
{
|
||||
const AesFilter &aesFilter = m_aesDisplayFilter->filterToData();
|
||||
INFO_LOG(m_logger) << "AesFilter content " << aesFilter.content();
|
||||
return m_fltFtc->aesFilterUpdateRequest(aesFilter, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
}
|
||||
|
||||
//
|
||||
// BuildingComponentFilter
|
||||
//
|
||||
if (m_ui->cbBuildingComponentFilter->isChecked() && m_ui->cbBuildingComponentFilter->isVisible())
|
||||
{
|
||||
if (fData.buildingComponentsFilterContent().size() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " FilterData (BuildingComponentFilter) is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
// get current:
|
||||
BuildingComponentFilter buildingComponentFilter = m_buildingComponentSettings->bldCmpSettingsToData();
|
||||
|
||||
// update content:
|
||||
buildingComponentFilter.content(fData.buildingComponentsFilterContent());
|
||||
|
||||
// write back:
|
||||
m_buildingComponentSettings->setBldCmpSettingsFromData(buildingComponentFilter);
|
||||
|
||||
auto cb = [this]() -> bool
|
||||
{
|
||||
const BuildingComponentFilter &filterData = m_buildingComponentSettings->bldCmpSettingsToData();
|
||||
INFO_LOG(m_logger) << "BuildingComponentFilter content " << filterData.content();
|
||||
return m_fltFtc->buildingComponentFilterUpdateRequest(filterData, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// OperatorMapSettings
|
||||
//
|
||||
if (m_ui->cbOperatorMapSettings->isChecked())
|
||||
{
|
||||
if (fData.operatorMapSettingsContent().size() <= 0)
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " FilterData (OperatorMapSettings) is empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<SituationMap::ForeignGuiInterface> sitMapIfc;
|
||||
if (!m_session->getForeignGuiInterface<SituationMap::ForeignGuiInterface>(sitMapIfc))
|
||||
{
|
||||
ERROR_LOG(m_logger) << LOGFUNCTION << " no SituationMap::ForeignGuiInterface";
|
||||
return false;
|
||||
}
|
||||
sitMapIfc->setOperatorMapSettingsJson(QByteArray::fromRawData(fData.operatorMapSettingsContent().c_str(), fData.operatorMapSettingsContent().size()));
|
||||
}
|
||||
|
||||
bool ret = true;
|
||||
if (m_requestHelper->hasRequests())
|
||||
ret = m_requestHelper->startRequests();
|
||||
|
||||
close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void FilterChangeDialog::onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
void FilterChangeDialog::onAesFilterUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
void FilterChangeDialog::onBuildingComponentFilterUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void FilterChangeDialog::onTriggerFilterDataUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void FilterChangeDialog::enableDisable()
|
||||
{
|
||||
// qCritical() << " enableDisable";
|
||||
|
||||
{
|
||||
int myOperatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
int myScreenId = m_session->screenId();
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " my operatorId=" << myOperatorId << " my screenId=" << myScreenId;
|
||||
}
|
||||
|
||||
|
||||
const int cbxOperatorId = m_ui->cbxOperator->currentData().toInt();
|
||||
const int cbxScreenId = m_ui->cbxScreen->currentData().toInt();
|
||||
const int cbxScreenContainerId = m_ui->cbxScreenContainer->currentData().toInt();
|
||||
//const QList<QPair<int,int> > availableScreenIds = m_filterDataPerScreen.keys();
|
||||
|
||||
|
||||
// const int cnt = m_ui->cbxScreen->count();
|
||||
// qCritical() << " yyyyyyyyy" << cnt;
|
||||
|
||||
const bool screenOk = (cbxScreenId >=0) && (cbxScreenId <=4) && (m_ui->cbxScreen->count() > 0);
|
||||
const bool ena = (cbxOperatorId > 0) && screenOk && m_filterDataPerScreen.contains(QPair<int,int>(cbxScreenId, cbxScreenContainerId));
|
||||
m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(ena);
|
||||
// qCritical() << " yyyyyyyyy" << ena;
|
||||
|
||||
dump();
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " cbxScreenId=" << cbxScreenId
|
||||
<< " cbxScreenContainerId=" << cbxScreenContainerId
|
||||
<< ", availableScreenId count=" << m_filterDataPerScreen.count()
|
||||
<< ", DialogButton::Ok: enabled=" << m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->isEnabled();
|
||||
}
|
||||
|
||||
void FilterChangeDialog::dump()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " -------------------------";
|
||||
{
|
||||
int myOperatorId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
int myScreenId = m_session->screenId();
|
||||
DEBUG_LOG(m_logger)<< ", myOperatorId=" << myOperatorId << ", myScreenId=" << myScreenId;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
const int cbxOperatorId = m_ui->cbxOperator->currentData().toInt();
|
||||
const int cbxScreenId = m_ui->cbxScreen->currentData().toInt();
|
||||
const int cbxScreenContainerId = m_ui->cbxScreenContainer->currentData().toInt();
|
||||
DEBUG_LOG(m_logger)<< ", cbxOperatorId=" << cbxOperatorId << ", cbxScreenId=" << cbxScreenId << ", cbxScreenContainerId=" << cbxScreenContainerId;
|
||||
}
|
||||
|
||||
QMapIterator<QPair<int /*ScreenId*/, int /*ScreenContainerId*/>, FilterData> it(m_filterDataPerScreen);
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
QPair<int,int> key = it.key();
|
||||
DEBUG_LOG(m_logger) << " ScreenId=" << key.first << ", ScreenContainerId=" << key.second;
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " -------------------------";
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,106 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Select filter settings from other operator
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Hanna Rathje, SLSE, 2017-11-20
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Plugins/FilterManagement/Gui/FilterChange/fltfilterchange_export.h>
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <OperatorManagement/opm_gui_combobox_plugin_interface.h>
|
||||
#include <FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_plugin_interface.h>
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FilterChangeDialog;
|
||||
}
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class FLTFILTERCHANGE_EXPORT FilterChangeDialog final : public LtsWidgets::LtsFramelessDialog
|
||||
, private FilterManagement::Interface::Ftc::SymbolAppearanceUpdateReplyHandler
|
||||
, private FilterManagement::Interface::Ftc::AesFilterUpdateReplyHandler
|
||||
, private FilterManagement::Interface::Ftc::BuildingComponentFilterUpdateReplyHandler
|
||||
, private FilterManagement::Interface::Ftc::TriggerFilterDataUpdateReplyHandler
|
||||
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FilterChangeDialog(QWidget *parent = nullptr);
|
||||
~FilterChangeDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session,
|
||||
SymbolAppearanceSettings::Part preSelectSymbolAppearanceSettings = SymbolAppearanceSettings::Part::All,
|
||||
bool preSelectAesFilter = false,
|
||||
bool preSelectBuildingComponentSettings = false,
|
||||
bool preSelectOperatorMapSettings = false);
|
||||
|
||||
static bool isAvailableAtApp(const LtsAppDescriptor::App app)
|
||||
{
|
||||
// GUEZE-1771: Plan Overlay: Kein Speichern von Filtern / Arbeitsbereichen möglich
|
||||
return (app == LtsAppDescriptor::App::Situation) ||
|
||||
(app == LtsAppDescriptor::App::ScriptEditorEssentialsView) ||
|
||||
(app == LtsAppDescriptor::App::PlanEditor)
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
bool apply();
|
||||
void onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onAesFilterUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onBuildingComponentFilterUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void onTriggerFilterDataUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
void enableDisable();
|
||||
|
||||
void dump();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onOperatorChanged();
|
||||
void onScreenChanged();
|
||||
void onScreenContainerChanged();
|
||||
void onFilterDataChanged(const FilterManagement::FilterData &data, DataModification modType);
|
||||
|
||||
|
||||
private:
|
||||
LtsSession::LtsSession *m_session;
|
||||
std::shared_ptr<OperatorManagement::ForeignGuiComboboxInterface> m_opmCbxDtc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantGuiIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltBuildingComponentGuiInterface> m_fltBuildingComponentIfc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
|
||||
|
||||
QMap<int, int> m_screenTypes;
|
||||
QMap<QPair<int /*ScreenId*/, int /*ScreenContainerId*/>, FilterData> m_filterDataPerScreen; // NOTE: contains the filter data of the requested operator!
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> m_symbolAppearanceSettings;
|
||||
std::shared_ptr<AesDisplayFilter> m_aesDisplayFilter;
|
||||
std::shared_ptr<BuildingComponentSettings> m_buildingComponentSettings;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
Ui::FilterChangeDialog *m_ui;
|
||||
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FilterChangeDialog</class>
|
||||
<widget class="QWidget" name="FilterChangeDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>321</width>
|
||||
<height>326</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Load Operator Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbxOperator">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbxScreen">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Screen:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Operator:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_ScreenContainer">
|
||||
<property name="text">
|
||||
<string>Container:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbxScreenContainer">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="Line" name="line_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbSymbolappear">
|
||||
<property name="text">
|
||||
<string>Symbol appearance</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbTypeFilter">
|
||||
<property name="text">
|
||||
<string>Type filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbCollapseExpand">
|
||||
<property name="text">
|
||||
<string>Collapse / Expand Participants</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="cbOperatorMapSettings">
|
||||
<property name="text">
|
||||
<string>Operator Map Settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="cbAesFilter">
|
||||
<property name="text">
|
||||
<string>Aes Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="Line" name="line_overBuildingComponentFilter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QCheckBox" name="cbBuildingComponentFilter">
|
||||
<property name="text">
|
||||
<string>Building Component Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsDialogButtonBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>LtsWidgets/lts_dialog_button_box.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,75 @@
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by Christian Ehrlicher, SLSE, 2017-06-16
|
||||
#
|
||||
|
||||
SET(flt_part_widget_SRCS
|
||||
flt_collapse_expand_participants_widget.cpp
|
||||
flt_collapse_expand_participants_widget.h
|
||||
flt_symbol_appearance_widget.cpp
|
||||
flt_symbol_appearance_widget.h
|
||||
flt_type_filter_widget.cpp
|
||||
flt_type_filter_widget.h
|
||||
)
|
||||
|
||||
NGL_WRAP_UI(flt_part_widget_SRCS
|
||||
flt_collapse_expand_participants_widget.ui
|
||||
flt_symbol_appearance_widget.ui
|
||||
flt_type_filter_widget.ui
|
||||
)
|
||||
NGL_ADD_LIBRARY(WS FltParticipantWidget STATIC ${flt_part_widget_SRCS})
|
||||
NGL_TARGET_LINK_LIBRARIES(FltParticipantWidget
|
||||
PRIVATE
|
||||
svcFltCommon
|
||||
PpmCommon
|
||||
LtsProjectionWorkstation
|
||||
PUBLIC
|
||||
AsbDataPluginInterface
|
||||
FltDataPluginInterface
|
||||
PdmGuiPluginInterface
|
||||
PpmGuiComboboxPluginInterface
|
||||
Qt5::Widgets
|
||||
)
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(FltParticipantWidget
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../..
|
||||
)
|
||||
|
||||
|
||||
SET(flt_part_gui_SRCS
|
||||
flt_collapse_expand_participants_dialog.cpp
|
||||
flt_collapse_expand_participants_dialog.h
|
||||
flt_participant_gui_plugin.cpp
|
||||
flt_participant_gui_plugin.h
|
||||
flt_symbol_appearance_dialog.cpp
|
||||
flt_symbol_appearance_dialog.h
|
||||
flt_type_filter_dialog.cpp
|
||||
flt_type_filter_dialog.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(WS FltParticipantGuiPlugin MODULE ${flt_part_gui_SRCS})
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(FltParticipantGuiPlugin
|
||||
AsbDataPluginInterface
|
||||
LtsPrinting
|
||||
FltFilterChange
|
||||
FltDataPluginInterface
|
||||
FltParticipantGuiPluginInterface
|
||||
FltParticipantWidget
|
||||
PdmGuiPluginInterface
|
||||
PpmGuiComboboxPluginInterface
|
||||
PpmDataPluginInterface
|
||||
PpmCommon
|
||||
FlmDataPluginInterface
|
||||
FltAesGuiCommon
|
||||
svcFltCommon
|
||||
LtsSession
|
||||
LtsSessionData
|
||||
LtsUtilsGuiDds
|
||||
LtsUtilsSettings
|
||||
LtsWidgets
|
||||
Qt5::Widgets
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(FltParticipantGuiPlugin)
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Collapse/Expand Participants
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "flt_collapse_expand_participants_dialog.h"
|
||||
#include <FilterManagement/Gui/FilterChange/flt_filter_change.h>
|
||||
|
||||
#include <AdvancedSymbology/asb_data_plugin_interface.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
|
||||
#include <LtsPrinting/printing.h>
|
||||
#include <QGridLayout>
|
||||
#include <QTreeView>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
CollapseExpandParticipantDialog::CollapseExpandParticipantDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_widget(new CollapseExpandParticipantWidget)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_session(nullptr)
|
||||
, m_logger(getLogger("CollapseExpandParticipantDialog"))
|
||||
{
|
||||
QGridLayout *gl = new QGridLayout(this);
|
||||
gl->setMargin(0);
|
||||
gl->addWidget(m_widget, 0, 0);
|
||||
|
||||
connect(m_widget, &CollapseExpandParticipantWidget::changesMade,
|
||||
this, &CollapseExpandParticipantDialog::slotChangesMade);
|
||||
connect(m_widget, &CollapseExpandParticipantWidget::modelResetted,
|
||||
this, &CollapseExpandParticipantDialog::__unchange__);
|
||||
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Print, this, &CollapseExpandParticipantDialog::onPrint);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Collapse-Expand"));
|
||||
}
|
||||
|
||||
CollapseExpandParticipantDialog::~CollapseExpandParticipantDialog()
|
||||
{
|
||||
delete m_widget;
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantDialog::retranslate()
|
||||
{
|
||||
m_widget->retranslate();
|
||||
|
||||
// lupdate doesn't like translate(tr("foo")) ...
|
||||
const QString txt(tr("Collapse/Expand Participants"));
|
||||
translate(txt);
|
||||
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
bool CollapseExpandParticipantDialog::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
m_session = session;
|
||||
if (!session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(m_ppmGuiCbxIfc) ||
|
||||
!session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc) ||
|
||||
!session->getForeignGuiInterface(m_fltParticipantIfc) ||
|
||||
!session->getDtc<FilterManagement::DataInterface>(m_fltDtc) ||
|
||||
!session->getFtc<FilterManagement::DataInterface>(m_fltFtc))
|
||||
return false;
|
||||
|
||||
connect(m_fltDtc.get(), &FilterManagement::Interface::Dtc::symbolAppearanceChanged,
|
||||
this, &CollapseExpandParticipantDialog::onDataChanged);
|
||||
|
||||
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> asb;
|
||||
session->getForeignDataInterface<AdvancedSymbology::DataInterface>(asb);
|
||||
auto symbolAppearanceSettings = m_fltParticipantIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(),
|
||||
m_session->workspaceId());
|
||||
m_widget->init(m_ppmDtc, m_ppmGuiCbxIfc, asb, /*m_fltParticipantIfc,*/ symbolAppearanceSettings);
|
||||
|
||||
if (FilterChangeDialog::isAvailableAtApp(m_session->app()))
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Load filter"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load,
|
||||
this, &CollapseExpandParticipantDialog::onLoadButtonClicked);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CollapseExpandParticipantDialog::apply()
|
||||
{
|
||||
m_widget->apply();
|
||||
|
||||
const SymbolAppearance symbolAppearance = m_widget->filter()->settingsToData();
|
||||
auto cb = [symbolAppearance, this]() -> bool
|
||||
{
|
||||
return m_fltFtc->symbolAppearanceUpdateRequest(symbolAppearance, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantDialog::dialogCanceled()
|
||||
{
|
||||
m_widget->dialogCanceled();
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantDialog::onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantDialog::onLoadButtonClicked()
|
||||
{
|
||||
FilterChangeDialog *dialog = new FilterChangeDialog(this);
|
||||
if (!dialog->init(m_session, SymbolAppearanceSettings::Part::CollapseExpand))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QObject::connect(dialog, &FilterChangeDialog::rejected, dialog, &FilterChangeDialog::deleteLater);
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantDialog::onDataChanged(const SymbolAppearance &data, DataModification modType)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onDataChanged ... " << data;
|
||||
if (modType != DataModification::eRemoved &&
|
||||
data.operatorId() == LtsSessionData::LtsSessionData::getInstance()->getOperatorId())
|
||||
{
|
||||
auto symbolAppearanceSettings = m_fltParticipantIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(),
|
||||
m_session->workspaceId());
|
||||
m_widget->onDataChanged(symbolAppearanceSettings);
|
||||
|
||||
// the data can be changed if another replay is selected or filter are loaded.
|
||||
// So our widget has to be updated:
|
||||
__unchange__();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CollapseExpandParticipantDialog::onPrint()
|
||||
{
|
||||
LtsPrinting::printView(m_session, this, m_widget->treeView());
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Collapse/Expand Participants
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flt_collapse_expand_participants_widget.h"
|
||||
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <FilterManagement/flt_ftc.h>
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSession;
|
||||
}
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
class ParticipantEditModel;
|
||||
}
|
||||
namespace FilterManagement
|
||||
{
|
||||
class CollapseExpandParticipantDialog final : public LtsWidgets::LtsDialog
|
||||
, private FilterManagement::Interface::Ftc::SymbolAppearanceUpdateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CollapseExpandParticipantDialog(QWidget *parent = nullptr);
|
||||
~CollapseExpandParticipantDialog();
|
||||
|
||||
void retranslate() override;
|
||||
bool init(LtsSession::LtsSession *session);
|
||||
protected:
|
||||
bool apply() override;
|
||||
void dialogCanceled() override;
|
||||
private slots:
|
||||
void onLoadButtonClicked();
|
||||
void onDataChanged(const FilterManagement::SymbolAppearance &data, DataModification modType);
|
||||
void onPrint();
|
||||
|
||||
private:
|
||||
void onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
private:
|
||||
CollapseExpandParticipantWidget *m_widget;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
|
||||
LtsSession::LtsSession *m_session;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmGuiCbxIfc;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
+265
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Collapse/Expand Participants
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "flt_collapse_expand_participants_widget.h"
|
||||
#include "ui_flt_collapse_expand_participants_widget.h"
|
||||
#include <FilterManagement/Gui/FilterChange/flt_filter_change.h>
|
||||
|
||||
#include <ParticipantManagement/Gui/Common/participant_edit_model.h>
|
||||
#include <ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
#include <nglwidgets/ngltreeitem.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
#include <QMenu>
|
||||
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
int CollapseExpandParticipantWidget::s_preselectedParty = -1;
|
||||
|
||||
CollapseExpandParticipantWidget::CollapseExpandParticipantWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_model(nullptr)
|
||||
, m_ui(new Ui::CollapseExpandParticipantWidget)
|
||||
, m_logger(getLogger("CollapseExpandParticipantWidget"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->tvParticipants, &QTreeView::customContextMenuRequested,
|
||||
this, &CollapseExpandParticipantWidget::showContextMenu);
|
||||
connect(m_ui->tvParticipants, &QTreeView::expanded,
|
||||
this, &CollapseExpandParticipantWidget::changesMade);
|
||||
connect(m_ui->tvParticipants, &QTreeView::collapsed,
|
||||
this, &CollapseExpandParticipantWidget::changesMade);
|
||||
connect(this, &CollapseExpandParticipantWidget::changesMade,
|
||||
this, [this]() { setWindowModified(true); });
|
||||
connect(m_ui->cbParty, static_cast<void (LtsWidgets::LtsComboBox::*)(int)>(&LtsWidgets::LtsComboBox::currentIndexChanged),
|
||||
this, &CollapseExpandParticipantWidget::onPartyChanged);
|
||||
}
|
||||
|
||||
CollapseExpandParticipantWidget::~CollapseExpandParticipantWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::retranslate()
|
||||
{
|
||||
m_ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
bool CollapseExpandParticipantWidget::init(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmIfc,
|
||||
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc,
|
||||
// const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
|
||||
const std::shared_ptr<SymbolAppearanceSettings> &filter)
|
||||
{
|
||||
m_ppmDtc = ppmDtc;
|
||||
m_ppmGuiCbxIfc = ppmIfc;
|
||||
// m_fltParticipantIfc = fltParticipantIfc;
|
||||
m_symbolAppearanceSettings = filter;
|
||||
|
||||
#ifdef TABLET_MODE
|
||||
//css didn"t worked
|
||||
m_ui->tvParticipants->setIconSize(QSize(50,50));
|
||||
#endif
|
||||
|
||||
m_model = new ParticipantManagement::ParticipantEditModel(this, m_ppmDtc, asbIfc);
|
||||
m_model->setRowsCheckable(true);
|
||||
m_ui->tvParticipants->setModel(m_model);
|
||||
#ifndef LTS_DEBUG
|
||||
m_ui->tvParticipants->hideColumn(ParticipantManagement::ParticipantEditModel::ColParticipantId);
|
||||
#endif
|
||||
connect(m_model, &ParticipantManagement::ParticipantEditModel::dataChanged,
|
||||
this, &CollapseExpandParticipantWidget::onModelDataChanged, Qt::UniqueConnection);
|
||||
|
||||
m_originalSymbolAppearance = m_symbolAppearanceSettings->settings();
|
||||
m_currentSymbolAppearance = m_originalSymbolAppearance;
|
||||
|
||||
m_ppmGuiCbxIfc->fillPartyComboBox(m_ui->cbParty, ParticipantManagement::ForeignGuiComboboxInterface::CbxPartyFilter::NormalOc);
|
||||
const int idx = m_ui->cbParty->findData(s_preselectedParty);
|
||||
if (idx >= 0)
|
||||
m_ui->cbParty->setCurrentIndex(idx);
|
||||
onPartyChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void mergeParticipantIds(QSet<int> &idsToUpdate, const QSet<int> &affectedIds, const QSet<int> &idsToAdd)
|
||||
{
|
||||
// remove all currently affectedIds (= ids for a specific party) from the
|
||||
// idSet to update
|
||||
auto it = idsToUpdate.begin();
|
||||
while (it != idsToUpdate.end())
|
||||
{
|
||||
if (affectedIds.contains(*it))
|
||||
it = idsToUpdate.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
// now add the new ids to the idSet to update
|
||||
idsToUpdate += idsToAdd;
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::apply()
|
||||
{
|
||||
const QSet<int> currentParticipantIds = m_model->participantIds();
|
||||
const QSet<int> newHiddenParticipantIds = m_model->checkStateForParticipants(Qt::Unchecked);
|
||||
const QSet<int> collapsedParticipantIds = collapsedParticipants(m_ui->tvParticipants->rootIndex());
|
||||
|
||||
mergeParticipantIds(m_currentSymbolAppearance.colExpand.hiddenParticipantIds, currentParticipantIds, newHiddenParticipantIds);
|
||||
mergeParticipantIds(m_currentSymbolAppearance.colExpand.collapsedParticipantIds, currentParticipantIds, collapsedParticipantIds);
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
{
|
||||
QStringList sl;
|
||||
sl.reserve(m_currentSymbolAppearance.colExpand.hiddenParticipantIds.size());
|
||||
for (int i : qAsConst(m_currentSymbolAppearance.colExpand.hiddenParticipantIds))
|
||||
sl += QString::number(i);
|
||||
DEBUG_LOG(m_logger) << "Hidden participant ids: " << sl.join(QLatin1Char(' '));
|
||||
sl.clear();
|
||||
for (int i : qAsConst(m_currentSymbolAppearance.colExpand.collapsedParticipantIds))
|
||||
sl += QString::number(i);
|
||||
DEBUG_LOG(m_logger) << "Collapsed participant ids: " << sl.join(QLatin1Char(' '));
|
||||
}
|
||||
|
||||
m_symbolAppearanceSettings->setSettings(m_currentSymbolAppearance, SymbolAppearanceSettings::Part::CollapseExpand);
|
||||
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::dialogCanceled()
|
||||
{
|
||||
m_symbolAppearanceSettings->setSettings(m_originalSymbolAppearance, SymbolAppearanceSettings::Part::CollapseExpand);
|
||||
}
|
||||
|
||||
QTreeView *CollapseExpandParticipantWidget::treeView()
|
||||
{
|
||||
return m_ui->tvParticipants;
|
||||
}
|
||||
|
||||
|
||||
void CollapseExpandParticipantWidget::onModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
|
||||
{
|
||||
Q_UNUSED(topLeft);
|
||||
Q_UNUSED(bottomRight);
|
||||
if (roles.isEmpty() || roles.contains(Qt::CheckStateRole))
|
||||
emit changesMade();
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::onPartyChanged()
|
||||
{
|
||||
const int newPartyId = m_ui->cbParty->currentData().toInt();
|
||||
s_preselectedParty = newPartyId;
|
||||
if (m_model->partyId() == newPartyId)
|
||||
return;
|
||||
if (isWindowModified())
|
||||
{
|
||||
switch (LtsWidgets::LtsMessageDialog::askApplyDiscardCancel(this))
|
||||
{
|
||||
case LtsWidgets::Button::Apply:
|
||||
apply();
|
||||
doReinitModel(newPartyId);
|
||||
break;
|
||||
case LtsWidgets::Button::Cancel:
|
||||
m_ui->cbParty->setCurrentIndex(m_ui->cbParty->findData(m_model->partyId(), Qt::UserRole));
|
||||
s_preselectedParty = m_ui->cbParty->currentData().toInt();
|
||||
break;
|
||||
case LtsWidgets::Button::Discard:
|
||||
m_currentSymbolAppearance = m_originalSymbolAppearance;
|
||||
doReinitModel(newPartyId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
doReinitModel(newPartyId);
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::doReinitModel(int newPartyId)
|
||||
{
|
||||
m_model->onReinitModel(newPartyId,
|
||||
m_currentSymbolAppearance.colExpand.hiddenParticipantIds,
|
||||
Qt::Unchecked);
|
||||
m_ui->tvParticipants->setUpdatesEnabled(false);
|
||||
collapseExpand(m_ui->tvParticipants->rootIndex());
|
||||
for (int i = 0; i < m_model->columnCount(QModelIndex()); ++i)
|
||||
m_ui->tvParticipants->resizeColumnToContents(i);
|
||||
m_ui->tvParticipants->header()->resizeSection(0, m_ui->tvParticipants->columnWidth(0) + m_ui->tvParticipants->iconSize().width() + 10);
|
||||
m_ui->tvParticipants->setUpdatesEnabled(true);
|
||||
emit modelResetted();
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::collapseExpand(const QModelIndex &idx)
|
||||
{
|
||||
auto *item = static_cast<ParticipantManagement::ParticipantEditModel::CheckedTreeItem *>(m_model->privateData(idx));
|
||||
const auto &data = item->participant;
|
||||
if (m_currentSymbolAppearance.colExpand.collapsedParticipantIds.contains(data.id()))
|
||||
m_ui->tvParticipants->collapse(idx);
|
||||
else
|
||||
m_ui->tvParticipants->expand(idx);
|
||||
for (int row = 0; row < m_model->rowCount(idx); ++row)
|
||||
collapseExpand(m_model->index(row, 0, idx));
|
||||
}
|
||||
|
||||
QSet<int> CollapseExpandParticipantWidget::collapsedParticipants(const QModelIndex &idx) const
|
||||
{
|
||||
QSet<int> collapsedParticipantIds;
|
||||
if (!m_ui->tvParticipants->isExpanded(idx))
|
||||
{
|
||||
ParticipantManagement::ParticipantEditModel::CheckedTreeItem *item = m_model->privateData(idx);
|
||||
if (item && item->participant.id() != 0)
|
||||
collapsedParticipantIds += item->participant.id();
|
||||
}
|
||||
for (int row = 0; row < m_model->rowCount(idx); ++row)
|
||||
collapsedParticipantIds += collapsedParticipants(m_model->index(row, 0, idx));
|
||||
return collapsedParticipantIds;
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::showContextMenu(const QPoint &position)
|
||||
{
|
||||
QTreeView *tv = qobject_cast<QTreeView *>(sender());
|
||||
if (!tv)
|
||||
return;
|
||||
const QModelIndex idx = tv->currentIndex();
|
||||
if (!idx.isValid())
|
||||
return;
|
||||
if (m_model->rowCount(idx) == 0)
|
||||
return;
|
||||
|
||||
QMenu menu;
|
||||
if (tv->isExpanded(idx))
|
||||
{
|
||||
QAction *collapseAction = new QAction(tr("Collapse"), &menu);
|
||||
connect(collapseAction, &QAction::triggered, this, [tv, idx]() { tv->collapse(idx);});
|
||||
menu.addAction(collapseAction);
|
||||
}
|
||||
else
|
||||
{
|
||||
QAction *expandAction = new QAction(tr("Expand"), &menu);
|
||||
connect(expandAction, &QAction::triggered, this, [tv, idx]() { tv->expand(idx);});
|
||||
menu.addAction(expandAction);
|
||||
}
|
||||
menu.exec(tv->viewport()->mapToGlobal(position));
|
||||
}
|
||||
|
||||
void CollapseExpandParticipantWidget::onDataChanged(const std::shared_ptr<SymbolAppearanceSettings> &newFilter)
|
||||
{
|
||||
m_originalSymbolAppearance = newFilter->settings();
|
||||
m_symbolAppearanceSettings = newFilter;
|
||||
DEBUG_LOG(m_logger) << "onDataChanged ... " << QJsonDocument(newFilter->settingsToJson()).toJson();
|
||||
collapseExpand(m_ui->tvParticipants->rootIndex());
|
||||
m_model->setCheckStateForParticipants(m_originalSymbolAppearance.colExpand.hiddenParticipantIds, Qt::Unchecked);
|
||||
}
|
||||
|
||||
|
||||
} // namespace FilterManagement
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Collapse/Expand Participants
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
|
||||
class QTreeView;
|
||||
namespace AdvancedSymbology
|
||||
{
|
||||
class ForeignDataInterface;
|
||||
}
|
||||
namespace Ui
|
||||
{
|
||||
class CollapseExpandParticipantWidget;
|
||||
}
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
class ForeignGuiComboboxInterface;
|
||||
class ParticipantEditModel;
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class ForeignFltParticipantGuiInterface;
|
||||
class CollapseExpandParticipantWidget final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CollapseExpandParticipantWidget(QWidget *parent = nullptr);
|
||||
~CollapseExpandParticipantWidget();
|
||||
|
||||
void retranslate();
|
||||
bool init(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmIfc,
|
||||
const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asbIfc,
|
||||
// const std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> &fltParticipantIfc,
|
||||
const std::shared_ptr<SymbolAppearanceSettings> &filter);
|
||||
|
||||
void apply();
|
||||
void dialogCanceled();
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> filter() const { return m_symbolAppearanceSettings; }
|
||||
void onDataChanged(const std::shared_ptr<SymbolAppearanceSettings> &newFilter);
|
||||
QTreeView *treeView();
|
||||
|
||||
signals:
|
||||
void changesMade();
|
||||
void modelResetted();
|
||||
|
||||
private slots:
|
||||
void onModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
|
||||
void onPartyChanged();
|
||||
void doReinitModel(int newPartyId);
|
||||
void showContextMenu(const QPoint &position);
|
||||
|
||||
private:
|
||||
void collapseExpand(const QModelIndex &idx);
|
||||
QSet<int> collapsedParticipants(const QModelIndex &idx) const;
|
||||
private:
|
||||
ParticipantManagement::ParticipantEditModel *m_model;
|
||||
|
||||
// std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
||||
std::shared_ptr<SymbolAppearanceSettings> m_symbolAppearanceSettings;
|
||||
SymbolAppearanceSettings::Settings m_originalSymbolAppearance;
|
||||
SymbolAppearanceSettings::Settings m_currentSymbolAppearance;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> m_ppmGuiCbxIfc;
|
||||
static int s_preselectedParty;
|
||||
Ui::CollapseExpandParticipantWidget *m_ui;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CollapseExpandParticipantWidget</class>
|
||||
<widget class="QWidget" name="CollapseExpandParticipantWidget">
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QTreeView" name="tvParticipants">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::NoSelection</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbParty">
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Party:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>132</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for FilterManagement (Participant)
|
||||
* $Id: flt_participant_plugin.cpp 50305 2020-03-10 08:30:39Z ehrlicher $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/FilterManagement/Gui/Participant/flt_participant_plugin.cpp $
|
||||
* $Author: ehrlicher $
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "flt_collapse_expand_participants_dialog.h"
|
||||
#include "flt_participant_gui_plugin.h"
|
||||
#include "flt_symbol_appearance_dialog.h"
|
||||
#include "flt_type_filter_dialog.h"
|
||||
|
||||
#include <Plugins/FilterManagement/Gui/Aes/Common/symbol_appearance_settings_impl.h>
|
||||
#include <LtsProjectionWorkstation/lts_projection_workstation.h>
|
||||
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <FilterManagement/flt_operator_rights.h>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
|
||||
{
|
||||
return std::make_shared<InterfaceImpl>(session);
|
||||
}
|
||||
|
||||
|
||||
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
|
||||
: GuiPluginBase::Interface(session, getLogger("Plugins.Gui.Interface"))
|
||||
, m_logger(getLogger("ParticipantInterfaceImpl"))
|
||||
{}
|
||||
|
||||
|
||||
bool InterfaceImpl::fetchInterfaces()
|
||||
{
|
||||
if (!m_session->getDtc<FilterManagement::DataInterface>(m_fltDtc))
|
||||
return false;
|
||||
|
||||
connect(m_fltDtc.get(), &FilterManagement::Interface::Dtc::symbolAppearanceChanged,
|
||||
this, &InterfaceImpl::onSymbolAppearanceChanged, Qt::UniqueConnection);
|
||||
|
||||
// NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// filterPresetLoadUnsaved at PWS leads to race condition
|
||||
// (create dtc and update data via request)
|
||||
// enable AesFilter and SymbolAppearance already here
|
||||
|
||||
// 22.01.2025, Thoden: Nachtrag zu NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// GUEZE-3459: Hannas OPW: Hänger beim Login
|
||||
// 1. waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// gehört eingentlich VOR fltDtc->{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// 2. Da diese aber auf der PWS wohl wichtig waren, wird fetchInterfaces jeweils
|
||||
// angepasst:
|
||||
// waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters} wird
|
||||
// nicht mehr grundsätzlich, sondern nur auf der PWS ausgeführt:
|
||||
// if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
// m_fltDtc->waitForHistoricalDataXXX(1000);
|
||||
|
||||
if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
m_fltDtc->waitForHistoricalDataSymbolAppearance(1000); // wait... contains enable
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
|
||||
{
|
||||
QVector<LtsWidgets::PluginData> ret;
|
||||
LtsWidgets::PluginData plData;
|
||||
|
||||
const bool bShowSymApp =
|
||||
(m_session->partitionType() != IDL::PartitionType::Global) ||
|
||||
(m_session->app() == LtsAppDescriptor::App::ResourceManager);
|
||||
|
||||
const bool bShowTypeStateColExp =
|
||||
(m_session->partitionType() != IDL::PartitionType::Global);
|
||||
|
||||
if (bShowSymApp)
|
||||
{
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Symbol Appearance");
|
||||
plData.identifier = QLatin1String("fltParticipantFilter");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:filter_map_settings.svg")); // ToDo: passendes Icon erstellen
|
||||
plData.operatorRight = OperatorRights::FilterManagement::SymbolAppearanceEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
return LtsWidgets::initDialog(new SymbolAppearanceDialog(parent, appId() == LtsAppDescriptor::App::OC),
|
||||
m_session);
|
||||
};
|
||||
ret.append(plData);
|
||||
}
|
||||
|
||||
if (bShowTypeStateColExp)
|
||||
{
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Type/State Filter");
|
||||
plData.identifier = QLatin1String("fltTypeFilter");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:filter_player.svg")); // ToDo: passendes Icon erstellen
|
||||
plData.operatorRight = OperatorRights::FilterManagement::SymbolAppearanceEdit;
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
return LtsWidgets::initDialog(new TypeFilterDialog(parent),
|
||||
m_session);
|
||||
};
|
||||
ret.append(plData);
|
||||
|
||||
if (m_session->app() != LtsAppDescriptor::App::OC)
|
||||
{
|
||||
plData.menuGroup = menuGroup();
|
||||
plData.menuText = tr("Collapse/Expand Participants");
|
||||
plData.identifier = QLatin1String("fltColExpand");
|
||||
plData.menuIcon = QIcon(QLatin1String("icon:filter_collapse_expand.svg"));
|
||||
plData.operatorRight = OperatorRights::FilterManagement::SymbolAppearanceEdit; // FIXME!
|
||||
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
|
||||
plData.createWidgetFunc = [this](QWidget * parent)
|
||||
{
|
||||
return LtsWidgets::initDialog(new CollapseExpandParticipantDialog(parent),
|
||||
m_session);
|
||||
};
|
||||
ret.append(plData);
|
||||
}
|
||||
} // if (showTypeStateColExp)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InterfaceImpl::onSymbolAppearanceChanged(const FilterManagement::SymbolAppearance &data, DataModification mod)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
|
||||
|
||||
auto it = m_symbolAppearanceMap.find(FilterKey{data.operatorId(), data.ctx()});
|
||||
if (it != m_symbolAppearanceMap.end())
|
||||
{
|
||||
std::shared_ptr<SymbolAppearanceSettingsImpl> ret = it->second.lock();
|
||||
if (ret && mod != DataModification::eRemoved)
|
||||
ret->setSettingsFromData(data);
|
||||
else
|
||||
{
|
||||
// Maybe the scvFilterManagement (hosted at svcExerciseEventManagement)
|
||||
// is restarted. In that case the topics are removed from DDS.
|
||||
// But when the svc is starting again, the data is inserted into this
|
||||
// map again - but the callbacks are lost!! So some related dialog do
|
||||
// not work anymore... :-(
|
||||
// To avoid this, prevent 'used' SymbolAppearanceSettingsImpl from
|
||||
// being removed:
|
||||
if (!(ret && ret->hasChangedCallbacks()))
|
||||
m_symbolAppearanceMap.erase(it);
|
||||
}
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> InterfaceImpl::symbolAppearanceForOperator(int operatorId, const QString &context)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
|
||||
<< ", operatorId=" << operatorId
|
||||
<< ", context=" << context
|
||||
<< ", m_session->toString " << m_session->toString();
|
||||
std::shared_ptr<SymbolAppearanceSettingsImpl> ret;
|
||||
|
||||
auto it = m_symbolAppearanceMap.find({operatorId, context.toStdString()});
|
||||
if (it != m_symbolAppearanceMap.end())
|
||||
ret = it->second.lock();
|
||||
if (!ret)
|
||||
{
|
||||
FilterManagement::SymbolAppearance filterData;
|
||||
// it's 0 when there is not yet a filter for this operator, so set it here and use it for comparision
|
||||
filterData.operatorId(operatorId);
|
||||
filterData.ctx(context.toStdString());
|
||||
|
||||
std::function<bool(const FilterManagement::SymbolAppearance &)> func = [&filterData](const FilterManagement::SymbolAppearance &f)
|
||||
{
|
||||
if (f.operatorId() == filterData.operatorId() &&
|
||||
f.ctx() == filterData.ctx())
|
||||
{
|
||||
filterData = f;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// 22.01.2025, Thoden: Nachtrag zu NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// GUEZE-3459: Hannas OPW: Hänger beim Login
|
||||
// 1. waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// gehört eingentlich VOR fltDtc->{SymbolAppearance|AesFilter|buildingComponentFilters}
|
||||
// 2. Da diese aber auf der PWS wohl wichtig waren, wird fetchInterfaces jeweils
|
||||
// angepasst:
|
||||
// waitForHistoricalData{SymbolAppearance|AesFilter|buildingComponentFilters} wird
|
||||
// nicht mehr grundsätzlich, sondern nur auf der PWS ausgeführt:
|
||||
// if (LtsProjectionWorkstation::LtsProjectionWorkstation::hasInstance())
|
||||
// m_fltDtc->waitForHistoricalDataXXX(1000);
|
||||
|
||||
m_fltDtc->waitForHistoricalDataSymbolAppearance(1000);
|
||||
|
||||
m_fltDtc->symbolAppearances(func);
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> dtcPpm;
|
||||
m_session->getDtc<ParticipantManagement::DataInterface>(dtcPpm);
|
||||
ret = std::make_shared<SymbolAppearanceSettingsImpl>(dtcPpm, m_session->workspaceId());
|
||||
ret->setSettingsFromData(filterData);
|
||||
|
||||
m_symbolAppearanceMap[FilterKey(operatorId, context.toStdString())] = ret;
|
||||
}
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
|
||||
<< ", operatorId=" << operatorId
|
||||
<< ", context=" << context;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
} //namespace FilterManagement
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Gui Plugin for FilterManagement (Participant)
|
||||
* $Id: flt_participant_plugin.h 50296 2020-03-09 15:45:03Z ehrlicher $
|
||||
* $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/FilterManagement/Gui/Participant/flt_participant_plugin.h $
|
||||
* $Author: ehrlicher $
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <Plugins/FilterManagement/flt_data_plugin_interface.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class SymbolAppearanceSettingsImpl;
|
||||
|
||||
|
||||
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
|
||||
{
|
||||
Q_PLUGIN_METADATA(IID "gui:3:flt.participant")
|
||||
Q_INTERFACES(GuiPluginBase::Plugin)
|
||||
|
||||
Q_OBJECT
|
||||
public:
|
||||
GuiPlugin() = default;
|
||||
~GuiPlugin() = default;
|
||||
|
||||
QString pluginName() override { return QLatin1String("FilterManagementParticipantGuiPlugin"); }
|
||||
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
|
||||
bool availableInPartition(IDL::PartitionType partition) const override
|
||||
{
|
||||
return (partition == IDL::PartitionType::Global) ||
|
||||
(partition == IDL::PartitionType::Exercise) ||
|
||||
(partition == IDL::PartitionType::Replay);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ...
|
||||
class InterfaceImpl final : public QObject, public ForeignFltParticipantGuiInterface, public GuiPluginBase::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfaceImpl(LtsSession::LtsSession *session);
|
||||
|
||||
bool fetchInterfaces() override;
|
||||
QString menuGroup() const override { return tr("Situation Map"); }
|
||||
QVector<LtsWidgets::PluginData> getActions() override;
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> symbolAppearanceForOperator(int operatorId, const QString &context) override;
|
||||
|
||||
private slots:
|
||||
void onSymbolAppearanceChanged(const SymbolAppearance &data, DataModification mod);
|
||||
|
||||
private:
|
||||
// <operatorId, filter>
|
||||
struct FilterKey
|
||||
{
|
||||
int operatorId = 0;
|
||||
std::string context;
|
||||
FilterKey() = default;
|
||||
FilterKey(int _operatorId, const std::string &_context)
|
||||
: operatorId(_operatorId)
|
||||
, context(_context)
|
||||
{}
|
||||
bool operator<(const FilterKey &o) const
|
||||
{
|
||||
if (operatorId != o.operatorId)
|
||||
return operatorId < o.operatorId;
|
||||
return context < o.context;
|
||||
}
|
||||
};
|
||||
|
||||
std::map<FilterKey, std::weak_ptr<SymbolAppearanceSettingsImpl>> m_symbolAppearanceMap;
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "flt_symbol_appearance_dialog.h"
|
||||
#include "flt_symbol_appearance_widget.h"
|
||||
#include <FilterManagement/Gui/FilterChange/flt_filter_change.h>
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <PluginInterfaces/gui_plugin_interface.h>
|
||||
#include <ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
SymbolAppearanceDialog::SymbolAppearanceDialog(QWidget *parent, bool isOc)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_widget(new SymbolAppearanceWidget(this, isOc))
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_session(nullptr)
|
||||
, m_logger(getLogger("SymbolAppearanceDialog"))
|
||||
{
|
||||
QGridLayout *gl = new QGridLayout(this);
|
||||
gl->setMargin(0);
|
||||
gl->addWidget(m_widget, 0, 0);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Symbol_Appearance"));
|
||||
}
|
||||
|
||||
SymbolAppearanceDialog::~SymbolAppearanceDialog()
|
||||
{
|
||||
delete m_widget;
|
||||
}
|
||||
|
||||
bool SymbolAppearanceDialog::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " m_session = " << session->toString();
|
||||
m_session = session;
|
||||
|
||||
if (!session->getForeignGuiInterface(m_fltParticipantGuiIfc) ||
|
||||
!session->getDtc<FilterManagement::DataInterface>(m_fltDtc) ||
|
||||
!session->getFtc<FilterManagement::DataInterface>(m_fltFtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not use Filter Management";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save/Load from Library Button
|
||||
m_buttonBox->connectLibraryButton(this,
|
||||
&SymbolAppearanceDialog::onImportButtonClicked,
|
||||
&SymbolAppearanceDialog::onExportButtonClicked);
|
||||
|
||||
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
|
||||
{
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Library, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(m_fltDtc.get(), &Interface::Dtc::symbolAppearanceChanged,
|
||||
this, &SymbolAppearanceDialog::onDataChanged);
|
||||
}
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
|
||||
if (!session->getDtc<ParticipantManagement::DataInterface>(ppmDtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get data interface for ParticipantManagement";
|
||||
return false;
|
||||
}
|
||||
QMap<qint32, ParticipantManagement::Party> parties;
|
||||
if (!ppmDtc->visibleParties(parties, LtsSessionData::LtsSessionData::getInstance()->getVisibleParties(m_session->exerciseId())))
|
||||
return false;
|
||||
|
||||
auto symbolAppearanceSettings = m_fltParticipantGuiIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(),
|
||||
m_session->workspaceId());
|
||||
|
||||
if (FilterChangeDialog::isAvailableAtApp(m_session->app()))
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Load filter"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load,
|
||||
this, &SymbolAppearanceDialog::onLoadButtonClicked);
|
||||
}
|
||||
|
||||
// First init widget:
|
||||
bool success = m_widget->init(parties, symbolAppearanceSettings);
|
||||
|
||||
// then connect:
|
||||
connect(m_widget, &SymbolAppearanceWidget::changesMade,
|
||||
this, &SymbolAppearanceDialog::slotChangesMade, Qt::UniqueConnection);
|
||||
|
||||
connect(m_widget, &SymbolAppearanceWidget::unknownChangesRecognized,
|
||||
this, &SymbolAppearanceDialog::onUnknownChangesRecognized, Qt::UniqueConnection);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::retranslate()
|
||||
{
|
||||
m_widget->retranslate();
|
||||
|
||||
// lupdate doesn't like translate(tr("foo")) ...
|
||||
const QString txt(tr("Symbol Appearance"));
|
||||
translate(txt);
|
||||
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
bool SymbolAppearanceDialog::apply()
|
||||
{
|
||||
m_widget->apply();
|
||||
|
||||
const SymbolAppearance symbolAppearance = m_widget->filter()->settingsToData();
|
||||
auto cb = [symbolAppearance, this]() -> bool
|
||||
{
|
||||
return m_fltFtc->symbolAppearanceUpdateRequest(symbolAppearance, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::dialogCanceled()
|
||||
{
|
||||
m_widget->dialogCanceled();
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::onLoadButtonClicked()
|
||||
{
|
||||
FilterChangeDialog *dialog = new FilterChangeDialog(this);
|
||||
if (!dialog->init(m_session, SymbolAppearanceSettings::Part::Symbol))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QObject::connect(dialog, &FilterChangeDialog::rejected, dialog, &FilterChangeDialog::deleteLater);
|
||||
dialog->show();
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::onDataChanged(const FilterManagement::SymbolAppearance &data, DataModification modType)
|
||||
{
|
||||
if (modType != DataModification::eRemoved &&
|
||||
data.operatorId() == LtsSessionData::LtsSessionData::getInstance()->getOperatorId())
|
||||
{
|
||||
auto symbolAppearanceSettings = m_fltParticipantGuiIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(), m_session->workspaceId());
|
||||
m_widget->onDataChanged(symbolAppearanceSettings);
|
||||
|
||||
// the data can be changed if another replay is selected or filter are loaded.
|
||||
// So our widget has to be updated:
|
||||
__unchange__();
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::onExportButtonClicked()
|
||||
{
|
||||
m_widget->apply();
|
||||
const auto s = m_widget->filter();
|
||||
QJsonObject saveObject;
|
||||
saveObject[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::FLTSymbolAppearance);
|
||||
saveObject[QStringLiteral("content")] = s->settingsToJson();
|
||||
|
||||
const QJsonDocument saveDoc(saveObject);
|
||||
DEBUG_LOG(m_logger) << "Saving: " << saveDoc.toJson();
|
||||
|
||||
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), saveDoc.toJson(QJsonDocument::Compact));
|
||||
if (fileId > 0)
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::onImportButtonClicked()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " onImportButtonClicked() ";
|
||||
|
||||
QByteArray content;
|
||||
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::FLTSymbolAppearance));
|
||||
if (fileId > 0)
|
||||
{
|
||||
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::FLTSymbolAppearance)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QJsonDocument loadDoc(QJsonDocument::fromJson(content));
|
||||
DEBUG_LOG(m_logger) << "Loading: " << loadDoc.toJson();
|
||||
m_widget->filter()->setSettings(loadDoc.object().value(QStringLiteral("content")).toObject(),
|
||||
FilterManagement::SymbolAppearanceSettings::Part::Symbol);
|
||||
const SymbolAppearance symbolAppearance = m_widget->filter()->settingsToData();
|
||||
|
||||
auto cb = [symbolAppearance, this]()
|
||||
{
|
||||
return m_fltFtc->symbolAppearanceUpdateRequest(symbolAppearance, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
m_requestHelper->startRequests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolAppearanceDialog::onUnknownChangesRecognized()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " onUnknownChangesRecognized() ";
|
||||
|
||||
m_widget->updateGuiToFilter();
|
||||
|
||||
__unchange__();
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Participant Symbol Appearance Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flt_symbol_appearance_widget.h"
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SymbolAppearanceDialog;
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
// --------------------------------------------------------
|
||||
// AesFilterDialog
|
||||
// --------------------------------------------------------
|
||||
class SymbolAppearanceDialog final : public LtsWidgets::LtsDialog
|
||||
, private FilterManagement::Interface::Ftc::SymbolAppearanceUpdateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SymbolAppearanceDialog(QWidget *parent = nullptr, bool isOc = false);
|
||||
~SymbolAppearanceDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session);
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
bool apply() override;
|
||||
void dialogCanceled() override;
|
||||
void onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onLoadButtonClicked();
|
||||
void onDataChanged(const FilterManagement::SymbolAppearance &data, DataModification modType);
|
||||
void onExportButtonClicked();
|
||||
void onImportButtonClicked();
|
||||
void onUnknownChangesRecognized();
|
||||
|
||||
private:
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantGuiIfc;
|
||||
std::shared_ptr<FilterManagement::ForeignAesGuiInterface> m_fltAesIfc;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
|
||||
|
||||
SymbolAppearanceWidget *m_widget;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
LtsSession::LtsSession *m_session;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
+528
@@ -0,0 +1,528 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Aes Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
|
||||
#include "flt_symbol_appearance_widget.h"
|
||||
#include "ui_flt_symbol_appearance_widget.h"
|
||||
|
||||
#include <ParticipantManagement/ppm.hpp>
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <QTimer>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class PartyCheckBox final : public QCheckBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PartyCheckBox(int partyId, QWidget *parent = nullptr)
|
||||
: QCheckBox(parent)
|
||||
, m_partyId(partyId)
|
||||
{}
|
||||
|
||||
int partyId() const { return m_partyId; }
|
||||
|
||||
private:
|
||||
int m_partyId;
|
||||
};
|
||||
|
||||
class BoolLocker
|
||||
{
|
||||
public:
|
||||
explicit BoolLocker(bool &b)
|
||||
: m_b(b)
|
||||
{
|
||||
m_b = true;
|
||||
}
|
||||
~BoolLocker()
|
||||
{
|
||||
m_b = false;
|
||||
}
|
||||
private:
|
||||
bool &m_b;
|
||||
};
|
||||
|
||||
SymbolAppearanceWidget::SymbolAppearanceWidget(QWidget *parent, bool isOC)
|
||||
: QWidget(parent)
|
||||
, m_bIgnoreUiSignals(false)
|
||||
, m_ui(new Ui::SymbolAppearanceWidget)
|
||||
, m_updateTimer(new QTimer(this))
|
||||
, m_doUpdateViaCallback(true)
|
||||
, m_logger(getLogger("SymbolAppearanceWidget"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
initUiElements();
|
||||
|
||||
m_updateTimer->setSingleShot(true);
|
||||
m_updateTimer->setInterval(500);
|
||||
connect(m_updateTimer, &QTimer::timeout,
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
|
||||
// GUEZE-1474: Name nur, wenn Umriss:
|
||||
// the slots are executed in order of creation!?
|
||||
connect(m_ui->cbShowBuildingOutline, &QCheckBox::clicked, this, [this] {
|
||||
if (m_ui->cbShowBuildingOutline->isChecked())
|
||||
{
|
||||
m_ui->cbShowBuildingIdentifier->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->cbShowBuildingIdentifier->setEnabled(false);
|
||||
m_ui->cbShowBuildingIdentifier->setChecked(false);
|
||||
}
|
||||
});
|
||||
|
||||
connect(m_ui->slSymbolScale, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onSymbolScaleChanged);
|
||||
connect(m_ui->slSymbolTransparency, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onSymbolTransparencyChanged);
|
||||
connect(m_ui->slSymbolFireEvenFlashing, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onSymbolFireEventFlashingChanged);
|
||||
connect(m_ui->slHitLineDisplayLength, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onHitLineDisplayLengthChanged);
|
||||
connect(m_ui->slLRFDisplayLength, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onLRFDisplayLengthChanged);
|
||||
connect(m_ui->slLTDDisplayLength, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onLTDDisplayLengthChanged);
|
||||
connect(m_ui->slMovementTrackLength, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onMovementTrackLengthChanged);
|
||||
connect(m_ui->cbShowBuildingOutline, &QCheckBox::stateChanged,
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
connect(m_ui->cbShowBuildingIdentifier, &QCheckBox::stateChanged,
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
connect(m_ui->cbShowTrainingAreaBorder, &QCheckBox::stateChanged,
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
connect(m_ui->cbShowSpecialAreas, &QCheckBox::stateChanged,
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
connect(m_ui->cbShowFiringUnits, &QCheckBox::stateChanged,
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
connect(m_ui->slNasatNineLinerDisplayLength, &QSlider::valueChanged,
|
||||
this, &SymbolAppearanceWidget::onNasatNineLinerDisplayLengthChanged);
|
||||
|
||||
for (QComboBox *cbx : {m_ui->cbBitError, m_ui->cbManipulation, m_ui->cbInvalidPosition, m_ui->cbSimulatedPosition, m_ui->cbUnitSymbols})
|
||||
connect(cbx, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
|
||||
// after connect so the slots for setting the labels are executed
|
||||
m_ui->slSymbolScale->setValue(m_ui->slSymbolScale->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbSymbolScaleVal);
|
||||
m_ui->slSymbolTransparency->setValue(m_ui->slSymbolTransparency->minimum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbSymbolTransparencyVal);
|
||||
m_ui->slSymbolFireEvenFlashing->setValue(m_ui->slSymbolFireEvenFlashing->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbSymbolFireEventFlashingVal);
|
||||
|
||||
m_ui->slHitLineDisplayLength->setValue(m_ui->slHitLineDisplayLength->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbHitLineDisplayLengthVal);
|
||||
|
||||
m_ui->slLRFDisplayLength->setValue(m_ui->slLRFDisplayLength->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbLRFDisplayLengthVal);
|
||||
m_ui->slLTDDisplayLength->setValue(m_ui->slLTDDisplayLength->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbLTDDisplayLengthVal);
|
||||
|
||||
m_ui->slMovementTrackLength->setValue(m_ui->slMovementTrackLength->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbMovementTrackLengthVal);
|
||||
m_ui->slNasatNineLinerDisplayLength->setValue(m_ui->slNasatNineLinerDisplayLength->maximum());
|
||||
LtsWidgets::LtsDialog::setMinWidthForWidgetHelper(m_ui->lbNasatNineLinerDisplayLengthVal);
|
||||
|
||||
// show / hide TrainingAreaBorder
|
||||
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
||||
const bool enableTrainingAreaBorder =
|
||||
ps->value(QStringLiteral("SituationMap"), QStringLiteral("enableTrainingAreaBorder"), false).toBool();
|
||||
m_ui->lblShowTrainingAreaBorder->setVisible(enableTrainingAreaBorder);
|
||||
m_ui->cbShowTrainingAreaBorder->setVisible(enableTrainingAreaBorder);
|
||||
|
||||
// const bool enableBuildingComponentFilterEdit = ps->value(QStringLiteral("flt"),
|
||||
// QStringLiteral("enableBuildingComponentFilterEdit"), false).toBool();
|
||||
// m_ui->lblShowBuildingIdentifier->setVisible(!enableBuildingComponentFilterEdit);
|
||||
// m_ui->cbShowBuildingIdentifier->setVisible(!enableBuildingComponentFilterEdit);
|
||||
|
||||
// show / hide Guez NASAT
|
||||
const bool enableGuezNasat = ps->value(QStringLiteral("gna"),
|
||||
QStringLiteral("enableGuezNasat")).toBool();
|
||||
m_ui->lblShowNasatNineLiner->setVisible(enableGuezNasat);
|
||||
m_ui->slNasatNineLinerDisplayLength->setVisible(enableGuezNasat);
|
||||
m_ui->lbNasatNineLinerDisplayLengthVal->setVisible(enableGuezNasat);
|
||||
|
||||
//Additionally hide specific things in OC:
|
||||
if (isOC)
|
||||
{
|
||||
// no training area border
|
||||
m_ui->lblShowTrainingAreaBorder->setVisible(false);
|
||||
m_ui->cbShowTrainingAreaBorder->setVisible(false);
|
||||
// no nasat
|
||||
m_ui->lblShowNasatNineLiner->setVisible(false);
|
||||
m_ui->slNasatNineLinerDisplayLength->setVisible(false);
|
||||
m_ui->lbNasatNineLinerDisplayLengthVal->setVisible(false);
|
||||
// no hitline
|
||||
m_ui->lblHitlineDisplay->setVisible(false);
|
||||
m_ui->slHitLineDisplayLength->setVisible(false);
|
||||
m_ui->lbHitLineDisplayLengthVal->setVisible(false);
|
||||
m_ui->lblLRFDisplay->setVisible(false);
|
||||
m_ui->slLRFDisplayLength->setVisible(false);
|
||||
m_ui->lblLTDDisplay->setVisible(false);
|
||||
m_ui->slLTDDisplayLength->setVisible(false);
|
||||
//no blink
|
||||
m_ui->lblSymbolFireEventFlashing->setVisible(false);
|
||||
m_ui->slSymbolFireEvenFlashing->setVisible(false);
|
||||
m_ui->lbSymbolFireEventFlashingVal->setVisible(false);
|
||||
|
||||
//no bit error
|
||||
m_ui->lblBitError->setVisible(false);
|
||||
m_ui->cbBitError->setVisible(false);
|
||||
//no sim pos
|
||||
m_ui->lblSimPos->setVisible(false);
|
||||
m_ui->cbSimulatedPosition->setVisible(false);
|
||||
//no manipulation
|
||||
m_ui->lblManipulation->setVisible(false);
|
||||
m_ui->cbManipulation->setVisible(false);
|
||||
//no manipulation
|
||||
m_ui->lblInvalidPos->setVisible(false);
|
||||
m_ui->cbInvalidPosition->setVisible(false);
|
||||
//in Guez we don't use unit symbols right now
|
||||
if (strcmp(PROJECTBUILD, "guez") == 0)
|
||||
{
|
||||
m_ui->lblUnitSymbols->setVisible(false);
|
||||
m_ui->cbUnitSymbols->setVisible(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SymbolAppearanceWidget::~SymbolAppearanceWidget()
|
||||
{
|
||||
if (m_symbolAppearanceSettings)
|
||||
m_symbolAppearanceSettings->removeChangedCallback(this);
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
bool SymbolAppearanceWidget::init(const QMap<int, ParticipantManagement::Party> &parties,
|
||||
const std::shared_ptr<SymbolAppearanceSettings> &filter)
|
||||
{
|
||||
m_symbolAppearanceSettings = filter;
|
||||
m_originalSymbolAppearance = m_symbolAppearanceSettings->settings();
|
||||
|
||||
buildPartyTable(parties);
|
||||
|
||||
setSymbolAppearanceSettings();
|
||||
|
||||
m_symbolAppearanceSettings->addChangedCallback(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::retranslate()
|
||||
{
|
||||
BoolLocker l(m_bIgnoreUiSignals);
|
||||
m_ui->retranslateUi(this);
|
||||
initUiElements();
|
||||
onSymbolScaleChanged();
|
||||
onSymbolTransparencyChanged();
|
||||
onSymbolFireEventFlashingChanged();
|
||||
onHitLineDisplayLengthChanged();
|
||||
onLRFDisplayLengthChanged();
|
||||
onLTDDisplayLengthChanged();
|
||||
onMovementTrackLengthChanged();
|
||||
onNasatNineLinerDisplayLengthChanged();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void setComboBoxData(QComboBox *cbx, T val)
|
||||
{
|
||||
const int idxForVal = cbx->findData(static_cast<int>(val));
|
||||
cbx->setCurrentIndex(idxForVal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void readComboBoxData(QComboBox *cbx, T &val)
|
||||
{
|
||||
const QVariant v = cbx->currentData();
|
||||
if (v.isValid())
|
||||
val = static_cast<T>(v.toInt());
|
||||
else
|
||||
val = T();
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::setSymbolAppearanceSettings()
|
||||
{
|
||||
BoolLocker l(m_bIgnoreUiSignals);
|
||||
|
||||
const SymbolAppearanceSettings::Settings settings = m_symbolAppearanceSettings->settings();
|
||||
const auto &s = settings.symbolSettings;
|
||||
m_ui->slSymbolScale->setValue(qRound(s.symbolScale * 100)); // percent
|
||||
m_ui->slSymbolTransparency->setValue(qRound(s.symbolTransparency * 100)); // percent
|
||||
m_ui->slSymbolFireEvenFlashing->setValue(s.symbolFireEventFlashingMSec / 1000); // sec
|
||||
m_ui->slHitLineDisplayLength->setValue(s.hitLineDisplayLengthMSec / 1000); // sec
|
||||
m_ui->slLRFDisplayLength->setValue(s.lrfLineDisplayLengthMSec / 1000); // sec
|
||||
m_ui->slLTDDisplayLength->setValue(s.ltdLineDisplayLengthMSec / 1000); // sec
|
||||
m_ui->slMovementTrackLength->setValue(s.movementTrackLengthMSec / (60 * 1000)); // min
|
||||
m_ui->cbShowBuildingOutline->setChecked(s.showBuildingOutline);
|
||||
m_ui->cbShowBuildingIdentifier->setChecked(s.showBuildingIdentifier);
|
||||
m_ui->cbShowTrainingAreaBorder->setChecked(s.showTrainingAreaBorder);
|
||||
m_ui->cbShowSpecialAreas->setChecked(s.showSpecialAreas);
|
||||
m_ui->cbShowFiringUnits->setChecked(s.showFiringUnits);
|
||||
m_ui->slNasatNineLinerDisplayLength->setValue(s.nasatNineLinerDisplayLengthMSec / 1000);
|
||||
|
||||
setComboBoxData(m_ui->cbBitError, s.bitErrorVisibility);
|
||||
setComboBoxData(m_ui->cbManipulation, s.manipulationVisibility);
|
||||
setComboBoxData(m_ui->cbInvalidPosition, s.positionOutOfDateVisibility);
|
||||
setComboBoxData(m_ui->cbSimulatedPosition, s.simulatedPositionVisibility);
|
||||
setComboBoxData(m_ui->cbUnitSymbols, s.unitSymbolPosition);
|
||||
|
||||
for (PartyCheckBox *cb : qAsConst(m_visibleCont))
|
||||
cb->setChecked(s.symbolPartyAppearance[cb->partyId()].isVisible);
|
||||
for (PartyCheckBox *cb : qAsConst(m_designatorCont))
|
||||
cb->setChecked(s.symbolPartyAppearance[cb->partyId()].showDesignator);
|
||||
for (PartyCheckBox *cb : qAsConst(m_tactIdentCont))
|
||||
cb->setChecked(s.symbolPartyAppearance[cb->partyId()].showTacticalIdentifier);
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onSymbolScaleChanged()
|
||||
{
|
||||
m_ui->lbSymbolScaleVal->setText(tr("%1 %").arg(m_ui->slSymbolScale->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onSymbolTransparencyChanged()
|
||||
{
|
||||
m_ui->lbSymbolTransparencyVal->setText(tr("%1 %").arg(m_ui->slSymbolTransparency->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onSymbolFireEventFlashingChanged()
|
||||
{
|
||||
m_ui->lbSymbolFireEventFlashingVal->setText(tr("%1 sec").arg(m_ui->slSymbolFireEvenFlashing->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onHitLineDisplayLengthChanged()
|
||||
{
|
||||
m_ui->lbHitLineDisplayLengthVal->setText(tr("%1 sec").arg(m_ui->slHitLineDisplayLength->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onLRFDisplayLengthChanged()
|
||||
{
|
||||
m_ui->lbLRFDisplayLengthVal->setText(tr("%1 sec").arg(m_ui->slLRFDisplayLength->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onLTDDisplayLengthChanged()
|
||||
{
|
||||
m_ui->lbLTDDisplayLengthVal->setText(tr("%1 sec").arg(m_ui->slLTDDisplayLength->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onMovementTrackLengthChanged()
|
||||
{
|
||||
m_ui->lbMovementTrackLengthVal->setText(tr("%1 min").arg(m_ui->slMovementTrackLength->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onNasatNineLinerDisplayLengthChanged()
|
||||
{
|
||||
m_ui->lbNasatNineLinerDisplayLengthVal->setText(tr("%1 sec").arg(m_ui->slNasatNineLinerDisplayLength->value()));
|
||||
m_updateTimer->start(); // restart
|
||||
}
|
||||
|
||||
SymbolAppearanceSettings::Settings SymbolAppearanceWidget::getCurrentUiSettings() const
|
||||
{
|
||||
SymbolAppearanceSettings::Settings settings = m_symbolAppearanceSettings->settings();
|
||||
auto &s = settings.symbolSettings;
|
||||
s.symbolScale = m_ui->slSymbolScale->value() / 100.; // percent -> float
|
||||
s.symbolTransparency = m_ui->slSymbolTransparency->value() / 100.; // percent -> float
|
||||
s.symbolFireEventFlashingMSec = m_ui->slSymbolFireEvenFlashing->value() * 1000; // ms
|
||||
s.hitLineDisplayLengthMSec = m_ui->slHitLineDisplayLength->value() * 1000; // ms
|
||||
s.lrfLineDisplayLengthMSec = m_ui->slLRFDisplayLength->value() * 1000; // ms
|
||||
s.ltdLineDisplayLengthMSec = m_ui->slLTDDisplayLength->value() * 1000; // ms
|
||||
s.movementTrackLengthMSec = m_ui->slMovementTrackLength->value() * 60 * 1000; // ms
|
||||
s.showBuildingOutline = m_ui->cbShowBuildingOutline->isChecked();
|
||||
s.showBuildingIdentifier = m_ui->cbShowBuildingIdentifier->isChecked();
|
||||
s.showTrainingAreaBorder = m_ui->cbShowTrainingAreaBorder->isChecked();
|
||||
s.showSpecialAreas = m_ui->cbShowSpecialAreas->isChecked();
|
||||
s.showFiringUnits = m_ui->cbShowFiringUnits->isChecked();
|
||||
s.nasatNineLinerDisplayLengthMSec = m_ui->slNasatNineLinerDisplayLength->value() * 1000; // ms
|
||||
|
||||
readComboBoxData(m_ui->cbBitError, s.bitErrorVisibility);
|
||||
readComboBoxData(m_ui->cbManipulation, s.manipulationVisibility);
|
||||
readComboBoxData(m_ui->cbInvalidPosition, s.positionOutOfDateVisibility);
|
||||
readComboBoxData(m_ui->cbSimulatedPosition, s.simulatedPositionVisibility);
|
||||
readComboBoxData(m_ui->cbUnitSymbols, s.unitSymbolPosition);
|
||||
|
||||
for (PartyCheckBox *cb : qAsConst(m_visibleCont))
|
||||
s.symbolPartyAppearance[cb->partyId()].isVisible = cb->isChecked();
|
||||
for (PartyCheckBox *cb : qAsConst(m_designatorCont))
|
||||
s.symbolPartyAppearance[cb->partyId()].showDesignator = cb->isChecked();
|
||||
for (PartyCheckBox *cb : qAsConst(m_tactIdentCont))
|
||||
s.symbolPartyAppearance[cb->partyId()].showTacticalIdentifier = cb->isChecked();
|
||||
return settings;
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onSymbolAppearanceSettingsChanged(SymbolAppearanceSettings::Part part)
|
||||
{
|
||||
Q_UNUSED(part);
|
||||
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, m_doUpdateViaCallback=" << m_doUpdateViaCallback;
|
||||
if (m_doUpdateViaCallback)
|
||||
{
|
||||
updateGuiToFilter();
|
||||
emit unknownChangesRecognized();
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, m_doUpdateViaCallback=" << m_doUpdateViaCallback;
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::updateGuiToFilter()
|
||||
{
|
||||
this->onDataChanged(m_symbolAppearanceSettings);
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::readUpdateFilterFromUi()
|
||||
{
|
||||
if (!m_symbolAppearanceSettings || m_bIgnoreUiSignals)
|
||||
return;
|
||||
|
||||
m_doUpdateViaCallback = false;
|
||||
const SymbolAppearanceSettings::Settings &settings = getCurrentUiSettings();
|
||||
m_symbolAppearanceSettings->setSettings(settings, FilterManagement::SymbolAppearanceSettings::Part::Symbol);
|
||||
m_doUpdateViaCallback = true;
|
||||
}
|
||||
|
||||
static void addSpacerItem(QGridLayout *gridLayout, int row, int col)
|
||||
{
|
||||
gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding), row, col, 1, 1, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::buildPartyTable(const QMap<int, ParticipantManagement::Party> &parties)
|
||||
{
|
||||
m_visibleCont.clear();
|
||||
m_designatorCont.clear();
|
||||
m_tactIdentCont.clear();
|
||||
QGridLayout *glParty = m_ui->glParty;
|
||||
// first row is header
|
||||
// remove all other rows (for reinit)
|
||||
for (int row = glParty->rowCount() - 1; row > 0; --row)
|
||||
{
|
||||
for (int col = 0; col < glParty->columnCount(); ++col)
|
||||
{
|
||||
QLayoutItem *item = glParty->itemAtPosition(row, col);
|
||||
if (!item)
|
||||
continue;
|
||||
delete item->widget();
|
||||
}
|
||||
}
|
||||
const SymbolAppearanceSettings::Settings settings = m_symbolAppearanceSettings->settings();
|
||||
const auto &s = settings.symbolSettings;
|
||||
// <name> <spc> <cbDesignator> <spc> <spc> <cbTactIdent> <spc> <spc> <cbSimu> <spc>
|
||||
int row = 1;
|
||||
for (const ParticipantManagement::Party &party : parties)
|
||||
{
|
||||
const int partyId = party.id();
|
||||
QLabel *lblParty = new QLabel(ParticipantManagement::trPartyName(party.name()), this);
|
||||
int col = 0;
|
||||
glParty->addWidget(lblParty, row, col++, 1, 1, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
// <spc>
|
||||
addSpacerItem(glParty, row, col++);
|
||||
// <cbVisible>
|
||||
{
|
||||
PartyCheckBox *cbVisible = new PartyCheckBox(partyId, this);
|
||||
cbVisible->setChecked(s.symbolPartyAppearance[partyId].showDesignator);
|
||||
connect(cbVisible, &PartyCheckBox::stateChanged, this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
glParty->addWidget(cbVisible, row, col++, 1, 1, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
m_visibleCont += cbVisible;
|
||||
}
|
||||
// <spc>
|
||||
addSpacerItem(glParty, row, col++);
|
||||
// <spc>
|
||||
addSpacerItem(glParty, row, col++);
|
||||
// <cbDesignator>
|
||||
{
|
||||
PartyCheckBox *cbDesignator = new PartyCheckBox(partyId, this);
|
||||
cbDesignator->setChecked(s.symbolPartyAppearance[partyId].showDesignator);
|
||||
connect(cbDesignator, &PartyCheckBox::stateChanged, this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
glParty->addWidget(cbDesignator, row, col++, 1, 1, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
m_designatorCont += cbDesignator;
|
||||
}
|
||||
// <spc>
|
||||
addSpacerItem(glParty, row, col++);
|
||||
// <spc>
|
||||
addSpacerItem(glParty, row, col++);
|
||||
// <cbTactIdent>
|
||||
{
|
||||
PartyCheckBox *cbTactIdent = new PartyCheckBox(partyId, this);
|
||||
cbTactIdent->setChecked(s.symbolPartyAppearance[partyId].showTacticalIdentifier);
|
||||
connect(cbTactIdent, &PartyCheckBox::stateChanged, this, &SymbolAppearanceWidget::readUpdateFilterFromUi);
|
||||
glParty->addWidget(cbTactIdent, row, col++, 1, 1, Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
m_tactIdentCont += cbTactIdent;
|
||||
}
|
||||
// <spc>
|
||||
addSpacerItem(glParty, row, col++);
|
||||
|
||||
++row;
|
||||
}
|
||||
|
||||
for (auto cb : qAsConst(m_visibleCont))
|
||||
connect(cb, &QCheckBox::stateChanged, this, &SymbolAppearanceWidget::changesMade);
|
||||
for (auto cb : qAsConst(m_designatorCont))
|
||||
connect(cb, &QCheckBox::stateChanged, this, &SymbolAppearanceWidget::changesMade);
|
||||
for (auto cb : qAsConst(m_tactIdentCont))
|
||||
connect(cb, &QCheckBox::stateChanged, this, &SymbolAppearanceWidget::changesMade);
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::fillCbSymbolVisibility(QComboBox *cbx, int defaultValue)
|
||||
{
|
||||
const int idx = cbx->currentIndex();
|
||||
cbx->clear();
|
||||
cbx->addItem(tr("No change"), static_cast<int>(SymbolAppearanceSettings::SymbolVisibility::Standard));
|
||||
cbx->addItem(tr("Fade"), static_cast<int>(SymbolAppearanceSettings::SymbolVisibility::Faded));
|
||||
cbx->addItem(tr("Hide"), static_cast<int>(SymbolAppearanceSettings::SymbolVisibility::Hidden));
|
||||
cbx->addItem(tr("Additional Symbol"), static_cast<int>(SymbolAppearanceSettings::SymbolVisibility::AdditionalSymbol));
|
||||
cbx->setCurrentIndex(idx < 0 ? defaultValue : idx);
|
||||
}
|
||||
|
||||
|
||||
void SymbolAppearanceWidget::apply()
|
||||
{
|
||||
readUpdateFilterFromUi();
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::dialogCanceled()
|
||||
{
|
||||
m_symbolAppearanceSettings->setSettings(m_originalSymbolAppearance, FilterManagement::SymbolAppearanceSettings::Part::Symbol);
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::initUiElements()
|
||||
{
|
||||
fillCbSymbolVisibility(m_ui->cbBitError);
|
||||
fillCbSymbolVisibility(m_ui->cbManipulation);
|
||||
fillCbSymbolVisibility(m_ui->cbSimulatedPosition, static_cast<int>(SymbolAppearanceSettings::SymbolVisibility::AdditionalSymbol));
|
||||
fillCbSymbolVisibility(m_ui->cbInvalidPosition);
|
||||
|
||||
const int idx = m_ui->cbUnitSymbols->currentIndex();
|
||||
m_ui->cbUnitSymbols->clear();
|
||||
m_ui->cbUnitSymbols->addItem(tr("Center"), static_cast<int>(SymbolAppearanceSettings::UnitSymbolPosition::Center));
|
||||
m_ui->cbUnitSymbols->addItem(tr("Leader"), static_cast<int>(SymbolAppearanceSettings::UnitSymbolPosition::Leader));
|
||||
m_ui->cbUnitSymbols->setCurrentIndex(idx < 0 ? 0 : idx);
|
||||
}
|
||||
|
||||
void SymbolAppearanceWidget::onDataChanged(const std::shared_ptr<SymbolAppearanceSettings> &newFilter)
|
||||
{
|
||||
m_originalSymbolAppearance = newFilter->settings();
|
||||
m_symbolAppearanceSettings = newFilter;
|
||||
DEBUG_LOG(m_logger) << "onDataChanged ... " << QJsonDocument(newFilter->settingsToJson()).toJson();
|
||||
setSymbolAppearanceSettings();
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
|
||||
#include "flt_symbol_appearance_widget.moc"
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Participant Symbol Appearance Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <FilterManagement/flt_aes_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVector>
|
||||
|
||||
class QComboBox;
|
||||
class QTimer;
|
||||
|
||||
namespace ParticipantManagement
|
||||
{
|
||||
class Party;
|
||||
}
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class SymbolAppearanceWidget;
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class PartyCheckBox;
|
||||
class DataInterface;
|
||||
// --------------------------------------------------------
|
||||
// AesFilterDialog
|
||||
// --------------------------------------------------------
|
||||
class SymbolAppearanceWidget final : public QWidget, public SymbolAppearanceSettings::SettingsChangedCallback
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SymbolAppearanceWidget(QWidget *parent = nullptr, bool isOC = false);
|
||||
~SymbolAppearanceWidget();
|
||||
|
||||
void retranslate();
|
||||
bool init(const QMap<int, ParticipantManagement::Party> &parties,
|
||||
const std::shared_ptr<SymbolAppearanceSettings> &filter);
|
||||
|
||||
void apply();
|
||||
void dialogCanceled();
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> filter() const { return m_symbolAppearanceSettings; }
|
||||
void onDataChanged(const std::shared_ptr<SymbolAppearanceSettings> &newFilter);
|
||||
|
||||
SymbolAppearanceSettings::Settings getCurrentUiSettings() const;
|
||||
|
||||
void onSymbolAppearanceSettingsChanged(SymbolAppearanceSettings::Part part);
|
||||
void updateGuiToFilter();
|
||||
|
||||
signals:
|
||||
void changesMade();
|
||||
void unknownChangesRecognized();
|
||||
|
||||
private slots:
|
||||
void onSymbolScaleChanged();
|
||||
void onSymbolTransparencyChanged();
|
||||
void onSymbolFireEventFlashingChanged();
|
||||
void onHitLineDisplayLengthChanged();
|
||||
void onLRFDisplayLengthChanged();
|
||||
void onLTDDisplayLengthChanged();
|
||||
void onMovementTrackLengthChanged();
|
||||
void onNasatNineLinerDisplayLengthChanged();
|
||||
void readUpdateFilterFromUi();
|
||||
|
||||
private:
|
||||
void setSymbolAppearanceSettings();
|
||||
void buildPartyTable(const QMap<int, ParticipantManagement::Party> &parties);
|
||||
static void fillCbSymbolVisibility(QComboBox *cbx, int defaultValue = 0);
|
||||
|
||||
void initUiElements();
|
||||
|
||||
private:
|
||||
std::shared_ptr<SymbolAppearanceSettings> m_symbolAppearanceSettings;
|
||||
SymbolAppearanceSettings::Settings m_originalSymbolAppearance;
|
||||
QVector<PartyCheckBox *> m_visibleCont;
|
||||
QVector<PartyCheckBox *> m_designatorCont;
|
||||
QVector<PartyCheckBox *> m_tactIdentCont;
|
||||
bool m_bIgnoreUiSignals;
|
||||
|
||||
Ui::SymbolAppearanceWidget *m_ui;
|
||||
QTimer *m_updateTimer;
|
||||
bool m_doUpdateViaCallback;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
+675
@@ -0,0 +1,675 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SymbolAppearanceWidget</class>
|
||||
<widget class="QWidget" name="SymbolAppearanceWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1024</width>
|
||||
<height>326</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Symbol Apperance</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1">
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="3">
|
||||
<widget class="QLabel" name="lbSymbolTransparencyVal">
|
||||
<property name="text">
|
||||
<string notr="true">%1 %</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QCheckBox" name="cbShowBuildingOutline">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="lbSymbolScaleVal">
|
||||
<property name="text">
|
||||
<string notr="true">%1 %</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<widget class="QLabel" name="lblShowSpecialAreas">
|
||||
<property name="text">
|
||||
<string>Special Areas:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QSlider" name="slSymbolTransparency">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>90</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLabel" name="lbLTDDisplayLengthVal">
|
||||
<property name="text">
|
||||
<string>%1 sec</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblHitlineDisplay">
|
||||
<property name="text">
|
||||
<string>Hit Line Display Length:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QSlider" name="slHitLineDisplayLength">
|
||||
<property name="maximum">
|
||||
<number>120</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QSlider" name="slLRFDisplayLength">
|
||||
<property name="maximum">
|
||||
<number>120</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Symbol Scale:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QCheckBox" name="cbShowSpecialAreas">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLabel" name="lbLRFDisplayLengthVal">
|
||||
<property name="text">
|
||||
<string>%1 sec</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblLRFDisplay">
|
||||
<property name="text">
|
||||
<string>LRF Display Length:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QLabel" name="lbNasatNineLinerDisplayLengthVal">
|
||||
<property name="text">
|
||||
<string>%1 sec</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="lblSymbolFireEventFlashing">
|
||||
<property name="text">
|
||||
<string>Symbol Flashing:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="lblShowNasatNineLiner">
|
||||
<property name="text">
|
||||
<string>NASAT Nine-Liner:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QLabel" name="lbSymbolFireEventFlashingVal">
|
||||
<property name="text">
|
||||
<string>%1 sec</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="lblShowTrainingAreaBorder">
|
||||
<property name="text">
|
||||
<string>Training Area Border:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QCheckBox" name="cbShowBuildingIdentifier">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="lblMovementTrack">
|
||||
<property name="text">
|
||||
<string>Movement Track Length:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSlider" name="slSymbolFireEvenFlashing">
|
||||
<property name="maximum">
|
||||
<number>120</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="lblShowBuildingOutline">
|
||||
<property name="text">
|
||||
<string>Building Outline:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QSlider" name="slLTDDisplayLength">
|
||||
<property name="maximum">
|
||||
<number>120</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QCheckBox" name="cbShowTrainingAreaBorder">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QSlider" name="slSymbolScale">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>10</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>400</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QSlider" name="slNasatNineLinerDisplayLength">
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QSlider" name="slMovementTrackLength">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="lblLTDDisplay">
|
||||
<property name="text">
|
||||
<string>LTD Display Length:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Symbol Transparency:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QLabel" name="lbMovementTrackLengthVal">
|
||||
<property name="text">
|
||||
<string notr="true">%1 min</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="lblShowBuildingIdentifier">
|
||||
<property name="text">
|
||||
<string>Building Name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QLabel" name="lbHitLineDisplayLengthVal">
|
||||
<property name="text">
|
||||
<string>%1 sec</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="lblShowSpecialAreas_2">
|
||||
<property name="text">
|
||||
<string>Firing Units:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<widget class="QCheckBox" name="cbShowFiringUnits">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lblBitError">
|
||||
<property name="text">
|
||||
<string>BIT-Error:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbBitError"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lblManipulation">
|
||||
<property name="text">
|
||||
<string>Manipulation:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbManipulation"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lblInvalidPos">
|
||||
<property name="text">
|
||||
<string>Invalid Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbInvalidPosition"/>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="lblUnitSymbols">
|
||||
<property name="text">
|
||||
<string>Unit Symbols:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbUnitSymbols"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lblSimPos">
|
||||
<property name="text">
|
||||
<string>Simulated Position:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbSimulatedPosition"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>2</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="glParty">
|
||||
<item row="1" column="1">
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="4" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Designator</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="6">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="7" colspan="3">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Tact. Identifier</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string notr="true">Party 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="9">
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QCheckBox" name="cbDesignator">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="8">
|
||||
<widget class="QCheckBox" name="cbTactIdentifier">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="cbDesignator_2">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="7">
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>14</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Visible</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="Line" name="line_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>cbDesignator_2</tabstop>
|
||||
<tabstop>cbDesignator</tabstop>
|
||||
<tabstop>cbTactIdentifier</tabstop>
|
||||
<tabstop>slSymbolScale</tabstop>
|
||||
<tabstop>slSymbolTransparency</tabstop>
|
||||
<tabstop>slSymbolFireEvenFlashing</tabstop>
|
||||
<tabstop>slHitLineDisplayLength</tabstop>
|
||||
<tabstop>cbBitError</tabstop>
|
||||
<tabstop>cbManipulation</tabstop>
|
||||
<tabstop>cbInvalidPosition</tabstop>
|
||||
<tabstop>cbSimulatedPosition</tabstop>
|
||||
<tabstop>cbUnitSymbols</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,216 @@
|
||||
|
||||
#include "flt_type_filter_dialog.h"
|
||||
#include <FilterManagement/Gui/FilterChange/flt_filter_change.h>
|
||||
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsSession/lts_session_manager.h>
|
||||
#include <FileManagement/flm_translation.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QJsonDocument>
|
||||
#include <QCheckBox>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
TypeFilterDialog::TypeFilterDialog(QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::OkApplyCancel)
|
||||
, m_session(nullptr)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_widget(new TypeFilterWidget(this))
|
||||
, m_logger(getLogger("TypeFilterDialog"))
|
||||
{
|
||||
QGridLayout *gl = new QGridLayout(this);
|
||||
gl->setMargin(0);
|
||||
gl->addWidget(m_widget, 0, 0);
|
||||
|
||||
connect(m_widget, &TypeFilterWidget::partyChanged, this, &TypeFilterDialog::__unchange__);
|
||||
connect(m_widget, &TypeFilterWidget::typeFilterChanged, this, &TypeFilterDialog::onTypeFilterClicked);
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Type-State_Filter"));
|
||||
}
|
||||
|
||||
TypeFilterDialog::~TypeFilterDialog()
|
||||
{}
|
||||
|
||||
void TypeFilterDialog::retranslate()
|
||||
{
|
||||
// lupdate doesn't like translate(tr("foo")) ...
|
||||
const QString txt(tr("Type/State Filter"));
|
||||
translate(txt);
|
||||
|
||||
m_widget->retranslate();
|
||||
m_uiRequirements->retranslate();
|
||||
}
|
||||
|
||||
bool TypeFilterDialog::init(LtsSession::LtsSession *session)
|
||||
{
|
||||
m_session = session;
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
|
||||
std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> ppmGuiCbxIfc;
|
||||
|
||||
if (!session->getForeignGuiInterface<ParticipantManagement::ForeignGuiComboboxInterface>(ppmGuiCbxIfc) ||
|
||||
!session->getForeignGuiInterface(m_fltParticipantIfc) ||
|
||||
!session->getDtc<FilterManagement::DataInterface>(m_fltDtc) ||
|
||||
!session->getFtc<FilterManagement::DataInterface>(m_fltFtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not use Filter Management";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!session->getDtc<ParticipantManagement::DataInterface>(ppmDtc))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Can not get data interface for Participant Management";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save/Load from Library Button
|
||||
m_buttonBox->connectLibraryButton(this,
|
||||
&TypeFilterDialog::onImportButtonClicked,
|
||||
&TypeFilterDialog::onExportButtonClicked);
|
||||
|
||||
if (!m_session->getForeignGuiInterface<FileManagement::ForeignGuiInterface>(m_flmGui))
|
||||
{
|
||||
m_buttonBox->setButtonEnabled(LtsWidgets::DialogButton::Library, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
connect(m_fltDtc.get(), &Interface::Dtc::symbolAppearanceChanged,
|
||||
this, &TypeFilterDialog::onDataChanged);
|
||||
}
|
||||
|
||||
if (FilterChangeDialog::isAvailableAtApp(m_session->app()))
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Load)->setText(tr("Load filter"));
|
||||
m_buttonBox->connectButton(LtsWidgets::DialogButton::Load,
|
||||
this, &TypeFilterDialog::onLoadButtonClicked);
|
||||
}
|
||||
|
||||
auto symbolAppearanceSettings = m_fltParticipantIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(),
|
||||
m_session->workspaceId());
|
||||
#ifdef GUEZ_MODE
|
||||
bool success = m_widget->init(ppmDtc, ppmGuiCbxIfc, symbolAppearanceSettings,
|
||||
(m_session->app() == LtsAppDescriptor::App::OC) || (LtsSessionData::LtsSessionData::getInstance()->isTablet()));
|
||||
#else
|
||||
bool success = m_widget->init(ppmDtc, ppmGuiCbxIfc, symbolAppearanceSettings, false); //in AHCT we have units!
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool TypeFilterDialog::apply()
|
||||
{
|
||||
m_widget->apply();
|
||||
|
||||
const SymbolAppearance symbolAppearance = m_widget->filter()->settingsToData();
|
||||
auto cb = [this, symbolAppearance]()
|
||||
{
|
||||
return m_fltFtc->symbolAppearanceUpdateRequest(symbolAppearance, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
return m_requestHelper->startRequests();
|
||||
}
|
||||
|
||||
void TypeFilterDialog::onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject)
|
||||
{
|
||||
m_requestHelper->requestReply(replyObject);
|
||||
}
|
||||
|
||||
void TypeFilterDialog::dialogCanceled()
|
||||
{
|
||||
m_widget->dialogCanceled();
|
||||
}
|
||||
|
||||
void TypeFilterDialog::onTypeFilterClicked()
|
||||
{
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(true);
|
||||
m_buttonBox->getButton(LtsWidgets::DialogButton::Apply)->setEnabled(true);
|
||||
}
|
||||
|
||||
void TypeFilterDialog::onLoadButtonClicked()
|
||||
{
|
||||
FilterChangeDialog *dialog = new FilterChangeDialog(this);
|
||||
if (!dialog->init(m_session, SymbolAppearanceSettings::Part::Types))
|
||||
{
|
||||
delete dialog;
|
||||
return;
|
||||
}
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
QObject::connect(dialog, &FilterChangeDialog::rejected, dialog, &FilterChangeDialog::deleteLater);
|
||||
dialog->show();
|
||||
|
||||
}
|
||||
|
||||
void TypeFilterDialog::onDataChanged(const FilterManagement::SymbolAppearance &data, DataModification modType)
|
||||
{
|
||||
if (modType != DataModification::eRemoved &&
|
||||
data.operatorId() == LtsSessionData::LtsSessionData::getInstance()->getOperatorId())
|
||||
{
|
||||
auto symbolAppearanceSettings = m_fltParticipantIfc->symbolAppearanceForOperator(LtsSessionData::LtsSessionData::getInstance()->getOperatorId(),
|
||||
m_session->workspaceId());
|
||||
m_widget->onDataChanged(symbolAppearanceSettings);
|
||||
|
||||
// the data can be changed if another replay is selected or filter are loaded.
|
||||
// So our widget has to be updated:
|
||||
__unchange__();
|
||||
}
|
||||
}
|
||||
|
||||
void TypeFilterDialog::onExportButtonClicked()
|
||||
{
|
||||
m_widget->apply();
|
||||
const auto s = m_widget->filter();
|
||||
QJsonObject saveObject;
|
||||
saveObject[QStringLiteral("XmlType")] = FileManagement::toString(FileManagement::XmlType::FLTTypeFilter);
|
||||
saveObject[QStringLiteral("content")] = s->settingsToJson();
|
||||
|
||||
const QJsonDocument saveDoc(saveObject);
|
||||
DEBUG_LOG(m_logger) << "Saving: " << saveDoc.toJson();
|
||||
|
||||
int fileId = m_flmGui->saveFileContent(this, FileManagement::FileType::Xml, m_session->exerciseId(), saveDoc.toJson(QJsonDocument::Compact));
|
||||
if (fileId > 0)
|
||||
DEBUG_LOG(m_logger) << "Saved file with id = " << fileId;
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Could not save file in library ";
|
||||
}
|
||||
|
||||
void TypeFilterDialog::onImportButtonClicked()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << " onImportButtonClicked() ";
|
||||
|
||||
QByteArray content;
|
||||
int fileId = m_flmGui->loadFileContent(this, content, {FileManagement::FileType::Xml}, m_session->exerciseId(), FileManagement::toString(FileManagement::XmlType::FLTTypeFilter));
|
||||
if (fileId > 0)
|
||||
{
|
||||
if (!m_flmGui->isXmlType(content, FileManagement::toString(FileManagement::XmlType::FLTTypeFilter)))
|
||||
{
|
||||
QHash<LtsWidgets::Button, QString> texts({{LtsWidgets::Button::Yes, tr("Ok")}});
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this,
|
||||
tr("Invalid xml file content"),
|
||||
windowTitle(),
|
||||
LtsWidgets::Behaviour::Modal,
|
||||
LtsWidgets::Button::Yes,
|
||||
texts);
|
||||
}
|
||||
else
|
||||
{
|
||||
const QJsonDocument loadDoc(QJsonDocument::fromJson(content));
|
||||
DEBUG_LOG(m_logger) << "Loading: " << loadDoc.toJson();
|
||||
m_widget->filter()->setSettings(loadDoc.object().value(QStringLiteral("content")).toObject(),
|
||||
FilterManagement::SymbolAppearanceSettings::Part::Types);
|
||||
const SymbolAppearance symbolAppearance = m_widget->filter()->settingsToData();
|
||||
|
||||
auto cb = [symbolAppearance, this]()
|
||||
{
|
||||
return m_fltFtc->symbolAppearanceUpdateRequest(symbolAppearance, this);
|
||||
};
|
||||
m_requestHelper->addRequest(cb);
|
||||
m_requestHelper->startRequests();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Type Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsWidgets/lts_dialog.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_participant_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <FileManagement/flm_explorer_gui_plugin_interface.h>
|
||||
#include <ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
|
||||
#include "flt_type_filter_widget.h"
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class TypeFilterDialog final : public LtsWidgets::LtsDialog
|
||||
, private FilterManagement::Interface::Ftc::SymbolAppearanceUpdateReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TypeFilterDialog(QWidget *parent = nullptr);
|
||||
~TypeFilterDialog();
|
||||
|
||||
bool init(LtsSession::LtsSession *session);
|
||||
void retranslate() override;
|
||||
|
||||
private:
|
||||
bool apply() override;
|
||||
void dialogCanceled() override;
|
||||
void onSymbolAppearanceUpdateReply(const Core::FunctionReplyObject &replyObject) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onTypeFilterClicked();
|
||||
void onLoadButtonClicked();
|
||||
void onDataChanged(const FilterManagement::SymbolAppearance &data, DataModification modType);
|
||||
void onExportButtonClicked();
|
||||
void onImportButtonClicked();
|
||||
|
||||
private:
|
||||
LtsSession::LtsSession *m_session;
|
||||
std::shared_ptr<FilterManagement::Interface::Dtc> m_fltDtc;
|
||||
std::shared_ptr<FilterManagement::Interface::Ftc> m_fltFtc;
|
||||
std::shared_ptr<FilterManagement::ForeignFltParticipantGuiInterface> m_fltParticipantIfc;
|
||||
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
|
||||
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
TypeFilterWidget *m_widget;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Type Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#include "flt_type_filter_widget.h"
|
||||
#include "ui_flt_type_filter_widget.h"
|
||||
|
||||
#include <ParticipantManagement/ppm_translation.h>
|
||||
#include <ProjectDataManagement/pdm_translation.h>
|
||||
#include <LtsWidgets/lts_message_dialog.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGroupBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
TypeFilterWidget::TypeFilterWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_hiddenTypeFilter(QSet<int>())
|
||||
, m_hiddenStateFilter(QSet<int>())
|
||||
, m_partyId(0)
|
||||
, m_gridLayout(new QGridLayout)
|
||||
, m_ui(new Ui::TypeFilterWidget)
|
||||
, m_logger(getLogger("TypeFilterWidget"))
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
initStateElements();
|
||||
|
||||
connect(m_ui->cbParty, &LtsWidgets::LtsComboBox::currentTextChanged, this, &TypeFilterWidget::onPartyChanged);
|
||||
}
|
||||
|
||||
TypeFilterWidget::~TypeFilterWidget()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void TypeFilterWidget::retranslate()
|
||||
{
|
||||
m_ui->retranslateUi(this);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::initTypeClassElements(bool ocMode)
|
||||
{
|
||||
static const auto typeClassesUnit = {ParticipantManagement::TypeClass_def::Unit,
|
||||
ParticipantManagement::TypeClass_def::SupportUnit,
|
||||
};
|
||||
static const auto typeClasses = {ParticipantManagement::TypeClass_def::SupportEntity,
|
||||
ParticipantManagement::TypeClass_def::Human,
|
||||
ParticipantManagement::TypeClass_def::GroundVehicle,
|
||||
ParticipantManagement::TypeClass_def::VehicleWithGear,
|
||||
ParticipantManagement::TypeClass_def::WeaponSystem,
|
||||
ParticipantManagement::TypeClass_def::Aircraft,
|
||||
ParticipantManagement::TypeClass_def::Vessel,
|
||||
};
|
||||
if (!ocMode)
|
||||
{
|
||||
for (auto typeClass : typeClassesUnit)
|
||||
createTypeClass(typeClass);
|
||||
}
|
||||
for (auto typeClass : typeClasses)
|
||||
createTypeClass(typeClass);
|
||||
|
||||
m_ui->gBTypes->setLayout(m_gridLayout);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::initStateElements()
|
||||
{
|
||||
QVBoxLayout *vBox = new QVBoxLayout;
|
||||
|
||||
// Getting the states from the enum definition (without the last three, which have other purposes)
|
||||
for (int enumIt = 0; enumIt <= ProjectDataManagement::VulnerabilityState_def::TemporarySeverance; ++enumIt)
|
||||
{
|
||||
QCheckBox *chb = new QCheckBox(m_ui->gBStates);
|
||||
|
||||
// Set the text for the checkbox = name of enum value
|
||||
chb->setText(ProjectDataManagement::toString(
|
||||
static_cast<ProjectDataManagement::VulnerabilityState_def::type>(enumIt)));
|
||||
|
||||
// Name the object as 'chb' + name of enum value; e.g. chbCombatReady
|
||||
chb->setObjectName(QStringLiteral("chb%1").arg(ProjectDataManagement::toString(
|
||||
static_cast<ProjectDataManagement::VulnerabilityState_def::type>(enumIt))));
|
||||
|
||||
chb->setProperty("stateId", enumIt);
|
||||
connect(chb, &QCheckBox::clicked, this, &TypeFilterWidget::onTypeFilterChanged);
|
||||
vBox->addWidget(chb);
|
||||
}
|
||||
|
||||
vBox->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding));
|
||||
m_ui->gBStates->setLayout(vBox);
|
||||
}
|
||||
|
||||
bool TypeFilterWidget::init(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmIfc,
|
||||
const std::shared_ptr<SymbolAppearanceSettings> &filter,
|
||||
bool ocMode)
|
||||
{
|
||||
m_ppmDtc = ppmDtc;
|
||||
|
||||
m_symbolAppearanceSettings = filter;
|
||||
m_originalSymbolAppearance = m_symbolAppearanceSettings->settings();
|
||||
setSymbolAppearanceSettings();
|
||||
initTypeClassElements(ocMode);
|
||||
|
||||
ppmIfc->fillPartyComboBox(m_ui->cbParty, ParticipantManagement::ForeignGuiComboboxInterface::CbxPartyFilter::NormalOc);
|
||||
onPartyChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TypeFilterWidget::createTypeClass(ParticipantManagement::TypeClass typeClass)
|
||||
{
|
||||
QGroupBox *gb = new QGroupBox;
|
||||
m_gbTypes.insert(typeClass, gb);
|
||||
|
||||
QGridLayout *gridLayout = new QGridLayout;
|
||||
gb->setTitle(ParticipantManagement::toString(typeClass));
|
||||
gb->setLayout(gridLayout);
|
||||
|
||||
// Button to check/uncheck all checkboxes
|
||||
QPushButton *btnCheckAll = new QPushButton(gb);
|
||||
connect(btnCheckAll, &QPushButton::clicked, this, &TypeFilterWidget::onCheckUncheckAllClicked);
|
||||
// Small horizontal layout, so the button doesn't take full width
|
||||
QHBoxLayout *btnHBL = new QHBoxLayout;
|
||||
btnHBL->addWidget(btnCheckAll);
|
||||
btnHBL->addStretch();
|
||||
gridLayout->addLayout(btnHBL, 0, 0, 1, 5);
|
||||
|
||||
const QMap<qint32, ParticipantManagement::Type> typeMap = m_ppmDtc->types();
|
||||
const int maxRow = 25;
|
||||
int iRow = 1;
|
||||
int iCol = 0;
|
||||
|
||||
QMap<std::string, ParticipantManagement::Type> typeMapOrder;
|
||||
for (const ParticipantManagement::Type &type : typeMap)
|
||||
typeMapOrder.insert(type.name(), type);
|
||||
|
||||
for (const ParticipantManagement::Type &type : qAsConst(typeMapOrder))
|
||||
{
|
||||
//removed types are still in the list! ignore deleted!
|
||||
if (type.isDeleted())
|
||||
continue;
|
||||
|
||||
// skip types not in use in this exercise
|
||||
if (!m_ppmDtc->isTypeInUse(type.id()))
|
||||
continue;
|
||||
|
||||
if (type.typeClass() == typeClass)
|
||||
{
|
||||
QCheckBox *cb = new QCheckBox(gb);
|
||||
cb->setText(ParticipantManagement::trTypeName(type.name()));
|
||||
cb->setProperty("typeId", type.id());
|
||||
cb->setProperty("typeClassId", typeClass.underlying());
|
||||
if (!m_hiddenTypeFilter.contains(type.id()))
|
||||
cb->setChecked(true);
|
||||
connect(cb, &QCheckBox::clicked, this, &TypeFilterWidget::onTypeFilterChanged);
|
||||
|
||||
gridLayout->addWidget(cb, iRow, iCol);
|
||||
++iRow;
|
||||
if (iRow > maxRow)
|
||||
{
|
||||
iRow = 1;
|
||||
++iCol;
|
||||
}
|
||||
}
|
||||
}
|
||||
iRow = iCol == 0 ? iRow : maxRow;
|
||||
gridLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), iRow, 0);
|
||||
m_gridLayout->addWidget(gb, 0, m_gridLayout->columnCount());
|
||||
}
|
||||
|
||||
void TypeFilterWidget::setGroupBoxesVisible(const bool bShowOC)
|
||||
{
|
||||
for (auto it = m_gbTypes.cbegin(); it != m_gbTypes.cend(); ++it)
|
||||
{
|
||||
QGroupBox *gb = it.value();
|
||||
const auto tc = it.key();
|
||||
const bool bIsOc = tc == ParticipantManagement::TypeClass_def::SupportEntity ||
|
||||
tc == ParticipantManagement::TypeClass_def::SupportUnit;
|
||||
bool bShow = bShowOC ? bIsOc : !bIsOc;
|
||||
if (bShow && !gb->findChild<QCheckBox*>())
|
||||
bShow = false;
|
||||
gb->setVisible(bShow);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeFilterWidget::setSymbolAppearanceSettings()
|
||||
{
|
||||
const SymbolAppearanceSettings::Settings &s = m_symbolAppearanceSettings->settings();
|
||||
m_hiddenTypeFilter = s.hiddenTypeFilter.value(m_partyId);
|
||||
m_hiddenStateFilter = s.hiddenStateFilter.value(m_partyId);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::apply()
|
||||
{
|
||||
const SymbolAppearanceSettings::Settings &s = getCurrentUiSettings();
|
||||
m_symbolAppearanceSettings->setSettings(s, FilterManagement::SymbolAppearanceSettings::Part::Types);
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
SymbolAppearanceSettings::Settings TypeFilterWidget::getCurrentUiSettings()
|
||||
{
|
||||
const auto gbs(m_ui->gBTypes->findChildren<QGroupBox *>(QString(), Qt::FindDirectChildrenOnly));
|
||||
for (QGroupBox *gb : gbs)
|
||||
setHiddenTypeFilter(gb);
|
||||
|
||||
setHiddenStateFilter();
|
||||
SymbolAppearanceSettings::Settings s = m_symbolAppearanceSettings->settings();
|
||||
s.hiddenTypeFilter.insert(m_partyId, m_hiddenTypeFilter);
|
||||
s.hiddenStateFilter.insert(m_partyId, m_hiddenStateFilter);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void TypeFilterWidget::dialogCanceled()
|
||||
{
|
||||
m_symbolAppearanceSettings->setSettings(m_originalSymbolAppearance, FilterManagement::SymbolAppearanceSettings::Part::Types);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::onDataChanged(const std::shared_ptr<SymbolAppearanceSettings> &newFilter)
|
||||
{
|
||||
m_originalSymbolAppearance = newFilter->settings();
|
||||
m_symbolAppearanceSettings = newFilter;
|
||||
setSymbolAppearanceSettings();
|
||||
onReinitTypeFilterCbx();
|
||||
updateStateFilter();
|
||||
}
|
||||
|
||||
void TypeFilterWidget::setHiddenTypeFilter(QGroupBox *gb)
|
||||
{
|
||||
if (gb)
|
||||
{
|
||||
const QList<QCheckBox *> listCbs = gb->findChildren<QCheckBox *>();
|
||||
for (QCheckBox *cb : listCbs)
|
||||
{
|
||||
int typeId = cb->property("typeId").toInt();
|
||||
if (cb->checkState() == Qt::Checked)
|
||||
m_hiddenTypeFilter.remove(typeId);
|
||||
else
|
||||
m_hiddenTypeFilter.insert(typeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TypeFilterWidget::setHiddenStateFilter()
|
||||
{
|
||||
const auto cbs(m_ui->gBStates->findChildren<QCheckBox *>(QString(), Qt::FindDirectChildrenOnly));
|
||||
for (QCheckBox *chb : cbs)
|
||||
{
|
||||
if (chb->isChecked())
|
||||
m_hiddenStateFilter.remove(chb->property("stateId").toInt());
|
||||
else
|
||||
m_hiddenStateFilter.insert(chb->property("stateId").toInt());
|
||||
}
|
||||
}
|
||||
|
||||
void TypeFilterWidget::updateStateFilter()
|
||||
{
|
||||
const auto cbs(m_ui->gBStates->findChildren<QCheckBox *>(QString(), Qt::FindDirectChildrenOnly));
|
||||
for (QCheckBox *chb : cbs)
|
||||
chb->setChecked(!m_hiddenStateFilter.contains(chb->property("stateId").toInt()));
|
||||
}
|
||||
|
||||
void TypeFilterWidget::onReinitTypeFilterCbx()
|
||||
{
|
||||
int partyId = m_ui->cbParty->currentData().toInt();
|
||||
|
||||
for (QGroupBox *gb : qAsConst(m_gbTypes))
|
||||
{
|
||||
const QList<QCheckBox *> checkBoxes = gb->findChildren<QCheckBox *>();
|
||||
bool bAtLeastOneUnchecked = false;
|
||||
for (QCheckBox *cb : checkBoxes)
|
||||
{
|
||||
const bool bIsChecked = !m_hiddenTypeFilter.contains(cb->property("typeId").toInt());
|
||||
cb->setChecked(bIsChecked);
|
||||
if (!bIsChecked)
|
||||
bAtLeastOneUnchecked = true;
|
||||
}
|
||||
adjustCheckButtonText(gb, bAtLeastOneUnchecked);
|
||||
}
|
||||
|
||||
setGroupBoxesVisible(partyId == 1);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::onTypeFilterChanged()
|
||||
{
|
||||
setWindowModified(true);
|
||||
emit typeFilterChanged();
|
||||
|
||||
// Used to handle CheckAll button text
|
||||
QGroupBox *gb = qobject_cast<QGroupBox *>(QObject::sender()->parent());
|
||||
if (!gb)
|
||||
return;
|
||||
|
||||
const QList<QCheckBox *> chbs = gb->findChildren<QCheckBox *>();
|
||||
if (chbs.isEmpty())
|
||||
return;
|
||||
|
||||
bool bAtLeastOneUnchecked = false;
|
||||
for (const QCheckBox *chb : chbs)
|
||||
{
|
||||
if (!chb->isChecked())
|
||||
{
|
||||
bAtLeastOneUnchecked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
adjustCheckButtonText(gb, bAtLeastOneUnchecked);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::onPartyChanged()
|
||||
{
|
||||
const int newPartyId = m_ui->cbParty->currentData().toInt();
|
||||
if (m_partyId == newPartyId)
|
||||
return;
|
||||
if (isWindowModified())
|
||||
{
|
||||
switch (LtsWidgets::LtsMessageDialog::askApplyDiscardCancel(this))
|
||||
{
|
||||
case LtsWidgets::Button::Apply:
|
||||
apply();
|
||||
doReinitModel(newPartyId);
|
||||
break;
|
||||
case LtsWidgets::Button::Cancel:
|
||||
m_ui->cbParty->setCurrentIndex(m_ui->cbParty->findData(m_partyId, Qt::UserRole));
|
||||
break;
|
||||
case LtsWidgets::Button::Discard:
|
||||
doReinitModel(newPartyId);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
doReinitModel(newPartyId);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::doReinitModel(int newPartyId)
|
||||
{
|
||||
m_partyId = newPartyId;
|
||||
setSymbolAppearanceSettings();
|
||||
onReinitTypeFilterCbx();
|
||||
updateStateFilter();
|
||||
emit partyChanged(); // __unchange__();
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::onCheckUncheckAllClicked()
|
||||
{
|
||||
QGroupBox *gb = qobject_cast<QGroupBox *>(QObject::sender()->parent());
|
||||
if (!gb)
|
||||
return;
|
||||
|
||||
const QList<QCheckBox *> chbs = gb->findChildren<QCheckBox *>();
|
||||
if (chbs.isEmpty())
|
||||
return;
|
||||
|
||||
bool bAtLeastOneUnchecked = false;
|
||||
for (const QCheckBox *chb : chbs)
|
||||
{
|
||||
if (!chb->isChecked())
|
||||
{
|
||||
bAtLeastOneUnchecked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setWindowModified(true);
|
||||
|
||||
for (QCheckBox *chb : chbs)
|
||||
chb->setChecked(bAtLeastOneUnchecked);
|
||||
|
||||
// negate bAtLeastOneUnchecked - we just toggled this state
|
||||
adjustCheckButtonText(gb, !bAtLeastOneUnchecked);
|
||||
}
|
||||
|
||||
void TypeFilterWidget::adjustCheckButtonText(QGroupBox *gb, bool bAtLeastOneUnchecked)
|
||||
{
|
||||
// Set CheckAll button text to 'on' if at least one entry is unchecked
|
||||
QPushButton *btn = gb->findChild<QPushButton *>();
|
||||
if (btn)
|
||||
{
|
||||
static int s_minWidth = -1;
|
||||
if (s_minWidth < 0)
|
||||
{
|
||||
btn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
btn->setText(tr("Switch all on"));
|
||||
const int w1 = btn->minimumSizeHint().width();
|
||||
btn->setText(tr("Switch all off"));
|
||||
const int w2 = btn->minimumSizeHint().width();
|
||||
s_minWidth = std::max(w1, w2);
|
||||
}
|
||||
btn->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
|
||||
btn->setMinimumWidth(s_minWidth);
|
||||
btn->setText(bAtLeastOneUnchecked ? tr("Switch all on") : tr("Switch all off"));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* FilterManagement - Type Filter Dialog
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
#include <FilterManagement/logger.h>
|
||||
#include <FilterManagement/flt_data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_symbol_appearance_settings.h>
|
||||
#include <ParticipantManagement/ppm_data_plugin_interface.h>
|
||||
#include <ParticipantManagement/ppm_gui_combobox_plugin_interface.h>
|
||||
|
||||
class QGroupBox;
|
||||
class QGridLayout;
|
||||
namespace Ui
|
||||
{
|
||||
class TypeFilterWidget;
|
||||
}
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class TypeFilterWidget final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TypeFilterWidget(QWidget *parent = nullptr);
|
||||
~TypeFilterWidget();
|
||||
|
||||
bool init(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
|
||||
const std::shared_ptr<ParticipantManagement::ForeignGuiComboboxInterface> &ppmIfc,
|
||||
const std::shared_ptr<SymbolAppearanceSettings> &filter,
|
||||
bool ocMode = false);
|
||||
void retranslate();
|
||||
|
||||
void apply();
|
||||
void dialogCanceled();
|
||||
void onDataChanged(const std::shared_ptr<SymbolAppearanceSettings> &newFilter);
|
||||
|
||||
SymbolAppearanceSettings::Settings getCurrentUiSettings();
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> filter() const { return m_symbolAppearanceSettings; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void partyChanged();
|
||||
void typeFilterChanged();
|
||||
|
||||
private:
|
||||
void initTypeClassElements(bool ocMode);
|
||||
void initStateElements();
|
||||
void setSymbolAppearanceSettings();
|
||||
void setHiddenTypeFilter(QGroupBox *gb);
|
||||
void onReinitTypeFilterCbx();
|
||||
void setHiddenStateFilter();
|
||||
void updateStateFilter();
|
||||
void createTypeClass(ParticipantManagement::TypeClass typeClass);
|
||||
void setGroupBoxesVisible(const bool bShowOC);
|
||||
void adjustCheckButtonText(QGroupBox *gb, bool bAtLeastOneUnchecked);
|
||||
|
||||
private Q_SLOTS:
|
||||
void onTypeFilterChanged();
|
||||
void onPartyChanged();
|
||||
void doReinitModel(int newPartyId);
|
||||
void onCheckUncheckAllClicked();
|
||||
|
||||
private:
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
|
||||
|
||||
std::shared_ptr<SymbolAppearanceSettings> m_symbolAppearanceSettings;
|
||||
SymbolAppearanceSettings::Settings m_originalSymbolAppearance;
|
||||
QSet<int> m_hiddenTypeFilter;
|
||||
QSet<int> m_hiddenStateFilter;
|
||||
qint32 m_partyId;
|
||||
QMap<ParticipantManagement::TypeClass, QGroupBox *> m_gbTypes;
|
||||
|
||||
QGridLayout *m_gridLayout;
|
||||
Ui::TypeFilterWidget *m_ui;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TypeFilterWidget</class>
|
||||
<widget class="QWidget" name="TypeFilterWidget">
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Type/State Filter</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbParty">
|
||||
<property name="text">
|
||||
<string>Party:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="LtsWidgets::LtsComboBox" name="cbParty">
|
||||
<property name="const" stdset="0">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QGroupBox" name="gBStates">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Participant State Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QGroupBox" name="gBTypes">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Participant Type Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LtsWidgets::LtsComboBox</class>
|
||||
<extends>QComboBox</extends>
|
||||
<header>LtsWidgets/lts_combo_box.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for FilterManagement - Aes Filter (Interface for access from other Plugins)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <Services/FilterManagement/flt.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class AesDisplayFilter;
|
||||
|
||||
class ForeignAesGuiInterface
|
||||
{
|
||||
public:
|
||||
ForeignAesGuiInterface() = default;
|
||||
virtual ~ForeignAesGuiInterface() = default;
|
||||
|
||||
// START :
|
||||
// moved to ForeignFltParticipantGuiInterface
|
||||
// at flt_participant_plugin_interface.h
|
||||
// virtual std::shared_ptr<SymbolAppearanceSettings> symbolAppearanceForOperator(int operatorId, const QString &context) = 0;
|
||||
// : END
|
||||
|
||||
virtual std::shared_ptr<AesDisplayFilter> aesFilterForOperator(int operatorId, const QString &context) = 0;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Filtermanagement Interface for access from other Plugins - SymbolAppearance
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Norbert Thodenr, SLSE, 2022-11-25
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FilterManagement/flt_building_cmpnt_settings.h>
|
||||
#include <InfrastructureManagement/ism_enums.hpp>
|
||||
#include <QSet>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
// just a headerfile for small helper:
|
||||
|
||||
// to avoid redefinition, use template:
|
||||
template <class UNUSED = void>
|
||||
QSet<InfrastructureManagement::MountingPointType> getVisibleTypesOfFilter(const FilterManagement::BuildingComponentSettings::BldCmpSettings &bldCmpSettings)
|
||||
{
|
||||
QSet<InfrastructureManagement::MountingPointType> visibleTypes;
|
||||
|
||||
const FilterManagement::BuildingComponentSettings::BldCmpSettings::ComponentSettings &compSettings =
|
||||
bldCmpSettings.componentSettings;
|
||||
|
||||
if (compSettings.showAnnouncementUnit) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::AnnouncementUnit);
|
||||
if (compSettings.showBuildingControlUnit) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::BuildingControlUnit);
|
||||
if (compSettings.showBuildingNetworkSwitch) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::BuildingNetworkSwitch);
|
||||
if (compSettings.showBuildingSensorModule) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::BuildingSensorModule);
|
||||
if (compSettings.showEffectGenerationControlUnit) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::EffectGenerationControlUnit);
|
||||
if (compSettings.showIndoorCamera) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::IndoorCamera);
|
||||
if (compSettings.showIndoorIPS) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::IndoorIPS);
|
||||
if (compSettings.showMeteoDataUnit) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::MeteoDataUnit);
|
||||
if (compSettings.showOutdoorCamera) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::OutdoorCamera);
|
||||
if (compSettings.showOutdoorControlUnit) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::OutdoorControlUnit);
|
||||
if (compSettings.showOutdoorIPS) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::OutdoorIPS);
|
||||
if (compSettings.showVirtualIPS) visibleTypes.insert(InfrastructureManagement::MountingPointType_def::type::VirtualIPS);
|
||||
|
||||
return visibleTypes;
|
||||
}
|
||||
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for FilterManagement - Participant Filter (Interface for access from other Plugins)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Services/FilterManagement/flt.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class BuildingComponentSettings;
|
||||
|
||||
class ForeignFltBuildingComponentGuiInterface
|
||||
{
|
||||
public:
|
||||
ForeignFltBuildingComponentGuiInterface() = default;
|
||||
virtual ~ForeignFltBuildingComponentGuiInterface() = default;
|
||||
|
||||
virtual std::shared_ptr<BuildingComponentSettings> buildingComponentSettingsForOperator(int operatorId, const QString &context) = 0;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Filtermanagement Interface for access from other Plugins - SymbolAppearance
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-06-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FilterManagement/flt_dtc.h>
|
||||
#include <functional>
|
||||
#include <QSet>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class BuildingComponentSettings
|
||||
{
|
||||
protected:
|
||||
BuildingComponentSettings() = default;
|
||||
virtual ~BuildingComponentSettings() = default;
|
||||
|
||||
public:
|
||||
virtual void resetBuildingComponentSettings() = 0;
|
||||
|
||||
struct BldCmpSettings
|
||||
{
|
||||
bool bIsValid = false;
|
||||
|
||||
// Building/Floors
|
||||
struct BuildingSettings
|
||||
{
|
||||
// GUEZE-1478
|
||||
// QSet<int> visibleFloorIds;
|
||||
// If QSet ist empty -> show all floors.
|
||||
// So use 'hidden..' instead of 'visible..':
|
||||
QSet<int> hiddenFloorIds;
|
||||
bool showBuildingOutline = true;
|
||||
bool showBuildingName = false;
|
||||
|
||||
bool operator==(const BuildingSettings &o) const
|
||||
{
|
||||
return
|
||||
hiddenFloorIds == o.hiddenFloorIds &&
|
||||
showBuildingOutline == o.showBuildingOutline &&
|
||||
showBuildingName == o.showBuildingName;
|
||||
}
|
||||
|
||||
bool operator !=(const BuildingSettings &o) const
|
||||
{
|
||||
return !operator==(o);
|
||||
}
|
||||
} buildingSettings;
|
||||
|
||||
// ISM / Components (MountingPointType)
|
||||
struct ComponentSettings
|
||||
{
|
||||
bool showBuildingSensorModule = true;
|
||||
bool showBuildingControlUnit = true;
|
||||
bool showOutdoorCamera = true;
|
||||
bool showIndoorCamera = true;
|
||||
bool showOutdoorIPS = true;
|
||||
bool showIndoorIPS = true;
|
||||
bool showMeteoDataUnit = true;
|
||||
bool showAnnouncementUnit = true;
|
||||
bool showVirtualIPS = true;
|
||||
bool showEffectGenerationControlUnit = true;
|
||||
bool showOutdoorControlUnit = true;
|
||||
bool showBuildingNetworkSwitch = true;
|
||||
|
||||
bool operator==(const ComponentSettings &o) const
|
||||
{
|
||||
return
|
||||
showBuildingSensorModule == o.showBuildingSensorModule &&
|
||||
showBuildingControlUnit == o.showBuildingControlUnit &&
|
||||
showOutdoorCamera == o.showOutdoorCamera &&
|
||||
showIndoorCamera == o.showIndoorCamera &&
|
||||
showOutdoorIPS == o.showOutdoorIPS &&
|
||||
showIndoorIPS == o.showIndoorIPS &&
|
||||
showMeteoDataUnit == o.showMeteoDataUnit &&
|
||||
showAnnouncementUnit == o.showAnnouncementUnit &&
|
||||
showVirtualIPS == o.showVirtualIPS &&
|
||||
showEffectGenerationControlUnit == o.showEffectGenerationControlUnit &&
|
||||
showOutdoorControlUnit == o.showOutdoorControlUnit &&
|
||||
showBuildingNetworkSwitch == o.showBuildingNetworkSwitch;
|
||||
;
|
||||
}
|
||||
bool operator!=(const ComponentSettings &o) const
|
||||
{
|
||||
return !operator==(o);
|
||||
}
|
||||
} componentSettings;
|
||||
|
||||
// over all / BldCmpSettings
|
||||
bool operator==(const BldCmpSettings &o) const
|
||||
{
|
||||
return buildingSettings == o.buildingSettings &&
|
||||
componentSettings == o.componentSettings;
|
||||
}
|
||||
bool operator!=(const BldCmpSettings &o) const
|
||||
{
|
||||
return !operator ==(o);
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return bIsValid;
|
||||
}
|
||||
}; // BldCmpSettings
|
||||
|
||||
// DDS
|
||||
virtual bool setBldCmpSettingsFromData(const BuildingComponentFilter &filterData) = 0; // BuildingComponentFilter == DDS
|
||||
virtual QJsonObject bldCmpSettingsToJson() const = 0;
|
||||
virtual BuildingComponentFilter bldCmpSettingsToData() const = 0;
|
||||
|
||||
// C++struct
|
||||
virtual bool setBldCmpSettings(const QJsonObject &obj) = 0;
|
||||
virtual bool setBldCmpSettings(const BldCmpSettings &s) = 0;
|
||||
virtual const BldCmpSettings &bldCmpSettings() const = 0;
|
||||
|
||||
class SettingsChangedCallback
|
||||
{
|
||||
public:
|
||||
virtual ~SettingsChangedCallback() = default;
|
||||
virtual void onBuildingComponentSettingsChanged() = 0;
|
||||
};
|
||||
|
||||
virtual void addChangedCallback(SettingsChangedCallback *cb) = 0;
|
||||
virtual void removeChangedCallback(SettingsChangedCallback *cb) = 0;
|
||||
virtual bool isChangedCallbackRegistered(SettingsChangedCallback *cb) const = 0;
|
||||
};
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Filtermanagement Interface for access from other Plugins - AesDisplayFilter
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-06-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PluginInterfaces/data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_dtc.h>
|
||||
#include <AreaEffectSimulation/aes_enums.hpp>
|
||||
#include <functional>
|
||||
#include <QSet>
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class AesDisplayFilter
|
||||
{
|
||||
protected:
|
||||
AesDisplayFilter() = default;
|
||||
virtual ~AesDisplayFilter() = default;
|
||||
|
||||
public:
|
||||
virtual void resetAesDisplayFilter() = 0;
|
||||
|
||||
struct EffectStateStruct
|
||||
{
|
||||
bool displayCreated = true;
|
||||
bool displayPrepared = true;
|
||||
bool displayActivated = true;
|
||||
bool limitOnChargeTypes = false;
|
||||
bool limitOnParties = false;
|
||||
bool showDetails = true; // used at MineArea setMineVisibility
|
||||
bool showDetails2 = true; // ExplosionClusterMeanHitPoint - MHP - MittlererTrefferPunkt
|
||||
bool showDetails3 = true; // ExplosionClusterGunToTargetLine
|
||||
bool showDetails4 = true; // ExplosionClusterTrajectory
|
||||
bool showDetails5 = false; // ExplosionClusterDetonationSphere
|
||||
bool displayCentral = true;
|
||||
bool displayPeripheral = true;
|
||||
int expiredAfterglowDurationMSec = 10 * 1000;
|
||||
QSet<int> visibleChargeTypeIds;
|
||||
QSet<int> visiblePartyIds;
|
||||
|
||||
bool operator==(const EffectStateStruct &o) const
|
||||
{
|
||||
return displayCreated == o.displayCreated &&
|
||||
displayPrepared == o.displayPrepared &&
|
||||
displayActivated == o.displayActivated &&
|
||||
limitOnChargeTypes == o.limitOnChargeTypes &&
|
||||
limitOnParties == o.limitOnParties &&
|
||||
showDetails == o.showDetails &&
|
||||
showDetails2 == o.showDetails2 &&
|
||||
showDetails3 == o.showDetails3 &&
|
||||
showDetails4 == o.showDetails4 &&
|
||||
showDetails5 == o.showDetails5 &&
|
||||
displayCentral == o.displayCentral &&
|
||||
displayPeripheral == o.displayPeripheral &&
|
||||
expiredAfterglowDurationMSec == o.expiredAfterglowDurationMSec &&
|
||||
visibleChargeTypeIds == o.visibleChargeTypeIds &&
|
||||
visiblePartyIds == o.visiblePartyIds;
|
||||
}
|
||||
bool operator!=(const EffectStateStruct &o) const
|
||||
{
|
||||
return !operator ==(o);
|
||||
}
|
||||
};
|
||||
|
||||
virtual bool setFilterFromData(const AesFilter &filterData) = 0;
|
||||
virtual bool setFilterFromData(const QJsonObject &filterData) = 0;
|
||||
virtual QJsonObject filterToJson() const = 0;
|
||||
virtual AesFilter filterToData() const = 0;
|
||||
|
||||
virtual bool isVisible(AreaEffectSimulation::AesType aesType,
|
||||
AreaEffectSimulation::AesEffectState aesState,
|
||||
int chargeTypeId,
|
||||
int partyId,
|
||||
bool isCentral,
|
||||
qint64 effectStart,
|
||||
qint64 effectDuration,
|
||||
qint64 currentTimeMSec) const = 0;
|
||||
virtual bool showDetails(AreaEffectSimulation::AesType aesType) const = 0;
|
||||
|
||||
|
||||
/*! ExplosionCluster */
|
||||
//@{
|
||||
virtual bool showExplosionClusterMeanHitPoint() const = 0; // MHP - MeanHitPoint - MittlererTrefferPunkt
|
||||
virtual bool showExplosionClusterGunToTargetLine() const = 0;
|
||||
virtual bool showExplosionClusterTrajectory() const = 0;
|
||||
virtual bool showExplosionClusterDetonationSphere() const = 0;
|
||||
virtual bool showNotTriggeredCDMine() const = 0;
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
virtual EffectStateStruct effectStateFilter(AreaEffectSimulation::AesType aesType) const = 0;
|
||||
virtual void setEffectStateFilter(AreaEffectSimulation::AesType aesType,
|
||||
const EffectStateStruct &ess) = 0;
|
||||
virtual int maxAfterglowDurationMSec() const = 0;
|
||||
|
||||
class FilterChangedCallback
|
||||
{
|
||||
public:
|
||||
virtual void onAesDisplayFilterChanged(AreaEffectSimulation::AesType aesType) = 0;
|
||||
};
|
||||
|
||||
virtual void addChangedCallback(FilterChangedCallback *cb) = 0;
|
||||
virtual void removeChangedCallback(FilterChangedCallback *cb) = 0;
|
||||
|
||||
virtual void setVisiblePartiesCheck(const std::function<bool(int)> &cb) = 0;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Filtermanagement Interface for access from other Plugins
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-06-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <PluginInterfaces/data_plugin_interface.h>
|
||||
#include <FilterManagement/flt_dtc.h>
|
||||
#include <FilterManagement/flt_ftc.h>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
/**
|
||||
* @brief The DataInterface class provides the Topics Clients only for the GUI Plugins
|
||||
*/
|
||||
class DataInterface : public DataPluginBase::Interface
|
||||
{
|
||||
public:
|
||||
using DataPluginBase::Interface::Interface;
|
||||
|
||||
virtual std::shared_ptr<FilterManagement::Interface::Dtc> getDtc() = 0;
|
||||
virtual std::shared_ptr<FilterManagement::Interface::Ftc> getFtc() = 0;
|
||||
};
|
||||
|
||||
} // namespace FilterManagement
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* HMI Plugin for FilterManagement - Participant Filter (Interface for access from other Plugins)
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-02-29
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Services/FilterManagement/flt.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
class SymbolAppearanceSettings;
|
||||
|
||||
class ForeignFltParticipantGuiInterface
|
||||
{
|
||||
public:
|
||||
ForeignFltParticipantGuiInterface() = default;
|
||||
virtual ~ForeignFltParticipantGuiInterface() = default;
|
||||
|
||||
// moved from AES (ForeignAesGuiInterface)
|
||||
virtual std::shared_ptr<SymbolAppearanceSettings> symbolAppearanceForOperator(int operatorId, const QString &context) = 0;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Filtermanagement Interface for access from other Plugins - SymbolAppearance
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2017-06-19
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <FilterManagement/flt_dtc.h>
|
||||
#include <AreaEffectSimulation/aes_enums.hpp>
|
||||
#include <functional>
|
||||
#include <QSet>
|
||||
|
||||
|
||||
namespace FilterManagement
|
||||
{
|
||||
|
||||
class SymbolAppearanceSettings
|
||||
{
|
||||
protected:
|
||||
SymbolAppearanceSettings() = default;
|
||||
virtual ~SymbolAppearanceSettings() = default;
|
||||
|
||||
public:
|
||||
virtual void resetSymbolAppearanceSettings() = 0;
|
||||
|
||||
enum class SymbolVisibility
|
||||
{
|
||||
Standard = 0,
|
||||
Faded = 1,
|
||||
Hidden = 2,
|
||||
AdditionalSymbol = 3
|
||||
};
|
||||
enum class UnitSymbolPosition
|
||||
{
|
||||
Center,
|
||||
Leader
|
||||
};
|
||||
|
||||
struct SymbolPartyAppearance
|
||||
{
|
||||
bool isVisible = true;
|
||||
bool showDesignator = true;
|
||||
bool showTacticalIdentifier = true;
|
||||
bool operator==(const SymbolPartyAppearance &o) const
|
||||
{
|
||||
return isVisible == o.isVisible &&
|
||||
showDesignator == o.showDesignator &&
|
||||
showTacticalIdentifier == o.showTacticalIdentifier;
|
||||
}
|
||||
bool operator !=(const SymbolPartyAppearance &o) const
|
||||
{
|
||||
return !operator==(o);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
bool bIsValid = false;
|
||||
// Part::Symbol
|
||||
struct SymbolSettings
|
||||
{
|
||||
float symbolScale = 1;
|
||||
float symbolTransparency = 0;
|
||||
int symbolFireEventFlashingMSec = 10 * 1000; // 10 sec
|
||||
int hitLineDisplayLengthMSec = 10 * 1000; // 10 sec
|
||||
int lrfLineDisplayLengthMSec = 10 * 1000; /// Laser range finder 10 sec
|
||||
int ltdLineDisplayLengthMSec = 10 * 1000; /// Laser Target designator 10 sec
|
||||
int movementTrackLengthMSec = 60 * 10 * 1000; // 10min
|
||||
bool showBuildingOutline = true;
|
||||
bool showBuildingIdentifier = false;
|
||||
bool showTrainingAreaBorder = false;
|
||||
bool showSpecialAreas = false;
|
||||
bool showFiringUnits = false; // feuereinheiten
|
||||
// bool showNasatNineLiner = true; // GUEZ NASAT / GNA // replaced by slider (GUEZE-1676)
|
||||
int nasatNineLinerDisplayLengthMSec = 100 * 1000; // 100 sec
|
||||
|
||||
SymbolVisibility bitErrorVisibility = SymbolVisibility::Standard;
|
||||
SymbolVisibility manipulationVisibility = SymbolVisibility::Standard;
|
||||
SymbolVisibility positionOutOfDateVisibility = SymbolVisibility::Standard;
|
||||
SymbolVisibility simulatedPositionVisibility = SymbolVisibility::AdditionalSymbol; // default AdditionalSymbol
|
||||
UnitSymbolPosition unitSymbolPosition = UnitSymbolPosition::Center;
|
||||
|
||||
QMap<int, SymbolPartyAppearance> symbolPartyAppearance;
|
||||
|
||||
bool operator==(const SymbolSettings &o) const
|
||||
{
|
||||
bool identicalPart1 =
|
||||
qFuzzyCompare(symbolScale, o.symbolScale) &&
|
||||
qFuzzyCompare(symbolTransparency, o.symbolTransparency) &&
|
||||
symbolFireEventFlashingMSec == o.symbolFireEventFlashingMSec &&
|
||||
hitLineDisplayLengthMSec == o.hitLineDisplayLengthMSec &&
|
||||
lrfLineDisplayLengthMSec == o.lrfLineDisplayLengthMSec &&
|
||||
ltdLineDisplayLengthMSec == o.ltdLineDisplayLengthMSec &&
|
||||
movementTrackLengthMSec == o.movementTrackLengthMSec &&
|
||||
showBuildingOutline == o.showBuildingOutline &&
|
||||
showBuildingIdentifier == o.showBuildingIdentifier &&
|
||||
showTrainingAreaBorder == o.showTrainingAreaBorder &&
|
||||
showSpecialAreas == o.showSpecialAreas &&
|
||||
showFiringUnits == o.showFiringUnits &&
|
||||
nasatNineLinerDisplayLengthMSec == o.nasatNineLinerDisplayLengthMSec &&
|
||||
bitErrorVisibility == o.bitErrorVisibility &&
|
||||
manipulationVisibility == o.manipulationVisibility &&
|
||||
positionOutOfDateVisibility == o.positionOutOfDateVisibility &&
|
||||
simulatedPositionVisibility == o.simulatedPositionVisibility &&
|
||||
unitSymbolPosition == o.unitSymbolPosition;
|
||||
|
||||
if (!identicalPart1)
|
||||
return false;
|
||||
|
||||
if (symbolPartyAppearance == o.symbolPartyAppearance)
|
||||
return true;
|
||||
|
||||
{
|
||||
// check if all entries are defaultValues:
|
||||
|
||||
static SymbolPartyAppearance defaultItem;
|
||||
|
||||
for (const SymbolPartyAppearance &item : symbolPartyAppearance)
|
||||
if (item != defaultItem)
|
||||
return false;
|
||||
for (const SymbolPartyAppearance &item : o.symbolPartyAppearance)
|
||||
if (item != defaultItem)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool operator !=(const SymbolSettings &o) const
|
||||
{
|
||||
return !operator==(o);
|
||||
}
|
||||
} symbolSettings;
|
||||
|
||||
// Part::Types
|
||||
QMap<qint32, QSet<int>> hiddenTypeFilter;
|
||||
QMap<qint32, QSet<int>> hiddenStateFilter;
|
||||
|
||||
static bool semanticCompare(const QMap<qint32, QSet<int>> &val1, const QMap<qint32, QSet<int>> &val2)
|
||||
{
|
||||
if (val1 == val2)
|
||||
return true;
|
||||
for (const QSet<int> &item : val1)
|
||||
if (!item.isEmpty())
|
||||
return false;
|
||||
for (const QSet<int> &item : val2)
|
||||
if (!item.isEmpty())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Part::CollapseExpand
|
||||
// do not use directly, use isParticipantFiltered()
|
||||
struct ColExpand
|
||||
{
|
||||
QSet<int> hiddenParticipantIds;
|
||||
QSet<int> collapsedParticipantIds;
|
||||
|
||||
bool operator==(const ColExpand &o) const
|
||||
{
|
||||
return hiddenParticipantIds == o.hiddenParticipantIds &&
|
||||
collapsedParticipantIds == o.collapsedParticipantIds;
|
||||
}
|
||||
bool operator!=(const ColExpand &o) const
|
||||
{
|
||||
return !operator==(o);
|
||||
}
|
||||
} colExpand;
|
||||
|
||||
|
||||
bool operator==(const Settings &o) const
|
||||
{
|
||||
return symbolSettings == o.symbolSettings &&
|
||||
hiddenTypeFilter == o.hiddenTypeFilter &&
|
||||
hiddenStateFilter == o.hiddenStateFilter &&
|
||||
colExpand == o.colExpand;
|
||||
}
|
||||
bool operator!=(const Settings &o) const
|
||||
{
|
||||
return !operator ==(o);
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return bIsValid;
|
||||
}
|
||||
};
|
||||
|
||||
enum class Part
|
||||
{
|
||||
Symbol,
|
||||
Types,
|
||||
CollapseExpand,
|
||||
All
|
||||
};
|
||||
|
||||
virtual bool setSettingsFromData(const SymbolAppearance &filterData) = 0; // SymbolAppearance == DDS
|
||||
virtual QJsonObject settingsToJson() const = 0;
|
||||
virtual SymbolAppearance settingsToData() const = 0;
|
||||
|
||||
virtual bool setSettings(const QJsonObject &obj, Part part) = 0;
|
||||
virtual bool setSettings(const Settings &s, Part part) = 0;
|
||||
virtual const Settings &settings() const = 0;
|
||||
|
||||
virtual bool isParticipantVisibileCollapseExpand(int participantId) const = 0;
|
||||
|
||||
class SettingsChangedCallback
|
||||
{
|
||||
public:
|
||||
virtual ~SettingsChangedCallback() = default;
|
||||
virtual void onSymbolAppearanceSettingsChanged(Part part) = 0;
|
||||
};
|
||||
|
||||
virtual void addChangedCallback(SettingsChangedCallback *cb) = 0;
|
||||
virtual void removeChangedCallback(SettingsChangedCallback *cb) = 0;
|
||||
virtual bool isChangedCallbackRegistered(SettingsChangedCallback *cb) const = 0;
|
||||
};
|
||||
} // namespace FilterManagement
|
||||
Reference in new issue
Block a user