Initial commit

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

No files matched your search

+40
View File
@@ -0,0 +1,40 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Christian Ehrlicher, SLSE, 2016-03-01
#
ADD_SUBDIRECTORY(Data)
ADD_SUBDIRECTORY(Gui)
ADD_SUBDIRECTORY(Helper)
#
# Data Plugin Interface
#
ADD_INTERFACE_LIBRARY(AsbDataPluginInterface
${CMAKE_CURRENT_SOURCE_DIR}/asb_data_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/..
DataPluginInterface
advancedSymbology
)
#
# Gui Plugin Interface (Symbol Editor)
#
ADD_INTERFACE_LIBRARY(AsbGuiPluginInterface
${CMAKE_CURRENT_SOURCE_DIR}/asb_gui_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/..
GuiPluginInterface
Qt5::Core
)
#
# Gui Plugin Interface (SymbolProxy)
#
ADD_INTERFACE_LIBRARY(AsbSymbolProxyGuiPluginInterface
${CMAKE_CURRENT_SOURCE_DIR}/asb_symbol_proxy_gui_plugin_interface.h
${CMAKE_CURRENT_SOURCE_DIR}/..
GuiPluginInterface
Qt5::Gui
)
+62
View File
@@ -0,0 +1,62 @@
#
# $Id$
# $HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Plugins/AdvancedSymbology/CMakeLists.txt
# $Author$
# Created by Mike Wille, SLSE, 2016-09-05
#
NGL_ADD_LIBRARY(WS AsbData STATIC
asb_foreign_interface_impl.cpp
asb_foreign_interface_impl.h
logger.cpp
logger.h
)
NGL_TARGET_LINK_LIBRARIES(AsbData
GimDataPluginInterface
AsbDataPluginInterface
AesDataPluginInterface
PpmDataPluginInterface
advancedSymbology
)
#
# Data Plugin
#
NGL_ADD_LIBRARY(WS AsbDataPlugin MODULE
asb_data_plugin.cpp
asb_data_plugin.h
asb_foreign_interface_impl.cpp
asb_foreign_interface_impl.h
logger.cpp
logger.h
)
NGL_TARGET_LINK_LIBRARIES(AsbDataPlugin
AsbData
Qt5::Core
AsbDataPluginInterface
GimDataPluginInterface
svcAesCommon
advancedSymbology
NGLLogger
LtsSessionDataDds
)
NGL_INSTALL_TARGET(AsbDataPlugin)
NGL_ADD_LIBRARY(WS AsbForeignDataPluginThp STATIC
asb_foreign_interface_impl.cpp
asb_foreign_interface_impl.h
logger.cpp
logger.h
)
NGL_TARGET_LINK_LIBRARIES(AsbForeignDataPluginThp
AsbData
Qt5::Core
AsbDataPluginInterface
GimDataPluginInterface
svcAesCommon
advancedSymbology
NGLLogger
LtsSessionDataDds
)
+82
View File
@@ -0,0 +1,82 @@
/**
* @RDE_HEADER@
* Data Plugin for AdvancedSymbology
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#include "asb_data_plugin.h"
#include "asb_foreign_interface_impl.h"
#include "logger.h"
#include <AreaEffectSimulation/aes_data_plugin_interface.h>
#include <ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/GuezIedManagement/gim_data_plugin_interface.h>
#include <SymbologyImpl/advanced_symbology_logging.h>
#include <Symbology/symbol_data_to_render_role.h>
#include <LtsSession/lts_session.h>
namespace AdvancedSymbology
{
AdvancedSymbology::SidcDefinitions::Identity roleToIdentity(const ParticipantManagement::Role role)
{
AdvancedSymbology::SidcDefinitions::Identity identity = AdvancedSymbology::SidcDefinitions::Identity::Unknown;
switch (role.underlying()) {
case ParticipantManagement::Role_def::Unknown:
identity = AdvancedSymbology::SidcDefinitions::Identity::Unknown;
break;
case ParticipantManagement::Role_def::Friend:
identity = AdvancedSymbology::SidcDefinitions::Identity::Friend;
break;
case ParticipantManagement::Role_def::Neutral:
identity = AdvancedSymbology::SidcDefinitions::Identity::Neutral;
break;
case ParticipantManagement::Role_def::Enemy:
identity = AdvancedSymbology::SidcDefinitions::Identity::HostileFaker;
break;
case ParticipantManagement::Role_def::Pending:
identity = AdvancedSymbology::SidcDefinitions::Identity::Pending;
break;
case ParticipantManagement::Role_def::AssumedFriend:
identity = AdvancedSymbology::SidcDefinitions::Identity::AssumedFriend;
break;
case ParticipantManagement::Role_def::Suspect:
identity = AdvancedSymbology::SidcDefinitions::Identity::SuspectJoker;
break;
} // switch
return identity;
}
std::shared_ptr<DataPluginBase::Interface> DataPlugin::createDataInterface(LtsSession::LtsSessionDataDds *session)
{
return std::make_shared<DataInterfaceImpl>(session);
}
DataInterfaceImpl::DataInterfaceImpl(LtsSession::LtsSessionDataDds *session)
: DataInterface()
, m_foreignInterface(nullptr)
, m_session(session)
{}
std::shared_ptr<ForeignDataInterface> DataInterfaceImpl::getForeignDataInterface()
{
if (!m_foreignInterface)
{
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> aesDtc;
std::shared_ptr<GuezIedManagement::Interface::Dtc> gimDtc;
m_session->getDtc<ParticipantManagement::DataInterface>(ppmDtc);
m_session->getDtc<AreaEffectSimulation::DataInterface>(aesDtc);
m_session->getDtc<GuezIedManagement::DataInterface>(gimDtc);
m_foreignInterface = std::make_shared<ForeignInterfaceImpl>(ppmDtc, aesDtc, gimDtc);
}
return m_foreignInterface;
}
} // namespace AdvancedSymbology
+45
View File
@@ -0,0 +1,45 @@
/**
* @RDE_HEADER@
* Data Plugin for AdvancedSymbology
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#pragma once
#include <PluginInterfaces/data_plugin_interface.h>
#include <AdvancedSymbology/asb_data_plugin_interface.h>
namespace AdvancedSymbology
{
class DataPlugin final : public QObject, public DataPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "data:3:asb")
Q_INTERFACES(DataPluginBase::Plugin)
Q_OBJECT
public:
DataPlugin() = default;
~DataPlugin() = default;
QString pluginName() const override { return QStringLiteral("AdvancedSymbology"); }
std::shared_ptr<DataPluginBase::Interface> createDataInterface(LtsSession::LtsSessionDataDds *session) override;
bool availableInPartition(IDL::PartitionType partition) const override { Q_UNUSED(partition); return true; }
};
class DataInterfaceImpl final : public DataInterface
{
public:
explicit DataInterfaceImpl(LtsSession::LtsSessionDataDds *session);
std::shared_ptr<ForeignDataInterface> getForeignDataInterface() override;
private:
std::shared_ptr<ForeignDataInterface> m_foreignInterface;
LtsSession::LtsSessionDataDds *m_session;
};
} // namespace AdvancedSymbology
@@ -0,0 +1,225 @@
/**
* @RDE_HEADER@
* Data Plugin for AdvancedSymbology
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#include "asb_foreign_interface_impl.h"
#include "logger.h"
#include <AreaEffectSimulation/aes_dtc.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <SymbologyImpl/advanced_symbology_logging.h>
#include <Symbology/symbol_data_to_render_role.h>
namespace AdvancedSymbology
{
ForeignInterfaceImpl::ForeignInterfaceImpl(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<AreaEffectSimulation::Interface::Dtc> &aesDtc,
const std::shared_ptr<GuezIedManagement::Interface::Dtc> &guezIedDtc)
: m_ppmDtc(ppmDtc)
, m_aesDtc(aesDtc)
, m_guezIedDtc(guezIedDtc)
, m_logger(getLogger("AdvancedSymbologyPlugin"))
{
if (!m_ppmDtc)
{
WARNING_LOG(m_logger) << "m_ppmDtc not available, No color and injury information will be included in created symbols";
Q_ASSERT(false);
}
}
AdvancedSymbology::SymbolDictionary &ForeignInterfaceImpl::getSymbolDictionary(AdvancedSymbology::SymbologyType type) const
{
// The underlying dictionary should be created and initialized during login.
return AdvancedSymbology::SymbolDictionary::dictionary(type);
}
AdvancedSymbology::SymbologyType ForeignInterfaceImpl::defaultSymbologyType() const
{
return AdvancedSymbology::SymbolDictionary::defaultSymbologyType();
} // AdvancedSymbology::SymbologyType ForeignInterfaceImpl::defaultSymbologyType() const
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findImage(const SymbolDictionary &dict,
const SymbolDataToRender &symDataToRender) const
{
return dict.findImage(symDataToRender);
}
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findImage(const SymbolDataToRender &symDataToRender) const
{
return AdvancedSymbology::SymbolDictionary::dictionary(defaultSymbologyType()).findImage(symDataToRender);
}
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findImage(const ParticipantManagement::Participant &participant, int sizeL, const QColor &desiredColor) const
{
AdvancedSymbology::SymbolDataToRender symDataToRender(QString::fromStdString(participant.symbol()), sizeL);
if (!m_ppmDtc)
return findImage(symDataToRender);
// Party Role (aka Identity / Affiliation)
const ParticipantManagement::Party &party = m_ppmDtc->party(participant.partyId());
symDataToRender.role = AdvancedSymbology::roleToRole<>(party.role());
// Party color
symDataToRender.fillColor = desiredColor.isValid() ? desiredColor : QColor::fromRgb(QRgb(party.color()));
symDataToRender.fillColorReplace = true;
// Injury color (which party caused the damage)
QColor injuryColor = QColor(100, 100, 0); // 100, 100, 0 -> ocker;;
ProjectDataManagement::VulnerabilityState currentState = ProjectDataManagement::VulnerabilityState::CombatReady;
const ParticipantManagement::DynamicParticipantData dData = m_ppmDtc->dynamicParticipantData(participant.id());
if (dData.stateHistory().size())
{
const ParticipantManagement::StateInformation &lastState = m_ppmDtc->youngestStateInformation(dData.stateHistory());
currentState = lastState.vulnerabilityState();
switch (lastState.originatorType().underlying())
{
case ProjectDataManagement::StateChangeOriginator::ImprovisedExplosiveDevice:
{
if (m_guezIedDtc)
{
const GuezIedManagement::Ied &gIed = m_guezIedDtc->iedForEquipmentNumber(lastState.originatorId());
if (gIed.id() > 0)
{
int injuryPartyId = gIed.partyId();
if (injuryPartyId >= 0)
injuryColor = m_ppmDtc->party(injuryPartyId).color();
}
}
break;
}
case ProjectDataManagement::StateChangeOriginator::DusMine:
{
if (!m_aesDtc)
{
WARNING_LOG(m_logger) << "Fetching 'm_aesDtc' failed, No color and injury information will be included in symbol created for participant.id() " << participant.id();
return findImage(symDataToRender);
}
const int partyId = m_aesDtc->partyForDusMine(lastState.originatorId());
if (partyId >= 0)
injuryColor = m_ppmDtc->party(partyId).color();
break;
}
case ProjectDataManagement::StateChangeOriginator::AreaEffectSimulation:
case ProjectDataManagement::StateChangeOriginator::FunctionalArea:
{
if (!m_aesDtc)
{
WARNING_LOG(m_logger) << "Fetching 'm_aesDtc' failed, No color and injury information will be included in symbol created for participant.id() " << participant.id();
return findImage(symDataToRender);
}
AreaEffectSimulation::AesItem aesItem;
m_aesDtc->aesItemFromId(lastState.originatorId(), aesItem);
if (aesItem.partyId().is_set())
injuryColor = m_ppmDtc->party(aesItem.partyId().get()).color();
break;
}
case ProjectDataManagement::StateChangeOriginator::Participant: // it's a participant not a party
{
const ParticipantManagement::Participant &participantOrigin = m_ppmDtc->participant(lastState.originatorId());
// Is the participant which caused the damaged known?
if (participantOrigin.id())
injuryColor = m_ppmDtc->party(participantOrigin.partyId()).color();
break;
}
case ProjectDataManagement::StateChangeOriginator::Party:
{
const ParticipantManagement::Party &partyOrigin = m_ppmDtc->party(lastState.originatorId());
if (partyOrigin.id())
injuryColor = partyOrigin.color();
break;
}
case ProjectDataManagement::StateChangeOriginator::ObserverController:
case ProjectDataManagement::StateChangeOriginator::ExerciseControl:
case ProjectDataManagement::StateChangeOriginator::Initialization:
injuryColor = m_ppmDtc->party(1).color(); //OC
break;
case ProjectDataManagement::StateChangeOriginator::WoundTreatmentDevice:
case ProjectDataManagement::StateChangeOriginator::MedicalTimeout:
case ProjectDataManagement::StateChangeOriginator::Sanitation:
case ProjectDataManagement::StateChangeOriginator::MaintainanceDevice:
case ProjectDataManagement::StateChangeOriginator::Unknown:
break;
}
}
symDataToRender.injury = stateToInjury(currentState);
symDataToRender.injuryColor = injuryColor;
return findImage(symDataToRender);
}
AdvancedSymbology::Injury ForeignInterfaceImpl::stateToInjury(const ProjectDataManagement::VulnerabilityState &state)
{
switch (state.underlying())
{
case ProjectDataManagement::VulnerabilityState::CombatReady:
case ProjectDataManagement::VulnerabilityState::TemporarySeverance:
case ProjectDataManagement::VulnerabilityState::NearMiss:
case ProjectDataManagement::VulnerabilityState::HitWithNoEffect:
return AdvancedSymbology::Injury::NoInjury;
case ProjectDataManagement::VulnerabilityState::LightDamage:
case ProjectDataManagement::VulnerabilityState::MediumDamage:
case ProjectDataManagement::VulnerabilityState::HeavyDamage:
case ProjectDataManagement::VulnerabilityState::NotReady:
return AdvancedSymbology::Injury::Hit;
case ProjectDataManagement::VulnerabilityState::MobilityKill:
case ProjectDataManagement::VulnerabilityState::VisibleMobilityKill:
return AdvancedSymbology::Injury::MobilityKill;
case ProjectDataManagement::VulnerabilityState::WeaponSystemDamage:
case ProjectDataManagement::VulnerabilityState::VisibleWeaponSystemDamage:
return AdvancedSymbology::Injury::WeaponKill;
case ProjectDataManagement::VulnerabilityState::CatastrophicKill:
return AdvancedSymbology::Injury::TotalKill;
case ProjectDataManagement::VulnerabilityState::NContamination:
case ProjectDataManagement::VulnerabilityState::BContamination:
case ProjectDataManagement::VulnerabilityState::CContamination:
case ProjectDataManagement::VulnerabilityState::VulnerabilityBitsChanged:
case ProjectDataManagement::VulnerabilityState::Reserved:
case ProjectDataManagement::VulnerabilityState::NoChange:
break;
} // switch
return AdvancedSymbology::Injury::NoInjury;
}
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findPreview(const SymbolDictionary &dict, const QString &sidc) const
{
return dict.findPreview(sidc);
}
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findPreview(const QString &sidc) const
{
return AdvancedSymbology::SymbolDictionary::dictionary(defaultSymbologyType()).findPreview(sidc);
}
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findBaseSymbol(const SymbolDictionary &dict, const QString &sidc) const
{
return dict.findBaseSymbol(sidc);
}
QSharedPointer<SymbolResult> ForeignInterfaceImpl::findBaseSymbol(const QString &sidc) const
{
return AdvancedSymbology::SymbolDictionary::dictionary(defaultSymbologyType()).findBaseSymbol(sidc);
}
} // namespace AdvancedSymbology
@@ -0,0 +1,69 @@
/**
* @RDE_HEADER@
* Data Plugin for AdvancedSymbology
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#pragma once
#include <PluginInterfaces/data_plugin_interface.h>
#include <AdvancedSymbology/asb_data_plugin_interface.h>
#include <ProjectDataManagement/pdm_enums.hpp>
#include <Plugins/GuezIedManagement/gim_data_plugin_interface.h>
#include <Symbology/symbol_dictionary.h>
namespace AreaEffectSimulation
{
namespace Interface
{
class Dtc;
}
}
namespace ParticipantManagement
{
namespace Interface
{
class Dtc;
}
}
namespace AdvancedSymbology
{
class ForeignInterfaceImpl final : public QObject, public ForeignDataInterface
{
Q_OBJECT
public:
explicit ForeignInterfaceImpl(const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<AreaEffectSimulation::Interface::Dtc> &aesDtc,
const std::shared_ptr<GuezIedManagement::Interface::Dtc> &guezIedDtc);
//
// SymbolDictionary: Access and find methods
//
AdvancedSymbology::SymbolDictionary &getSymbolDictionary(AdvancedSymbology::SymbologyType type) const override;
QSharedPointer<SymbolResult> findImage(const SymbolDictionary &dict, const SymbolDataToRender &symDataToRender) const override;
QSharedPointer<SymbolResult> findImage(const SymbolDataToRender &symDataToRender) const override;
QSharedPointer<SymbolResult> findImage(const ParticipantManagement::Participant &participant, int sizeL = 100, const QColor& desiredColor = QColor()) const override;
QSharedPointer<SymbolResult> findPreview(const SymbolDictionary &dict, const QString &sidc) const override;
QSharedPointer<SymbolResult> findPreview(const QString &sidc) const override;
QSharedPointer<SymbolResult> findBaseSymbol(const SymbolDictionary &dict, const QString &sidc) const override;
QSharedPointer<SymbolResult> findBaseSymbol(const QString &sidc) const override;
AdvancedSymbology::SymbologyType defaultSymbologyType() const override;
private:
static AdvancedSymbology::Injury stateToInjury(const ProjectDataManagement::VulnerabilityState &state);
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
std::shared_ptr<GuezIedManagement::Interface::Dtc> m_guezIedDtc;
NGL::INGLLogger &m_logger;
};
} // namespace AdvancedSymbology
+37
View File
@@ -0,0 +1,37 @@
/**
* @RDE_HEADER@
* Building - logging facility
* $Id$
* $HeadURL$
* $Author$
*/
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace BuildingViewer
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "ASB.";
std::string loggerName;
const size_t len = strlen(name);
loggerName.reserve(sizeof(ns) + len);
loggerName.append(ns, sizeof(ns) - 1);
loggerName.append(name, len);
try
{
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
getNGLLogger(loggerName);
}
catch (const std::exception &ex)
{
fprintf(stderr, "Error retrieving logger: %s", ex.what());
abort();
}
}
} // namespace BuildingViewer
+23
View File
@@ -0,0 +1,23 @@
/**
* @RDE_HEADER@
* Logging for BuildingViewer
* $Id$
* $HeadURL$
* $Author$
* Created by Patric Karwat, SLSE, 2016-08-17
*/
#pragma once
#include <NGLLogger/INGLLogger.h>
namespace BuildingViewer
{
typedef NGL::INGLLogger &LOGGER_T;
LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
} // namespace BuildingViewer
Binary file not shown.
+10
View File
@@ -0,0 +1,10 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Hannes Baeuerle, SLSE, 2017-06-13
#
add_subdirectory(SymbolEditor)
add_subdirectory(SymbolProxy)
@@ -0,0 +1,54 @@
# CMake script for SymbolEditor
SET(symboleditor_SRCS
asb_save_as_symbol.cpp
asb_save_as_symbol.h
asb_symbol_editor_gui_plugin.cpp
asb_symbol_editor_gui_plugin.h
asb_save_as_symbol.cpp
asb_save_as_symbol.h
asb_delete_elements_dialog.cpp
asb_delete_elements_dialog.h
asb_resize_dialog.cpp
asb_resize_dialog.h
asb_rotate_dialog.cpp
asb_rotate_dialog.h
asb_select_text_dialog.cpp
asb_select_text_dialog.h
asb_symbol_editor.cpp
asb_symbol_editor.h
asb_symbol_edit_scene.cpp
asb_symbol_edit_scene.h
flm_reply_handler.cpp
flm_reply_handler.h
)
SET(symboleditor_UICS
forms/asb_select_text_dialog.ui
forms/asb_delete_elements_dialog.ui
forms/asb_symbol_editor.ui
forms/asb_save_as_symbol.ui
forms/asb_rotate_dialog.ui
forms/asb_resize_dialog.ui
)
# Fuer die Icons
QT5_ADD_RESOURCES(symboleditor_SRCS application.qrc)
NGL_WRAP_UI(symboleditor_SRCS ${symboleditor_UICS})
NGL_ADD_LIBRARY(WS AsbSymEditGuiPlugin MODULE ${symboleditor_SRCS} ${symboleditor_UICS})
NGL_TARGET_LINK_LIBRARIES(AsbSymEditGuiPlugin
NGLLogger
LtsWidgets
FlmDataPluginInterface
PpmDataPluginInterface
advancedSymbology
advancedSymbologyXML
LtsSession
LtsSessionData
LtsUtilsGuiDds
Qt5::Core
Qt5::Gui
Qt5::Widgets
)
NGL_INSTALL_TARGET(AsbSymEditGuiPlugin)
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x00001003" dimen="land_units" affil="enemy" bcdab="undefined" command_level="undefined" mob="wheel">
<name>LinienOben</name>
<graphic scale="1.0">
<line transform="false" rotate="0" linewidth="0.1" linestyle="solid">
<point x="1.1" y="1.9"/>
<point x="1.1" y="1.9"/>
</line>
</graphic>
</symbol>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x00001003" dimen="undefined" affil="neutral" bcdab="undefined" command_level="undefined" mob="undefined">
<name>LinienOben</name>
<graphic scale="1">
<line transform="false" rotate="0" linewidth="0.05" linestyle="solid">
<point x="-1.6" y="1.6"/>
<point x="-0.1" y="1.6"/>
</line>
<line transform="false" rotate="0" linewidth="0.05" linestyle="solid">
<point x="0.1" y="1.6"/>
<point x="1.6" y="1.6"/>
</line>
</graphic>
</symbol>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x00001011" dimen="undefined" affil="neutral" bcdab="undefined" command_level="undefined" mob="undefined">
<name>Manipulation</name>
<graphic scale="1">
<line transform="false" rotate="0" color="#ffffffff" linewidth="0.1" linestyle="solid">
<point x="-1.2" y="-1.4"/>
<point x="1.2" y="-1.4"/>
</line>
<line transform="false" rotate="0" color="#000000ff" linewidth="0.1" linestyle="solid">
<point x="-1.2" y="-1.5"/>
<point x="1.2" y="-1.5"/>
</line>
</graphic>
</symbol>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x00001012" dimen="undefined" affil="neutral" bcdab="undefined" command_level="undefined" mob="undefined">
<name>NoPosition</name>
<graphic scale="1">
<line transform="false" rotate="0" color="#ff0000ff" linewidth="0.1" linestyle="solid">
<point x="-1.6" y="-1.6"/>
<point x="1.6" y="-1.6"/>
</line>
</graphic>
</symbol>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x1000" dimen="land_units" affil="neutral" bcdab="crew" command_level="undefined" mob="wheel">
<name>/shd/guez/int/WorkSpace/trunk/GDW/addOnSymbols/TestSymbol.xml</name>
<branch class="infantry" />
<text1 maxdatalength="9">
<data align="center">Test</data>
</text1>
<graphic scale="0.5">
<rect transform="false" rotate="45" linewidth="0.05" linestyle="dotted"
fill="0" color="#FF0000FF">
<point x="-0.543103" y="0.568966"/>
<point x="0.577586" y="-0.551724"/>
</rect>
</graphic>
</symbol>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x00001002" dimen="undefined" affil="neutral" bcdab="undefined" command_level="undefined" mob="undefined">
<name>vbgFireKill</name>
<graphic scale="1">
<line transform="false" rotate="0" linewidth="0.15" linestyle="solid">
<point x="-1.6" y="-1.6"/>
<point x="1.6" y="1.6"/>
</line>
</graphic>
</symbol>
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE symboltable SYSTEM "symbole.dtd">
<symbol version="1.0" id="0x00001001" dimen="undefined" affil="neutral" bcdab="undefined" command_level="undefined" mob="undefined">
<name>vbgFireKill</name>
<graphic scale="1">
<line transform="false" rotate="0" linewidth="0.15" linestyle="solid">
<point x="-1.6" y="1.6"/>
<point x="1.6" y="-1.6"/>
</line>
</graphic>
</symbol>
@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>icons/previewBackground.xpm</file>
</qresource>
</RCC>
@@ -0,0 +1,65 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#include "asb_delete_elements_dialog.h"
#include "ui_asb_delete_elements_dialog.h"
namespace AdvancedSymbology
{
//----------------------------------------------------------------------------
DeleteElementsDialog::DeleteElementsDialog(QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent)
, ui(new Ui_DeleteElementsDialog)
{
ui->setupUi(this);
initWidgets();
enaDisa();
}
//----------------------------------------------------------------------------
DeleteElementsDialog::~DeleteElementsDialog()
{
delete ui;
}
//----------------------------------------------------------------------------
void DeleteElementsDialog::initWidgets()
{
connect(ui->checkBoxPrims, &QCheckBox::toggled, this, &DeleteElementsDialog::enaDisa);
connect(ui->checkBoxPrimsSectorText, &QCheckBox::toggled, this, &DeleteElementsDialog::enaDisa);
connect(ui->checkBoxAttributes, &QCheckBox::toggled, this, &DeleteElementsDialog::enaDisa);
connect(ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &DeleteElementsDialog::accept);
connect(ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &DeleteElementsDialog::reject);
}
//----------------------------------------------------------------------------
void DeleteElementsDialog::enaDisa()
{
bool enabled = false;
if (ui->checkBoxPrims->isChecked() ||
ui->checkBoxPrimsSectorText->isChecked() ||
ui->checkBoxAttributes->isChecked())
enabled = true;
ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(enabled);
}
//----------------------------------------------------------------------------
void DeleteElementsDialog::getCheckedElements(bool &checkedPrims,
bool &checkedPrimsSectorText,
bool &checkedAttributes)
{
checkedPrims = ui->checkBoxPrims->isChecked();
checkedPrimsSectorText = ui->checkBoxPrimsSectorText->isChecked();
checkedAttributes = ui->checkBoxAttributes->isChecked();
}
}
@@ -0,0 +1,40 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
class Ui_DeleteElementsDialog;
namespace AdvancedSymbology
{
class DeleteElementsDialog final : public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
explicit DeleteElementsDialog(QWidget *parent);
~DeleteElementsDialog();
void getCheckedElements(bool &checkedPrims,
bool &checkedPrimsSectorText,
bool &checkedAttributes);
private Q_SLOTS :
void enaDisa();
protected:
void initWidgets();
Ui_DeleteElementsDialog *ui;
};
}
@@ -0,0 +1,65 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#include "asb_resize_dialog.h"
#include "asb_symbol_edit_scene.h"
#include "ui_asb_resize_dialog.h"
namespace AdvancedSymbology
{
ResizeDialog::ResizeDialog(bool lockChecked, bool lockEnabled, QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Popup)
, m_ui(new Ui_ResizeDialog)
{
m_ui->setupUi(this);
connect(m_ui->sliderHScale, &QSlider::valueChanged, this, &ResizeDialog::handleChange);
connect(m_ui->sliderVScale, &QSlider::valueChanged, this, &ResizeDialog::handleChange);
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &LtsWidgets::LtsFramelessDialog::reject);
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &LtsWidgets::LtsFramelessDialog::accept);
m_ui->checkBoxLock->setEnabled(lockEnabled);
m_ui->checkBoxLock->setChecked(lockChecked);
}
ResizeDialog::~ResizeDialog()
{
delete m_ui;
}
void ResizeDialog::handleChange(int val)
{
double hVal = double(val) / 100;
double vVal = double(val) / 100;
if (!m_ui->checkBoxLock->isChecked())
{
hVal = double(m_ui->sliderHScale->value()) / 100;
vVal = double(m_ui->sliderVScale->value()) / 100;
}
else
sync(val);
m_ui->spinBoxHScale->setValue(hVal);
m_ui->spinBoxVScale->setValue(vVal);
emit primitiveScaled(hVal, vVal);
}
void ResizeDialog::sync(int val)
{
m_ui->sliderHScale->setValue(val);
m_ui->sliderVScale->setValue(val);
}
}
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
class Ui_ResizeDialog;
/**
@author Stephan Kuhagen <stephan.kuhagen@rheinmetall.com>
*/
namespace AdvancedSymbology
{
class ResizeDialog final : public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
ResizeDialog(bool lockChecked, bool lockEnabled, QWidget *parent = nullptr);
~ResizeDialog();
signals:
void primitiveScaled(double xScale, double yScale);
private slots:
void handleChange(int val);
private:
void sync(int val);
Ui_ResizeDialog *m_ui;
};
}
@@ -0,0 +1,49 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#include "asb_rotate_dialog.h"
#include "ui_asb_rotate_dialog.h"
namespace AdvancedSymbology
{
RotateDialog::RotateDialog(QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent, LtsWidgets::Behaviour::Popup)
, m_ui(new Ui_RotateDialog)
{
m_ui->setupUi(this);
m_ui->spinBoxDegree->setSuffix(QStringLiteral(" °"));
connect(m_ui->sliderHDegree, &QSlider::valueChanged, this, &RotateDialog::handleValue);
connect(m_ui->spinBoxDegree, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, &RotateDialog::handleValue);
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &LtsWidgets::LtsFramelessDialog::reject);
connect(m_ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &LtsWidgets::LtsFramelessDialog::accept);
}
RotateDialog::~RotateDialog()
{
delete m_ui;
}
void RotateDialog::handleValue(double val)
{
sync(val);
emit rotationValueChanged(val);
}
void RotateDialog::sync(double val)
{
m_ui->sliderHDegree->setValue(int(val));
m_ui->spinBoxDegree->setValue(val);
}
}
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
class Ui_RotateDialog;
/**
@author Stephan Kuhagen <stephan.kuhagen@rheinmetall.com>
*/
namespace AdvancedSymbology
{
class RotateDialog final : public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
explicit RotateDialog(QWidget *parent = nullptr);
~RotateDialog();
private slots:
void handleValue(double val);
signals:
void rotationValueChanged(double val);
private:
void sync(double val);
Ui_RotateDialog *m_ui;
};
}
@@ -0,0 +1,91 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#include "asb_save_as_symbol.h"
#include "ui_asb_save_as_symbol.h"
#include <LtsWidgets/lts_dialog_button_box.h>
namespace AdvancedSymbology
{
SaveAsSymbol::SaveAsSymbol(QVariant &dlgData, const std::shared_ptr<FileManagement::Interface::Dtc> &flmDtc, QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent)
, m_ui(new Ui_SaveAsSymbol)
, m_buttonBox(new LtsWidgets::LtsDialogButtonBox(this))
, m_flmDtc(flmDtc)
, m_dlgData(dlgData)
{
m_ui->setupUi(this);
m_ui->verticalLayout->addWidget(m_buttonBox);
connect(m_buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked,
this, &SaveAsSymbol::reject);
connect(m_buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked,
this, &SaveAsSymbol::accept);
connect(m_ui->leName, &QLineEdit::textChanged,
this, &SaveAsSymbol::onInputChanged);
connect(m_flmDtc.get(), &FileManagement::Interface::Dtc::fileContentChanged,
this, &SaveAsSymbol::onFileContentChanged);
onInputChanged(m_ui->leName->text());
m_flmDtc->fileContents([this](const FileManagement::FileContent & data)
{
onFileContentChanged(data, DataModification::eAdded);
});
}
SaveAsSymbol::~SaveAsSymbol()
{
delete m_ui;
}
void SaveAsSymbol::accept()
{
m_symbolName = m_ui->leName->text();
m_dlgData.setValue(m_symbolName);
LtsFramelessDialog::accept();
}
void SaveAsSymbol::onInputChanged(const QString &input)
{
if (input.isEmpty())
{
m_ui->lblNameError->setText(tr("Name must not be empty"));
m_ui->lblNameError->setStyleSheet(QStringLiteral("color: rgb(255, 0, 0);"));
}
else if (m_takenNames.contains(input))
{
m_ui->lblNameError->setText(tr("Name is already taken"));
m_ui->lblNameError->setStyleSheet(QStringLiteral("color: rgb(255, 0, 0);"));
}
else
{
m_ui->lblNameError->setStyleSheet(QStringLiteral("color: rgb(0, 255, 0);"));
m_ui->lblNameError->setText(tr("Name is ok"));
}
m_buttonBox->getButton(LtsWidgets::DialogButton::Ok)->setEnabled(!(input.isEmpty() || m_takenNames.contains(input)));
}
void SaveAsSymbol::onFileContentChanged(const FileManagement::FileContent &data, DataModification modType)
{
if (data.fileType() != FileManagement::FileType::OperatorDefinedSymbol)
return;
QString name = QString::fromStdString(data.name());
if (modType == DataModification::eRemoved)
m_takenNames.removeAll(name);
else
m_takenNames.append(name);
}
}
@@ -0,0 +1,49 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <LtsWidgets/lts_frameless_dialog.h>
#include <FileManagement/flm_dtc.h>
class Ui_SaveAsSymbol;
namespace LtsWidgets
{
class LtsDialogButtonBox;
}
namespace AdvancedSymbology
{
class SaveAsSymbol final : public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
explicit SaveAsSymbol(QVariant &dlgData, const std::shared_ptr<FileManagement::Interface::Dtc> &flmDtc, QWidget *parent = nullptr);
~SaveAsSymbol();
QString symbolName() const;
private Q_SLOTS:
void accept() override final;
void onInputChanged(const QString &input);
void onFileContentChanged(const FileManagement::FileContent &data, DataModification modType);
private: // attributes
Ui_SaveAsSymbol *m_ui;
QString m_symbolName;
LtsWidgets::LtsDialogButtonBox *m_buttonBox;
QStringList m_takenNames;
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
QVariant &m_dlgData;
};
} //namespace AdvancedSymbology
@@ -0,0 +1,45 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#include "asb_select_text_dialog.h"
#include "ui_asb_select_text_dialog.h"
namespace AdvancedSymbology
{
//----------------------------------------------------------------------------
SelectTextDialog::SelectTextDialog(QVariant &returnData, QWidget *parent)
: LtsWidgets::LtsFramelessDialog(parent)
, ui(new Ui_SelectTextDialog)
, m_returnData(returnData)
{
ui->setupUi(this);
connect(ui->buttonBox->getButton(LtsWidgets::DialogButton::Close), &QPushButton::clicked, this, &SelectTextDialog::reject);
connect(ui->buttonBox->getButton(LtsWidgets::DialogButton::Ok), &QPushButton::clicked, this, &SelectTextDialog::accept);
}
//----------------------------------------------------------------------------
SelectTextDialog::~SelectTextDialog()
{
delete ui;
}
void SelectTextDialog::accept()
{
QVariantMap vmap;
vmap.insert(QStringLiteral("line_one"), ui->lineEdit1->text());
vmap.insert(QStringLiteral("line_two"), ui->lineEdit2->text());
m_returnData.setValue(vmap);
LtsWidgets::LtsFramelessDialog::accept();
}
}
@@ -0,0 +1,41 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <QVariant>
#include <LtsWidgets/lts_frameless_dialog.h>
class Ui_SelectTextDialog;
namespace AdvancedSymbology
{
class SelectTextDialog final : public LtsWidgets::LtsFramelessDialog
{
Q_OBJECT
public:
SelectTextDialog(QVariant &returnData, QWidget *parent);
~SelectTextDialog();
protected:
Ui_SelectTextDialog *ui;
private:
//NGL::INGLLogger& m_logger;
QVariant &m_returnData;
// QDialog interface
public slots:
void accept() override final;
};
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,344 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <QGraphicsScene>
#include <QPen>
#include <Viewer/SituationMap/SymbologyXML/primitive.h>
class QGraphicsItem;
class QGraphicsRectItem;
class QGraphicsSceneMouseEvent;
class QLabel;
class QPolygonF;
/**
\brief Implements mouse-events for editing symbol-items.
Derived class for user interaction with the preview and draw area of the
SymbolEditor.
@author Stephan Kuhagen <stephan.kuhagen@rheinmetall.com>
*/
namespace AdvancedSymbology
{
class SymbolEditScene final : public QGraphicsScene
{
Q_OBJECT
public:
explicit SymbolEditScene(QObject *parent = nullptr);
void setCoordsLabels(QLabel *xLabel, QLabel *yLabel, QLabel *zoomLabel)
{
m_labelCoordsX = xLabel;
m_labelCoordsY = yLabel;
m_labelZoom = zoomLabel;
}
//! Return the current zoom-value
double zoom() const
{
return m_zoom;
}
//! Set the current zoom-value and return it
double setZoom(double zoom);
//! Return current min zoom-value
double minZoom() const
{
return m_zoomMin;
}
//! Set min zoom-value
void setMinZoom(double min)
{
if (min < m_zoomMax) m_zoomMin = min;
}
//! Return current max zoom-value
double maxZoom() const
{
return m_zoomMax;
}
//! Set max zoom-value
void setMaxZoom(double max)
{
if (max > m_zoomMin) m_zoomMax = max;
}
//! The DrawModes
enum DrawMode
{
NONE,
ELLIPSE_START,
ELLIPSE_SET,
ELLIPSE_SET_START,
ELLIPSE_SET_EXTENT,
LINE_START,
LINE_SET,
POLYLINE_START,
POLYLINE_SET,
POLYGON_START,
POLYGON_SET,
RECT_START,
RECT_SET,
ICON_START,
ICON_SET,
TEXT_START,
TEXT_SET,
ELEMENT_DELETE,
ELEMENT_MOVE,
ELEMENT_ROTATE,
ELEMENT_PASTE,
ELEMENT_SCALE,
ELEMENT_SELECT
};
/**
Set the drawMode. This is used for Mouse-Interaction when the user draws
or manipulates new Primitives.
\param mode: the new DrawMode
*/
void setDrawMode(DrawMode mode);
/**
Return the current DrawMode
\return DrawMode
*/
DrawMode getDrawMode() const
{
return m_drawMode;
}
/**
If the scene manipulates the data, do not update the GraphicsViews
*/
bool updatesBlocked() const { return m_blockUpdates; }
/**
Called from a SEPathItem, when its Primitive needs to tell the Editor,
that it has been changed by user-interaction. Triggers emit primitiveChanged()
*/
void primitivePathItemChanged() { emit primitiveChanged(true); }
void setShowGrid(bool b);
void setShowDrawingArea(bool b);
void setGridWidth(double width);
void reset();
public slots:
/**
Set the Pen for Draw/Edit-Operations
*/
void setPen(const QPen &pen)
{
m_pen = pen;
}
void update(const QRectF &rect = QRectF());
//! Cancel the current action
void cancelCurrentAction();
signals:
/**
Emit a signal, if the zoom value has changed.
\param zoom: the new zoom value.
*/
void zoomChanged(double zoom);
/**
Emit a signal to add a new Primitive to the current Symbol
\param p: The new Primitive to add
*/
void addPrimitive(SymbologyXML::Primitive *p);
/**
Emit a signal, if a Primitive has changed
*/
void primitiveChanged(bool changed);
/**
Emit a signal, if a Primitive has been moved by user-interaction
*/
void primitiveMoved(QPointF diff);
/**
Transform the selected primitive
*/
void transformSelection(int key, Qt::KeyboardModifiers modifiers);
protected:
/**
Process a QGraphicsSceneMouseEvent. Used for displaying coordinates and
Primitive-Editing
\param mouseEvent: The Event
*/
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
/**
Process a QKeyEvent. Used for zooming and shift-functions
\param keyEvent: The Event
*/
void keyPressEvent(QKeyEvent *keyEvent) override;
/**
Process a QKeyEvent. Used for zooming and shift-functions
\param keyEvent: The Event
*/
void keyReleaseEvent(QKeyEvent *keyEvent) override;
/**
Process a QGraphicsSceneMouseEvent, used for adding new Primitives and
manipulating existing Primitives.
\param mouseEvent: The Event
*/
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
/**
Process a QGraphicsSceneMouseEvent, used for announcing end of manipulation
of Primitives.
\param mouseEvent: The Event
*/
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
/**
Process a QGraphicsSceneMouseEvent, used for announcing end of manipulation
of Primitives, i.e. Polyline and Polygon.
\param mouseEvent: The Event
*/
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
// QGraphicsScene interface
void drawForeground(QPainter *painter, const QRectF &rect) override final;
private:
//! NGLLogger
NGL::INGLLogger &logger;
/**
Create a new Ellipse. The point is the start-point of the bounding rect.
\param start: Startpoint of bounding rect.
*/
void newEllipse(const QPointF &start);
/**
Manipulate a new Ellipse
\param point: Change the second point of the boundnig rect end to this point
*/
void setEllipse(const QPointF &point);
/**
Set Start-Angle of a Ellipse. A line is drawn from the center to the given
point to indicate the start angle.
\param point: Reference point for the line
*/
void ellipseSetAngleStart(const QPointF &point);
/**
Set Extent-Angle of a Ellipse. A line is drawn from the center to the given
point to indicate the extent angle.
\param point: Reference point for the line
*/
void ellipseSetAngleExtent(const QPointF &point);
/**
Create a new Line starting from the given point
\param start: Startpoint of new line
*/
void newLine(const QPointF &start);
/**
Manipulate a new line
\param point: Change the line end to this point
*/
void setLine(const QPointF &point);
/**
Create a new Polygon starting from the given point
\param start: Startpoint of new polygon
*/
void newPolygon(const QPointF &start);
/**
Add new point to polygon
\param next: Set the next point
*/
void addPointPolygon(const QPointF &next);
/**
Manipulate a new polygon
\param point: Set the last point to this point
*/
void setPolygon(const QPointF &point);
/**
Create a new Rect.
\param start: Startpoint
*/
void newRect(const QPointF &start);
/**
Manipulate a new rect
\param end: Change the second point.
*/
void setRect(const QPointF &point);
/**
Create a Primitive and emit a signal announcing it.
\param type: Type of the new Primitive
*/
void sendNewItem(SymbologyXML::Primitive::t_primitive type);
/**
Rotate the stacking-order and selection of primitives
*/
void rotateSelection();
//! The currently drawn/edited graphicsItems
QPointF m_currentItemStartPoint;
QGraphicsItem *m_currentItem, *m_tmpItem;
//! Visible bounding rect for some Primitives
QGraphicsRectItem *m_boundingRect;
//! temp polygon for constructing polygons and polylines
QPolygonF m_tmpPolygon;
//! Start and Extent for Ellipsis
double m_ellipsisStart, m_ellipsisExtent;
//! construct Ellipsis: transitions 1° <--> 360° adjustment
double m_lastEllipseAngle, m_adjustAngle;
//!
double m_gridWidth;
//! If false, the Ellipsis ignores the angles
bool m_useAngles;
//!
bool m_showGrid;
//!
bool m_showDrawingArea;
//! The current Pen
QPen m_pen;
//! The Pen for the bounding rect
QPen m_rectPen;
//! The current zoom value and upper/lower limit
double m_zoom, m_zoomMin, m_zoomMax;
//! Pointer to labels for displaying current mouse coordinates
QLabel *m_labelCoordsX, *m_labelCoordsY, *m_labelZoom;
//! The current DrawMode
DrawMode m_drawMode;
//! If shift or Alt is pressed, modify some drawing functions
bool m_shiftPressed;
bool m_altPressed;
//! If the scene manipulates the data, do not update the GraphicsViews
bool m_blockUpdates;
//! The position of the mouse-pointer at the last click
QPointF m_mousePos;
//!
QPointF m_lastMousePos;
//!
QPointF m_startPos;
}; // class SymbolEditScene
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,236 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <LtsWidgets/lts_dialog.h>
#include <NGLLogger/INGLLogger.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Viewer/SituationMap/SymbologyXML/symbol_types.h>
#include <LtsSession/lts_session.h>
class QGraphicsScene;
class QComboBox;
namespace Ui { class SymbolEditor; }
namespace FileManagement { class ForeignGuiInterface; }
namespace SymbologyXML { class Symbol; class Primitive;}
namespace AdvancedSymbology
{
class SymbolEditorPrivate;
class SymbolEditor final : public LtsWidgets::LtsDialog
{
Q_OBJECT
public:
explicit SymbolEditor(LtsSession::LtsSession *session, QWidget *parent = nullptr);
~SymbolEditor();
bool init(const std::shared_ptr<FileManagement::Interface::Ftc> &flmFtc,
const std::shared_ptr<FileManagement::Interface::Dtc> &flmDtc,
const std::shared_ptr<FileManagement::ForeignGuiInterface> &flmGui,
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
bool asApp = false);
void keyPressEvent(QKeyEvent *keyEvent) override final;
void retranslate() override final;
bool apply() override final;
bool writeFile(bool saveAsNew);
enum e_category
{
CATEGORY_UNDEFINED = 0,
CATEGORY_HEADQUARTER,
CATEGORY_DIMENSION,
CATEGORY_AFFILIATION,
CATEGORY_BCDAB,
CATEGORY_COMMANDLEVEL,
CATEGORY_MOBILITY,
CATEGORY_BRANCH,
CATEGORY_ICON_TYPE
};
enum t_editMode
{
EDIT_NONE,
EDIT_PICK,
EDIT_MOVE,
EDIT_ROTATE,
EDIT_SCALE,
EDIT_COPY,
EDIT_PASTE,
EDIT_DELETE,
EDIT_EDIT
};
public slots:
void movePrimitive(QPointF diff);
bool createNewSymbol(const QString &symbolname);
void setChanged(bool changed);
void updateGraphicViews(bool editview = true, bool preview = true);
void reset();
void slotSaveAs();
void slotSave();
void slotSaveFinished();
void slotImportTemplate();
signals:
void documentChanged(bool changed);
void symbolSaved(bool saveToLib, bool saveToCurrent, bool saveToAll);
void canceled();
void helpRequested();
void invokeHelp(const QString &context);
void saveFinished();
private slots:
void transformSelection(int key, Qt::KeyboardModifiers modifiers);
void onToolButtonSelectClicked();
void onToolButtonRotateClicked();
void onToolButtonScaleClicked();
void onToolButtonDeleteClicked();
void onToolButtonClearClicked();
void onToolButtonUndoClicked();
void onToolButtonCopyClicked();
void onToolButtonPasteClicked();
void onToolButtonEllipseClicked();
void onToolButtonLineClicked();
void onToolButtonPolylineClicked();
void onToolButtonPolygonClicked();
void onToolButtonRectClicked();
void onToolButtonTextClicked();
void onPushButtonFillColorClicked();
void onComboBoxDimenCurrentIndexChanged(int index);
void onComboBoxAffilCurrentIndexChanged(int index);
void onComboBoxBCDABCurrentIndexChanged(int index);
void onComboBoxHeadquarterCurrentIndexChanged(int index);
void onComboBoxCommandLevelCurrentIndexChanged(int index);
void onComboBoxMobCurrentIndexChanged(int index);
void onComboBoxVehicleCurrentIndexChanged(int index);
void onComboBoxIntrinsicMobCurrentIndexChanged(int index);
void onComboBoxIntrinsicMob2CurrentIndexChanged(int index);
void onComboBoxArmingCurrentIndexChanged(int index);
void onListViewMiscItemSelectionChanged();
void onCheckBoxVehicleStateChanged(int state);
void onCheckBoxArmingStateChanged(int state);
void onCheckBoxMainStateChanged(int state);
void onComboBoxSector1CurrentIndexChanged(int index);
void onComboBoxSectorMainCurrentIndexChanged(int index);
void onListViewSectorMainItemSelectionChanged();
void onComboBoxSector2CurrentIndexChanged(int index);
void help_on_ComboBoxIndexChanged(QComboBox *comboBox,
int index, const QMap<int, QString> &contv,
SymbologyXML::SymbolTypes::t_icon_type iconType,
SymbologyXML::SymbolTypes::t_sector_position pos,
SymbologyXML::SymbolTypes::t_sector_rectpos rectpos = SymbologyXML::SymbolTypes::SECTOR_RECTPOS_DEFAULT);
void onComboBoxAlign1CurrentIndexChanged(int index);
void onComboBoxAlign2CurrentIndexChanged(int index);
void onComboBoxAlign3CurrentIndexChanged(int index);
void onComboBoxColorCurrentIndexChanged(int index);
void onComboBoxLineStyleCurrentIndexChanged(int index);
void onLineEdit1TextChanged(const QString &text);
void onLineEdit2TextChanged(const QString &text);
void onLineEdit3TextChanged(const QString &text);
void onListViewTruppengattungItemSelectionChanged();
void onCheckBoxBackgroundStateChanged(int state);
void onCheckBoxCopyValuesStateChanged(int state);
void onCheckBoxFillStateChanged(int state);
void onCheckBoxPlannedStateChanged(int state);
void onCheckBoxDrawAreaStateChanged(int state);
void onSpinBoxRasterValueChanged(double d);
void onSpinBoxLineWidthValueChanged(double d);
void onSpinBoxScaleValueChanged(double d);
void onSliderTransparencyValueChanged(int value);
void setZoom(double zoom);
void addItem(SymbologyXML::Primitive *prim);
void selectionChanged();
private:
void resetGUI();
void updateGUI();
void updateSymbolAttributesWidgets();
void updateTextProperties();
void resetToolButtonGroupState();
void pushUndo();
void popUndo();
void clearUndo();
void restoreSelection(SymbologyXML::Primitive *prim);
void copyFromSelectedPrimitive();
void enableSelectMove(bool enable);
void setPushButtonFillColorBackground(QColor color);
QIcon getIcon(e_category category, SymbologyXML::SymbolTypes::t_icon_type iconType,
int iconId, QSize iconSize);
int getFrameSymbolID(SymbologyXML::SymbolTypes::t_dimen dimen,
SymbologyXML::SymbolTypes::t_affil affil);
void fillListWidget(const QMap<int, QString> &container, QWidget *widget,
e_category category, SymbologyXML::SymbolTypes::t_icon_type iconType,
bool withIcons = true, bool sort = true);
void widgetInsertItem(QWidget *widget, int index, const QString &text, int key,
e_category category, SymbologyXML::SymbolTypes::t_icon_type iconType,
bool withIcons);
void drawSymbol(const SymbologyXML::Symbol *symbol, QGraphicsScene *scene,
const QColor &color, const QColor &fillColor,
double z, bool isAttrib = false, bool updateMap = false, bool drawBoundRect = false);
void drawSymbolPrimitive(SymbologyXML::Primitive *primitive, QGraphicsScene *scene,
const QColor &color, const QColor &fillColor,
double z, bool isAttrib = false, bool drawBoundRect = false);
void copyElementsFromSymbol(const SymbologyXML::Symbol &tmpSymbol) const;
Ui::SymbolEditor *m_ui;
SymbolEditorPrivate *m_internal;
LtsSession::LtsSession *m_session;
NGL::INGLLogger &m_logger;
};
}
@@ -0,0 +1,125 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2016-11-02
*/
#include "asb_symbol_editor_gui_plugin.h"
#include "asb_symbol_editor.h"
#include <LtsWidgets/lts_splash.h>
#include <Viewer/SituationMap/Symbology/symbol_dictionary.h>
#include <LtsSession/lts_session.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <QTimer>
namespace AdvancedSymbology
{
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("SymbolEditor"))
{}
QVector<LtsWidgets::PluginData> InterfaceImpl::getActions()
{
QVector<LtsWidgets::PluginData> ret;
m_flmDtc->enableFileContent();
m_flmDtc->enableFolder();
m_flmFtc->enableFileContentModify();
LtsWidgets::PluginData plData;
plData.menuGroup = menuGroup();
plData.menuText = tr("Symbol Editor");
plData.identifier = QLatin1String("AsbSymEditDialog");
plData.menuIcon = QIcon(QLatin1String("icon:draw_symbol.svg"));
plData.exercisePart = LtsWidgets::ExercisePart::eSpecial;
//as mainFlag
if (getFlags().testFlag(LtsAppDescriptor::PluginInfo::Flag::MAIN))
{
plData.layoutArea = LtsWidgets::LayoutArea::eMainTab;
plData.createInstant = LtsWidgets::CreateInstantType::CreateInstantAndDiscardAction;
plData.createWidgetFunc = [this](QWidget * parent)
{
return LtsWidgets::initDialog(new SymbolEditor(m_session, parent),
m_flmFtc, m_flmDtc, m_flmGui, m_ppmDtc, true);
};
}
else
{
plData.layoutArea = LtsWidgets::LayoutArea::eDialogTab;
plData.createWidgetFunc = [this](QWidget * parent)
{
return LtsWidgets::initDialog(new SymbolEditor(m_session, parent),
m_flmFtc, m_flmDtc, m_flmGui, m_ppmDtc, false);
};
}
ret.append(plData);
return ret;
}
/*
void InterfaceImpl::init()
{
LtsWidgets::Splash::getInstance()->setMessage(tr("Loading Esri dictionary..."));
connect(this, &InterfaceImpl::signalInitDone,
m_session, &LtsSession::LtsSession::slotPluginInitDone,
static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
if (LtsSession::LtsSession::s_valgrind)
{
qWarning() << "AES: skipped loading esri symbology dictionary";
emit signalInitDone();
return;
}
AdvancedSymbology::SymbolDictionary &dict =
AdvancedSymbology::SymbolDictionary::dictionary(AdvancedSymbology::SymbolDictionary::defaultSymbologyType());
dict.load();
if (dict.isLoaded())
{
emit signalInitDone();
return;
}
QTimer::singleShot(250, this, &InterfaceImpl::init); // look again if not loaded yet
}
*/
bool InterfaceImpl::fetchInterfaces()
{
return m_session->getDtc<FileManagement::DataInterface>(m_flmDtc) &&
m_session->getFtc<FileManagement::DataInterface>(m_flmFtc) &&
m_session->getDtc<ParticipantManagement::DataInterface>(m_ppmDtc) &&
m_session->getForeignGuiInterface(m_flmGui);
}
void InterfaceImpl::clearInterfaces()
{
m_flmDtc = nullptr;
m_flmFtc = nullptr;
m_flmGui = nullptr;
m_ppmDtc = nullptr;
}
std::shared_ptr<GuiPluginBase::Interface> GuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
} // namespace AdvancedSymbology
@@ -0,0 +1,74 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/AdvancedSymbology/asb_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/FileManagement/flm_explorer_gui_plugin_interface.h>
#include <Plugins/ParticipantManagement/ppm_data_plugin_interface.h>
namespace LtsUtils
{
class RequestHelper;
}
namespace AdvancedSymbology
{
class GuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_PLUGIN_METADATA(IID "gui:3:asb.symedit")
Q_INTERFACES(GuiPluginBase::Plugin)
Q_OBJECT
public:
explicit GuiPlugin() = default;
~GuiPlugin() = default;
QString pluginName() override { return ForeignGuiInterface::pluginName(); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
return partition == IDL::PartitionType::Exercise ||
partition == IDL::PartitionType::Global ||
partition == IDL::PartitionType::Replay;
}
};
class InterfaceImpl final
: public QObject
, public ForeignGuiInterface
, public GuiPluginBase::Interface
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
QString menuGroup() const override { return tr("Advanced Symbology"); }
bool fetchInterfaces() override;
void clearInterfaces() override;
QVector<LtsWidgets::PluginData> getActions() override;
// void init() override;
signals:
void signalInitDone();
private: // methods
LtsWidgets::LtsDialog *onShowSymbolEditorDialog();
private: // attributes
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_flmFtc;
std::shared_ptr<FileManagement::ForeignGuiInterface> m_flmGui;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
};
} // namespace AdvancedSymbology
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#include "flm_reply_handler.h"
#include <LtsUtilsGuiDds/request_helper.h>
namespace AdvancedSymbology
{
FileManagementReplyHandler::FileManagementReplyHandler(LtsUtils::RequestHelper *rh, QObject *parent)
: QObject(parent)
, m_requestHelper(rh)
, m_id(-1)
{
qRegisterMetaType<Core::FunctionReply>("Core::FunctionReply");
}
void FileManagementReplyHandler::requestReply(const Core::FunctionReplyObject &replyObject)
{
m_requestHelper->requestReply(replyObject);
emit signalFileContentModifyReplyReceived();
}
void FileManagementReplyHandler::onGetFileContentDataReply(const FileManagement::GetFileContentDataReply &replyObject)
{
m_content = replyObject.content();
m_id = replyObject.id();
m_requestHelper->requestReply(replyObject);
}
}
@@ -0,0 +1,59 @@
/**
* @RDE_HEADER@
* GUI Plugin for SymbolEditor
* $Id$
* $HeadURL$
* $Author$
*
* Created by Chrsitian Roeskens, SLSE, 2017-04-12
*/
#pragma once
#include <FileManagement/flm_ftc.h>
#include <FileManagement/flm_ftc_types.h>
#include <QtCore/QObject>
namespace LtsUtils
{
class RequestHelper;
}
namespace AdvancedSymbology
{
class FileManagementReplyHandler final
: public QObject
, public FileManagement::Interface::Ftc::FileContentModifyReplyHandler
, public FileManagement::Interface::Ftc::GetFileContentDataReplyHandler
{
Q_OBJECT
public:
explicit FileManagementReplyHandler(LtsUtils::RequestHelper *rh, QObject *parent);
const std::vector<uint8_t> &getContent() const { return m_content; }
int32_t getId() const { return m_id; }
signals:
void signalFileContentModifyReplyReceived();
protected:
// file content
void onFileContentModifyReply(const Core::FunctionReplyObject &replyObject) override final { requestReply(replyObject); }
void onGetFileContentDataReply(const FileManagement::GetFileContentDataReply &replyObject) override final;
private:
void requestReply(const Core::FunctionReplyObject &replyObject);
LtsUtils::RequestHelper *m_requestHelper;
std::vector<uint8_t> m_content;
int32_t m_id;
}; // FileManagementReplyHandler
} // namespace PlanEditorPlugin
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DeleteElementsDialog</class>
<widget class="QWidget" name="DeleteElementsDialog">
<property name="windowTitle">
<string>Delete Elements</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Delete elements/attributes from Symbol</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkBoxPrims">
<property name="text">
<string>Primitives</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxPrimsSectorText">
<property name="text">
<string>PrimsSectorText</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkBoxAttributes">
<property name="text">
<string>Attributes</string>
</property>
</widget>
</item>
</layout>
</widget>
</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>
<item>
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ResizeDialog</class>
<widget class="QWidget" name="ResizeDialog">
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSlider" name="sliderHScale">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>400</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinBoxHScale">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<double>4.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSlider" name="sliderVScale">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>400</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinBoxVScale">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<double>4.000000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="2" rowspan="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QCheckBox" name="checkBoxLock">
<property name="text">
<string>lock</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Horizontal:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Vertical:</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RotateDialog</class>
<widget class="QWidget" name="RotateDialog">
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="spinBoxDegree">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::UpDownArrows</enum>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QSlider" name="sliderHDegree">
<property name="maximum">
<number>360</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>sliderHDegree</tabstop>
<tabstop>spinBoxDegree</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SaveAsSymbol</class>
<widget class="QWidget" name="SaveAsSymbol">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>506</width>
<height>76</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true"/>
</property>
<property name="toolTip">
<string/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblName">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="leName">
<property name="toolTip">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="lblNameError">
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0);</string>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SelectTextDialog</class>
<widget class="QWidget" name="SelectTextDialog">
<property name="windowTitle">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Zeile 1:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit1"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Zeile 2:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit2"/>
</item>
</layout>
</item>
<item>
<widget class="LtsWidgets::LtsDialogButtonBox" name="buttonBox"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LtsWidgets::LtsDialogButtonBox</class>
<extends>QWidget</extends>
<header>LtsWidgets/lts_dialog_button_box.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>lineEdit1</tabstop>
<tabstop>lineEdit2</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because it is too large. Load diff
+54
View File
@@ -0,0 +1,54 @@
/*
*/
#include <cstdlib>
#include <getopt.h>
#include <string>
#include <nglapplication/nglapplication.h>
#include <QString>
#include <QDir>
#include "symboleditor.h"
#include "nglsettings.h"
#include <LtsPluginManager/lts_plugin_loader.h>
#include <PluginInterfaces/style_plugin_interface.h>
#include <PluginInterfaces/project_plugin_interface.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
int main(int argc, char *argv[])
{
NGLApplication app(argc, argv);
app.createLogger("SymbolApp");
QCoreApplication::addLibraryPath(QString::fromLocal8Bit(qgetenv("GFS_PATH")) + QLatin1Literal("/lib"));
// und auch in ../lib
QCoreApplication::addLibraryPath(QCoreApplication::applicationDirPath() + QLatin1Literal("/../lib"));
// QString ini = QString::fromStdString(qgetenv("GFS_PATH").toStdString()) + QLatin1Literal("/gfs.cfg");
// .. to keep some compatibility to old resource structure TODO: rm !
LtsPluginManager::LtsPluginLoader *pluginLoader = LtsPluginManager::LtsPluginLoader::getInstance();
pluginLoader->loadPlugins(LtsPluginManager::PluginType::STYLE, nullptr, QStringList() << QStringLiteral("rde.light"));
pluginLoader->loadPlugins(LtsPluginManager::PluginType::PROJECT, nullptr, QStringList() << QStringLiteral("legatus"));
QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/style/icons/")));
QDir::setSearchPaths(QLatin1String("icon"), QStringList(QLatin1String(":/style/"))); // FIXME: does qt check for recursion ??
STARTUP_LOG(app.baseLogger());
SymbolEditor *edit = new SymbolEditor(QString(), QString(), QString(), false);
if (!edit)
return -1;
edit->show();
int result = app.exec();
delete edit;
SHUTDOWN_LOG(app.baseLogger());
return result;
} // int main(int argc, char *argv[])
@@ -0,0 +1,37 @@
#
# $Id$
# $HeadURL$
# $Author$
#
# Created by Hannes Baeuerle, SLSE, 2017-06-14
#
SET(AsbSymbolProxyGuiPlugin_SRCS
asb_symbol_proxy_gui_plugin.h
asb_symbol_proxy_gui_plugin.cpp
asb_flm_subscriber.h
asb_flm_subscriber.cpp
flm_symbol_proxy.h
flm_symbol_proxy.cpp
)
NGL_WRAP_UI(AsbSymbolProxyGuiPlugin_SRCS
)
NGL_ADD_LIBRARY(WS AsbSymbolProxyGuiPlugin MODULE ${AsbSymbolProxyGuiPlugin_SRCS})
NGL_TARGET_LINK_LIBRARIES(AsbSymbolProxyGuiPlugin
AsbSymbolProxyGuiPluginInterface
NGLLogger
Qt5::Svg
Qt5::Xml
SituationMapGuiPluginInterface
LtsSession
LtsSessionData
FlmDataPluginInterface
OpmDataPluginInterface
advancedSymbology
)
NGL_INSTALL_TARGET(AsbSymbolProxyGuiPlugin)
@@ -0,0 +1,747 @@
/**
* @RDE_HEADER@
* Subscribe to file management service
* $Id$
* $HeadURL$
* $Author$
*
* Created by Norbert Thoden, NLE, 2019-04-15
*/
#include "asb_flm_subscriber.h"
#include <LtsUtilsCore/dds_vector.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <Symbology/symbol_dictionary.h>
#include <Symbology/sidc_codec.h>
#include "flm_symbol_proxy.h"
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
// Qt
#include <QPointer>
#include <QSet>
#include <QSvgRenderer>
#include <QImage>
#include <QPainter>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDomDocument>
#include <QTimer>
namespace AdvancedSymbology
{
uint qHash(SymbologyType type)
{
return static_cast<uint>(type);
}
struct FileContentStruct
{
enum SymbolType { UnsupportedSymbol, EtsSymbol, XmlSymbol };
enum ReplyState { Undefined, Requested, RequestFailure, ReplyReceived, ReplySuccess, ReplyFailure };
QString name;
SymbolType type{UnsupportedSymbol};
QString operatorName;
int64_t lastModified{0};
QStringList usrTags;
QColor colorTobeReplaced;
struct Monitoring
{
qint64 requestTime{-1}; // sec
int retryCnt{0};
ReplyState replyState{Undefined};
int replyContentSize{-1};
};
mutable Monitoring monitoring;
};
qint64 getRequestTime()
{
return time(nullptr);
}
QString toString(FileContentStruct::ReplyState rs)
{
switch (rs)
{
case FileContentStruct::Undefined:
return QStringLiteral("Undefined");
case FileContentStruct::Requested:
return QStringLiteral("Requested");
case FileContentStruct::RequestFailure:
return QStringLiteral("RequestFailure");
case FileContentStruct::ReplyReceived:
return QStringLiteral("ReplyReceived");
case FileContentStruct::ReplySuccess:
return QStringLiteral("ReplySuccess");
case FileContentStruct::ReplyFailure:
return QStringLiteral("ReplyFailure");
}
return QStringLiteral("UnknownReplyState");
}
//------------------------------------------------------------------------------
struct FlmSubscriber::Private
{
QHash<int32_t, FileContentStruct> m_fileContentMap; // fileContentId -> name
QTimer *m_reFetchTimer{nullptr};
FlmSymbolProxy m_symbolProxy;
QSet<SymbologyType> m_symbolDictionaryToUpdate;
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_flmFtc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
static long m_counter;
};
long FlmSubscriber::Private::m_counter = 0;
FlmSubscriber::FlmSubscriber(const std::shared_ptr<FileManagement::Interface::Dtc> &flmDtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &flmFtc,
const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc)
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("AdvSymbology.FlmSubscriber"))
, d(new Private())
{
INFO_LOG(m_logger) << LOGFUNCTION << " m_counter =" << ++d->m_counter;
d->m_flmDtc = flmDtc;
d->m_flmFtc = flmFtc;
d->m_opmDtc = opmDtc;
d->m_reFetchTimer = new QTimer(this);
d->m_reFetchTimer->setInterval(10000);
connect(d->m_reFetchTimer, &QTimer::timeout,
this, &FlmSubscriber::checkForReFetching);
// To enable QueuedConnection:
qRegisterMetaType<FileManagement::FileContent>("FileManagement::FileContent");
qRegisterMetaType<DataModification>("DataModification");
}
FlmSubscriber::~FlmSubscriber()
{
INFO_LOG(m_logger) << LOGFUNCTION << " m_counter =" << d->m_counter--;
if (d->m_reFetchTimer)
d->m_reFetchTimer->stop();
delete d;
}
bool FlmSubscriber::createFlmSymbolProxy(int type_placeholder)
{
Q_UNUSED(type_placeholder);
if (!d->m_flmDtc || !d->m_flmFtc)
return false;
d->m_flmDtc->enableFileContent();
d->m_flmFtc->enableGetFileContentData();
//
// 1 connect changed signals:
//
// avoid multiple connect
connect(d->m_flmDtc.get(), &FileManagement::Interface::Dtc::fileContentChanged,
this, &FlmSubscriber::onFileContentChanged, Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection));
//
// 2. retrieve FileContent
//
const auto cb = [this](const FileManagement::FileContent & data) -> void
{
updateFileContentMap(data);
};
if (!d->m_flmDtc->fileContents(cb))
ERROR_LOG(m_logger) << LOGFUNCTION << " Error performing fileContents";
INFO_LOG(m_logger) << LOGFUNCTION << " m_fileContentMap.size()=" << d->m_fileContentMap.size() ;
//
// now we have all FileContentIds: -> retrieve contentDATA (svg data)
//
for (auto it = d->m_fileContentMap.cbegin(); it != d->m_fileContentMap.cend(); ++it)
{
const int fileContentId = it.key();
FileManagement::GetFileContentDataRequest request(fileContentId);
const FileContentStruct &fcsRef = it.value(); // monitoring is mutable
#ifdef LTS_DEBUG
//#define SKIP_SOME_TO_TEST_REFETCHING
#ifdef SKIP_SOME_TO_TEST_REFETCHING
if (fileContentId>=98)
request.fileContentId(-1);
#endif // SKIP_SOME_TO_TEST_REFETCHING
#endif // LTS_DEBUG
if (d->m_flmFtc->getFileContentDataRequest(request, this))
{
fcsRef.monitoring.requestTime = getRequestTime();
fcsRef.monitoring.replyState = FileContentStruct::Requested;
} else {
fcsRef.monitoring.replyState = FileContentStruct::RequestFailure;
ERROR_LOG(m_logger) << "Error requesting FileContentData, fileContentId=" << fileContentId;
}
} // while
//
// start reFetchTimer using rand to avoid heavy load at server side:
//
const int randomOffset = rand() % 10 + 5; // 5 .. 15
QTimer::singleShot(randomOffset, this , [this]()
{
DEBUG_LOG(m_logger) << "start ReFetchingTimer";
d->m_reFetchTimer->start(); // -> checkForReFetching
});
return true;
}
void FlmSubscriber::onGetFileContentDataReply(const FileManagement::GetFileContentDataReply &reply)
{
const int32_t fileContentId = reply.id();
TRACE_LOG(m_logger) << LOGFUNCTION << " START, " << fileContentId;
if (!d->m_fileContentMap.contains(fileContentId))
{
ERROR_LOG(m_logger) << LOGFUNCTION << " fileContentId unknown, fileContentId=" << fileContentId;
return;
}
const FileContentStruct &fcData = d->m_fileContentMap[fileContentId];
fcData.monitoring.replyState = FileContentStruct::ReplyReceived;
const QString &name = fcData.name;
const QString &operatorName = fcData.operatorName;
const qint64 lastModified = fcData.lastModified;
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " fileContentId=" << fileContentId
<< " name=" << name
<< " operatorName=" << operatorName
<< " lastModified=" << lastModified
<< " #bytes =" << reply.content().size();
fcData.monitoring.replyContentSize = reply.content().size(); // update ReplayState
switch (fcData.type)
{
case FileContentStruct::SymbolType::EtsSymbol:
{
QImage image;
if (!svgToImage(QByteArray::fromRawData(reinterpret_cast<const char*>(&reply.content().at(0)), reply.content().size()), image))
{
ERROR_LOG(m_logger) << LOGFUNCTION << " svgToImage failed, fileContentId=" << fileContentId;
fcData.monitoring.replyState = FileContentStruct::ReplyFailure; // update ReplayState
return;
}
// now we have metaData (fileContentId, name) and data (content/svg)
// transfer to symbolProxy:
FlmSymbolProxy::SymbolData symbolData(name, image, fcData.colorTobeReplaced);
symbolData.setUsrTags(fcData.usrTags);
// store:
d->m_symbolProxy.setSymbol(fileContentId, symbolData);
fcData.monitoring.replyState = FileContentStruct::ReplySuccess; // update ReplayState
break;
}
case FileContentStruct::SymbolType::XmlSymbol:
{
FlmSymbolProxy::SymbolData symbolData(name, operatorName, lastModified, LtsUtils::toQByteArray(reply.content()));
if (symbolData.isXmlSymbol())
{
symbolData.setUsrTags(fcData.usrTags);
// store it
d->m_symbolProxy.setSymbol(fileContentId, symbolData);
fcData.monitoring.replyState = FileContentStruct::ReplySuccess; // update ReplayState
}
else
{
ERROR_LOG(m_logger) << LOGFUNCTION << " xmlSymbolContent is empty, fileContentId=" << fileContentId;
fcData.monitoring.replyState = FileContentStruct::ReplyFailure; // update ReplayState
}
break;
}
case FileContentStruct::SymbolType::UnsupportedSymbol:
{
ERROR_LOG(m_logger) << LOGFUNCTION << " unsupported symbol found, fileContentId=" << fileContentId;
fcData.monitoring.replyState = FileContentStruct::ReplyFailure; // update ReplayState
break;
}
} // switch
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool FlmSubscriber::svgToImage(const QByteArray &svgByteArray, QImage &imageOut)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
// load QByteArray
QSvgRenderer svgRenderer;
if (!svgRenderer.load(svgByteArray))
{
ERROR_LOG(m_logger) << LOGFUNCTION << " svgRenderer.load failed";
return false;
}
// prepare Image:
int size = 200; // pixel
imageOut = QImage(size, size, QImage::Format_ARGB32);
imageOut.fill(Qt::transparent);
// render
QPainter painter(&imageOut);
svgRenderer.render(&painter);
painter.end();
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
QString FlmSubscriber::operatorName(int operatorId)
{
if (d->m_opmDtc)
return QString::fromStdString(d->m_opmDtc->user(operatorId).name());
return QStringLiteral("unknown user<%1>").arg(operatorId);
}
void FlmSubscriber::checkForReFetching()
{
// use own logging channel:
LOGGER_T logger = NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("AdvSymbology.FlmSubscriber.ReFetch");
DEBUG_LOG(logger) << "********** checkForReFetching START, size=" << d->m_fileContentMap.size();
int i{0};
int unfinished{0};
int reFetchCounter{0};
static int s_reFetchCounter = 0;
const qint64 curTime = time(nullptr);
for (auto it = d->m_fileContentMap.cbegin(); it != d->m_fileContentMap.cend(); ++it)
{
const FileContentStruct &fcs = it.value();
qint64 ageSec = curTime - fcs.monitoring.requestTime;
DEBUG_LOG(logger) << "***** dump i=" << ++i
<< ", fileContentId=" << it.key()
<< ", retryCnt=" << fcs.monitoring.retryCnt
<< ", ageSec = " << ageSec
<< ", replyState=" << toString(fcs.monitoring.replyState)
<< ", replyContentSize=" << fcs.monitoring.replyContentSize
<< ", name='" << fcs.name << "'"
;
if (fcs.monitoring.replyState != FileContentStruct::ReplySuccess)
{
++unfinished;
if ((ageSec > 30) && (fcs.monitoring.retryCnt < 3))
{
// retry / reFetch
const int32_t fileContentId = it.key();
INFO_LOG(logger) << "***** reFetch *** :"
<< " ageSec = " << ageSec
<< ", fileContentId=" << fileContentId
<< ", replyState=" << toString(fcs.monitoring.replyState)
<< ", replyContentSize=" << fcs.monitoring.replyContentSize
<< ", name='" << fcs.name << "'"
;
FileManagement::GetFileContentDataRequest request(fileContentId);
if (!d->m_flmFtc->getFileContentDataRequest(request, this)) // -> onGetFileContentDataReply -> ... -> setSymbol
ERROR_LOG(logger) << LOGFUNCTION << "Error reading FileContentData, fileContentId=" << fileContentId;
fcs.monitoring.replyState = FileContentStruct::Requested;
fcs.monitoring.requestTime = getRequestTime();
++fcs.monitoring.retryCnt;
// Server-Restart: Topic is removed and therefore the fcs is also removed from container -> retryCnt is fine
++reFetchCounter;
++s_reFetchCounter;
}
}
}
INFO_LOG(logger) << "***** checkForReFetching END"
<< ", size=" << d->m_fileContentMap.size()
<< ", unfinished=" << unfinished
<< ", reFetchCounter=" << reFetchCounter
<< ", s_reFetchCounter=" << s_reFetchCounter;
}
void FlmSubscriber::onFileContentChanged(const FileManagement::FileContent &data, DataModification modType)
{
TRACE_LOG(m_logger) << LOGFUNCTION
<< " data.id=" << data.id()
<< " data.fileStatus=" << data.fileStatus().underlying()
<< " modType=" << modType
<< " data.name='" << data.name().c_str() << "'";
if (!d->m_flmFtc)
return;
if (data.isDeleted())
return;
// check fileType
if (data.fileType().underlying() != FileManagement::FileType::OperatorDefinedSymbol)
return;
// check fileStatus in relation with modType:
// (if modified to FileStatus::Deleted process as DataModification::eRemoved)
if (data.fileStatus().underlying() == FileManagement::FileStatus::Deleted)
{
switch (modType)
{
case DataModification::eAdded:
return;
case DataModification::eModified:
modType = DataModification::eRemoved;
break;
case DataModification::eRemoved:
// empty
break;
} // switch
}
//
// no check against ExerciseId, because we assume that all symbols are 'global'
//
const int32_t fileContentId = data.id();
switch (modType)
{
case DataModification::eAdded:
case DataModification::eModified:
{
// since it´s caused by an update/changed signal,
// we have to update our own map, (to let onGetFileContentDataReply work)
updateFileContentMap(data);
FileManagement::GetFileContentDataRequest request(fileContentId);
if (!d->m_flmFtc->getFileContentDataRequest(request, this)) // -> onGetFileContentDataReply -> ... -> setSymbol
ERROR_LOG(m_logger) << LOGFUNCTION << "Error reading FileContentData, fileContentId=" << fileContentId;
break;
}
case DataModification::eRemoved:
{
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " modType=" << modType
<< " fileContentId=" << fileContentId
<< " fileContentName=" << data.name();
// update own container:
d->m_fileContentMap.remove(fileContentId);
// remove:
if (!d->m_symbolProxy.removeSymbol(fileContentId))
ERROR_LOG(m_logger) << LOGFUNCTION << " removeSymbol failed"
<< " fileContentId=" << fileContentId
<< " fileContentName='" << data.name() << "'"
<< " contains=" << d->m_fileContentMap.contains(fileContentId);
break;
}
} // switch
} // void FlmSubscriber::onFileContentChanged(const FileManagement::FileContent &data, DataModification modType)
void FlmSubscriber::updateFileContentMap(const FileManagement::FileContent &data)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " d->m_fileContentMap.size()=" << d->m_fileContentMap.size()
<< " fileContentId=" << data.id()
<< " data.isDeleted()=" <<data.isDeleted()
<< " data.fileStatus().underlying()=" << data.fileStatus().underlying()
<< " data.name='" <<QString::fromStdString(data.name()) << "'";
if (data.isDeleted())
return;
if (data.fileStatus().underlying() == FileManagement::FileStatus::Deleted)
return;
if (data.fileType() != FileManagement::FileType::OperatorDefinedSymbol)
return;
// check exerciseId in future ???
const int32_t fileContentId = data.id();
FileContentStruct fcData;
fcData.name = QString::fromStdString(data.name());
fcData.type = FileContentStruct::SymbolType::UnsupportedSymbol;
fcData.operatorName = operatorName(data.operatorId());
fcData.lastModified = data.lastModified();
fcData.usrTags << QStringLiteral("file-id=%1").arg(fileContentId);
fcData.usrTags << QStringLiteral("exercise-id=%1").arg(data.exerciseId().is_set() ? data.exerciseId().get() : -1);
fcData.usrTags << fcData.operatorName;
// optional properties (containing 'imageFormat', 'partyColor')
if (data.properties().size() != 0)
{
const QByteArray attributesJson(QByteArray::fromRawData(data.properties().c_str(), data.properties().size()));
QJsonParseError parseError;
QJsonDocument jDoc(QJsonDocument::fromJson(attributesJson, &parseError));
if (parseError.error == QJsonParseError::NoError)
{
const QJsonObject &obj = jDoc.object();
const QLatin1String imageFormatKey("imageFormat");
if (obj.contains(imageFormatKey))
{
const QString &imageFormatValue = obj[imageFormatKey].toString();
if (QLatin1String("xml") == imageFormatValue)
fcData.type = FileContentStruct::SymbolType::XmlSymbol;
if (QLatin1String("ets") == imageFormatValue)
fcData.type = FileContentStruct::SymbolType::EtsSymbol;
}
else
fcData.type = FileContentStruct::SymbolType::EtsSymbol;
if (FileContentStruct::SymbolType::EtsSymbol == fcData.type)
{
// partyColor
const QLatin1String partyColorStr("partyColor");
if (obj.contains(partyColorStr))
{
QJsonObject partyColor = obj[partyColorStr].toObject();
if (partyColor.size() == 3) // r, g, b
{
// update map:
fcData.colorTobeReplaced.setRgb(
partyColor[QLatin1String("r")].toInt(),
partyColor[QLatin1String("g")].toInt(),
partyColor[QLatin1String("b")].toInt());
} // if (partyColor.size() == 3)
} // if (obj.contains(partyColorStr))
} // if (FileContentStruct::SymbolType::EtsSymbol == fcRef.type)
} else {
ERROR_LOG(m_logger) << LOGFUNCTION
<< " QJsonParseError->errorString: '" << parseError.errorString() << "'"
<< ", offset: " << parseError.offset;
} // if (parseError.error == QJsonParseError::NoError)
} // if (data.attributes().is_set())
d->m_fileContentMap[fileContentId] = fcData;
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
<< " d->m_fileContentMap.size()=" << d->m_fileContentMap.size()
<< " fileContentId=" << data.id()
<< " data.isDeleted()=" <<data.isDeleted()
<< " data.fileStatus().underlying()=" << data.fileStatus().underlying()
<< " data.name='" <<QString::fromStdString(data.name()) << "'";
} // void FlmSubscriber::updateFileContentMap(const FileManagement::FileContent &data)
void FlmSubscriber::onLocalSymbolProxyEtsSymbolAdded(qint32 fileContentId,
const QString &name,
const QImage &image,
const QColor &colorToBeReplaced,
const QStringList &usrTags)
{
Q_UNUSED(fileContentId);
for (const SymbologyType symbologyType : qAsConst(d->m_symbolDictionaryToUpdate))
{
AdvancedSymbology::SymbolDictionary &dict =
AdvancedSymbology::SymbolDictionary::dictionary(symbologyType);
this->setEtsSymbolToDict(dict, fileContentId, name, image, colorToBeReplaced, usrTags);
}
}
void FlmSubscriber::onLocalSymbolProxyEtsSymbolRemoved(qint32 fileContentId, const QString &name)
{
for (const SymbologyType &symbologyType : qAsConst(d->m_symbolDictionaryToUpdate))
{
AdvancedSymbology::SymbolDictionary &dict =
AdvancedSymbology::SymbolDictionary::dictionary(symbologyType);
INFO_LOG(m_logger) << LOGFUNCTION << " dict.removeEtsSymbol:"
<< " symbologyType='" << (int)symbologyType << "'"
<< ", name='" << name << "'"
<< ", fileContentId=" << fileContentId;
dict.removeEtsSymbol(fileContentId);
dict.removeEtsSymbol(name);
}
}
void FlmSubscriber::onLocalSymbolProxyXmlSymbolAdded(qint32 fileContentId,
const QString &operatorName,
qint64 lastModified,
const QString &name,
const QString &xmlContent,
const QStringList &usrTags)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " fileContentId=" << fileContentId
<< " name='" << name << "'";
if (!xmlContent.isEmpty())
{
for (const SymbologyType &symbologyType : qAsConst(d->m_symbolDictionaryToUpdate))
{
AdvancedSymbology::SymbolDictionary &dict =
AdvancedSymbology::SymbolDictionary::dictionary(symbologyType);
if (!this->setXmlSymbolToDict(dict, fileContentId, operatorName, lastModified, name, xmlContent, usrTags))
ERROR_LOG(m_logger) << LOGFUNCTION << " dict.setXmlSymbolToDict failed"
<< ", symbologyType='" << (int)symbologyType << "'"
<< ", name='" << name << "'";
}
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END"
<< " fileContentId=" << fileContentId
<< " name='" << name << "'";
}
void FlmSubscriber::onLocalSymbolProxyXmlSymbolRemoved(qint32 fileContentId)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START" << " fileContentId=" << fileContentId;
for (const SymbologyType &symbologyType : qAsConst(d->m_symbolDictionaryToUpdate))
{
AdvancedSymbology::SymbolDictionary &dict =
AdvancedSymbology::SymbolDictionary::dictionary(symbologyType);
DEBUG_LOG(m_logger) << LOGFUNCTION << " dict.removeXmlSymbol:"
<< " symbologyType='" << symbologyType << "'"
<< ", fileContentId=" << fileContentId;
const QString &skey = QString::number(fileContentId);
const QString &sidc = SidcCodec::encodeCivilXml(skey);
dict.removeXmlSymbol(sidc);
dict.removeXmlSymbol(fileContentId);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END" << " fileContentId=" << fileContentId;
}
//
// Proxy
//
bool FlmSubscriber::connectFlmSymbolProxy(int type_placeholder, SymbologyType symbologyType)
{
Q_UNUSED(type_placeholder);
TRACE_LOG(m_logger) << LOGFUNCTION << " m_fileContentMap.size()=" << d->m_fileContentMap.size() ;
d->m_symbolDictionaryToUpdate.insert(symbologyType);
// ETS
// connect to some signals like added, modified, removed:
connect(&d->m_symbolProxy, &FlmSymbolProxy::etsSymbolAdded,
this, &FlmSubscriber::onLocalSymbolProxyEtsSymbolAdded, Qt::QueuedConnection);
connect(&d->m_symbolProxy, &FlmSymbolProxy::etsSymbolRemoved,
this, &FlmSubscriber::onLocalSymbolProxyEtsSymbolRemoved, Qt::QueuedConnection);
// XML
// connect to some signals like added, modified, removed:
connect(&d->m_symbolProxy, &FlmSymbolProxy::xmlSymbolAdded,
this, &FlmSubscriber::onLocalSymbolProxyXmlSymbolAdded, Qt::QueuedConnection);
connect(&d->m_symbolProxy, &FlmSymbolProxy::xmlSymbolRemoved,
this, &FlmSubscriber::onLocalSymbolProxyXmlSymbolRemoved, Qt::QueuedConnection);
// continue?
if (d->m_symbolProxy.isEmpty())
return true;
AdvancedSymbology::SymbolDictionary &dict =
AdvancedSymbology::SymbolDictionary::dictionary(symbologyType);
// Don´t use QSignalBlocker here!!!
dict.blockSignals(true); // to make sure that set{Ets,Xml}SymbolToDict will NOT emit huge number of 'symbolAdded'
for (auto mapIt = d->m_symbolProxy.getMap().begin(); mapIt != d->m_symbolProxy.getMap().end(); ++mapIt)
{
const int fileContentId = mapIt.key();
const FlmSymbolProxy::SymbolData &symData = mapIt.value();
if (symData.isXmlSymbol())
setXmlSymbolToDict(dict, fileContentId, symData.operatorName(), symData.lastModified(), symData.name(), symData.xmlContent(), symData.usrTags());
else
setEtsSymbolToDict(dict, fileContentId, symData.name(), symData.image(), symData.colorToBeReplaced(), symData.usrTags());
}
dict.blockSignals(false);
return true;
}
bool FlmSubscriber::setEtsSymbolToDict(SymbolDictionary &dict,
qint32 fileContentId,
const QString &name,
const QImage &image,
const QColor &colorToBeReplaced,
const QStringList &usrTags)
{
// -> ETS_%1
SymbolProperties symProps;
symProps.setKey(name);
symProps.setSidc(SidcCodec::encodeCivilEts(name));
symProps.setName(name);
// symProps.setCategory(); // maybe?
symProps.setSymbolClass(QLatin1String("3")); // 18.10.2016, N.Thoden: 3 == PointSymbol (mil2525d.stylx - QuartzRelease)
symProps.setGeometryType(GeometryType::Point); // ETS-Symbols are always Points
symProps.setTags(QStringList() << name << usrTags);
symProps.setColorToBeReplaced(colorToBeReplaced);
if (!dict.setEtsSymbol(fileContentId, symProps.sidc(), symProps, image))
{
ERROR_LOG(m_logger) << LOGFUNCTION << " dict.insertExtraSymbol failed"
<< ", fileContentId=" << fileContentId << ", name='" << name << "'";
return false;
}
else
INFO_LOG(m_logger) << LOGFUNCTION << " dict.insertExtraSymbol done"
<< ", fileContentId=" << fileContentId << ", name='" << name << "'";
return true;
}
bool FlmSubscriber::setXmlSymbolToDict(SymbolDictionary &dict,
qint32 fileContentId,
const QString &operatorName,
qint64 lastModified,
const QString &name,
const QString &xmlContent,
const QStringList &usrTags)
{
SymbolProperties symProps;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ToDo add more search infos to symProps
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
symProps.setTags(QStringList() << name << usrTags);
bool success = dict.setXmlSymbol(fileContentId, name, operatorName, lastModified, xmlContent, symProps);
if (!success)
ERROR_LOG(m_logger) << LOGFUNCTION << " setXmlSymbol failed:"
<< ", file-id=" << fileContentId
<< ", filenameid='" << name << "'";
return success;
}
} // namespace AdvancedSymbology
@@ -0,0 +1,107 @@
/**
* @RDE_HEADER@
* Subscribe to file management service
* $Id$
* $HeadURL$
* $Author$
*
* Created by Norbert Thoden, NLE, 2019-04-15
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/AdvancedSymbology/asb_symbol_proxy_gui_plugin_interface.h>
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
#include <FileManagement/flm.hpp>
#include <LtsUtilsCore/data_modification_enum.h>
#include <memory>
namespace LtsUtils
{
class RequestHelper;
}
namespace AdvancedSymbology
{
class FlmSubscriber final
: public QObject
, public ForeignGuiFlmSymbolsProxyInterface
, public FileManagement::Interface::Ftc::GetFileContentDataReplyHandler
{
Q_OBJECT
public:
explicit FlmSubscriber(const std::shared_ptr<FileManagement::Interface::Dtc> &flmDtc,
const std::shared_ptr<FileManagement::Interface::Ftc> &flmFtc,
const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc);
~FlmSubscriber();
bool createFlmSymbolProxy(int type_placeholder) override; // type_placeholder: GlobalSymbols, ExerciseSymbols... to be prepared
bool connectFlmSymbolProxy(int type_placeholder, SymbologyType symbologyType) override;
private: // methods
bool setEtsSymbolToDict(SymbolDictionary &dict,
qint32 fileContentId,
const QString &name,
const QImage &image,
const QColor &colorToBeReplaced,
const QStringList &usrTags);
bool setXmlSymbolToDict(SymbolDictionary &dict,
qint32 fileContentId,
const QString &operatorName,
qint64 lastModified,
const QString &name,
const QString &xmlContent,
const QStringList &usrTags);
protected slots:
void onFileContentChanged(const FileManagement::FileContent &data, DataModification modType);
void updateFileContentMap(const FileManagement::FileContent &data);
void onLocalSymbolProxyEtsSymbolAdded(qint32 fileContentId,
const QString &name,
const QImage &image,
const QColor &colorToBeReplaced,
const QStringList &usrTags);
void onLocalSymbolProxyEtsSymbolRemoved(qint32 fileContentId, const QString &name);
void onLocalSymbolProxyXmlSymbolAdded(qint32 fileContentId,
const QString &operatorName,
qint64 lastModified,
const QString &name,
const QString &xmlContent,
const QStringList &usrTags);
void onLocalSymbolProxyXmlSymbolRemoved(qint32 fileContentId);
protected:
/**
* @brief onGetFileContentDataReply
* @param reply contains the FileContentData to be processed (Symbol as SVG/ByteArray)
*/
void onGetFileContentDataReply(const FileManagement::GetFileContentDataReply &reply) override;
bool svgToImage(const QByteArray &svgByteArray, QImage &imageOut);
QString operatorName(int operatorId);
void checkForReFetching();
private: // attributes
LOGGER_T m_logger; ///< Interface of the Logging-Facility
struct Private;
/**
* The private d->pointer to not break BC when changing internals of this class
*/
Private *d = nullptr;
};
} // namespace AdvancedSymbology
@@ -0,0 +1,149 @@
/**
* @RDE_HEADER@
* GUI proxy plugin to handle symbols via file management service
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, SLSE, 2016-11-02
*/
#include "asb_symbol_proxy_gui_plugin.h"
#include "asb_flm_subscriber.h"
#include <LtsSession/lts_session.h>
#include <NGLLogger/NGLLoggerBootstrap.h>
#include <Symbology/symbol_dictionary.h>
#include <Symbology/sidc_codec.h>
#include "flm_symbol_proxy.h"
#include <Plugins/FileManagement/flm_data_plugin_interface.h>
#include <Plugins/OperatorManagement/opm_data_plugin_interface.h>
namespace AdvancedSymbology
{
//------------------------------------------------------------------------------
std::shared_ptr<GuiPluginBase::Interface> FlmSymbolProxyGuiPlugin::createGuiInterface(LtsSession::LtsSession *session)
{
return std::make_shared<InterfaceImpl>(session);
}
//------------------------------------------------------------------------------
struct InterfaceImpl::Private
{
QSharedPointer<FlmSubscriber> getFlmSubscriber(int type_placeholder)
{
static QWeakPointer<FlmSubscriber> s_flmSubcriber;
m_flmSubscriber = s_flmSubcriber.toStrongRef();
if (!m_flmSubscriber)
{
m_flmSubscriber = QSharedPointer<FlmSubscriber> (new FlmSubscriber(m_flmDtc, m_flmFtc, m_opmDtc));
s_flmSubcriber = m_flmSubscriber.toWeakRef();
m_flmSubscriber->createFlmSymbolProxy(type_placeholder);
}
return m_flmSubscriber;
}
void clearFlmSubscriber()
{
m_flmSubscriber.clear();
}
std::shared_ptr<FileManagement::Interface::Dtc> m_flmDtc;
std::shared_ptr<FileManagement::Interface::Ftc> m_flmFtc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
private:
QSharedPointer<FlmSubscriber> m_flmSubscriber;
};
InterfaceImpl::InterfaceImpl(LtsSession::LtsSession *session)
: GuiPluginBase::Interface(session, NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("AdvSymbology.FlmSymbolProxy"))
, d(new Private())
{
// To enable QueuedConnection:
qRegisterMetaType<FileManagement::FileContent>("FileManagement::FileContent");
qRegisterMetaType<DataModification>("DataModification");
}
InterfaceImpl::~InterfaceImpl()
{
delete d;
}
bool InterfaceImpl::fetchInterfaces()
{
if (!m_session->getDtc<FileManagement::DataInterface>(d->m_flmDtc))
{
DEBUG_LOG(m_logger) << "getDtc for FileManagement::DataInterface failed.";
return false;
}
if (!m_session->getFtc<FileManagement::DataInterface>(d->m_flmFtc))
{
DEBUG_LOG(m_logger) << "getFtc for FileManagement::DataInterface failed.";
return false;
}
if (!m_session->getDtc<OperatorManagement::DataInterface>(d->m_opmDtc))
{
DEBUG_LOG(m_logger) << "getDtc for OperatorManagement::DataInterface failed.";
return false;
}
return true;
}
void InterfaceImpl::clearInterfaces()
{
d->m_flmDtc = nullptr;
d->m_flmFtc = nullptr;
d->m_opmDtc = nullptr;
// release dtc/ftc also at FlmSubscriber:
d->clearFlmSubscriber();
}
// type_placeholder: GlobalSymbols, ExerciseSymbols...
bool InterfaceImpl::createFlmSymbolProxy(int type_placeholder)
{
Q_UNUSED(type_placeholder);
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
if (!d->m_flmDtc || !d->m_flmFtc || !d->m_opmDtc)
return false;
QSharedPointer<FlmSubscriber> flmSubscriber = d->getFlmSubscriber(type_placeholder);
if (!flmSubscriber)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no FlmSubscriber";
return false;
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
bool InterfaceImpl::connectFlmSymbolProxy(int type_placeholder, SymbologyType symbologyType)
{
Q_UNUSED(type_placeholder);
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
QSharedPointer<FlmSubscriber> flmSubscriber = d->getFlmSubscriber(type_placeholder);
if (!flmSubscriber)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " no FlmSubscriber";
return false;
}
flmSubscriber->connectFlmSymbolProxy(type_placeholder, symbologyType);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
} // namespace AdvancedSymbology
@@ -0,0 +1,76 @@
/**
* @RDE_HEADER@
* GUI proxy plugin to handle symbols via file management service
* $Id$
* $HeadURL$
* $Author$
*
* Created by Hannes Baeuerle, SLSE, 2017-06-14
*/
#pragma once
#include <PluginInterfaces/gui_plugin_interface.h>
#include <Plugins/AdvancedSymbology/asb_symbol_proxy_gui_plugin_interface.h>
#include <memory>
namespace LtsUtils
{
class RequestHelper;
}
namespace AdvancedSymbology
{
class FlmSymbolProxyGuiPlugin final : public QObject, public GuiPluginBase::Plugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "gui:3:asb.flmsymbolproxy")
Q_INTERFACES(GuiPluginBase::Plugin)
public:
explicit FlmSymbolProxyGuiPlugin() = default;
~FlmSymbolProxyGuiPlugin() = default;
QString pluginName() override { return ForeignGuiFlmSymbolsProxyInterface::pluginName(); }
std::shared_ptr<GuiPluginBase::Interface> createGuiInterface(LtsSession::LtsSession *session) override;
bool availableInPartition(IDL::PartitionType partition) const override
{
Q_UNUSED(partition);
return true;
// return partition == IDL::PartitionType::Exercise ||
// partition == IDL::PartitionType::Global ||
// partition == IDL::PartitionType::Replay;
}
};
class InterfaceImpl final
: public QObject
, public ForeignGuiFlmSymbolsProxyInterface
, public GuiPluginBase::Interface
{
Q_OBJECT
public:
explicit InterfaceImpl(LtsSession::LtsSession *session);
~InterfaceImpl();
bool fetchInterfaces() override;
void clearInterfaces() override;
private: // methods
bool createFlmSymbolProxy(int type_placeholder) override; // type_placeholder: GlobalSymbols, ExerciseSymbols... to be prepared
bool connectFlmSymbolProxy(int type_placeholder, SymbologyType symbologyType) override;
protected slots:
private: // attributes
struct Private;
/**
* The private d->pointer to not break BC when changing internals of this class
*/
Private *d = nullptr;
};
} // namespace AdvancedSymbology
@@ -0,0 +1,45 @@
/**
* @RDE_HEADER@
* Preprocess symbols of Filemanagement
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "flm_symbol_proxy.h"
namespace AdvancedSymbology
{
FlmSymbolProxy::FlmSymbolProxy(QObject *parent)
: QObject(parent)
{
}
bool FlmSymbolProxy::setSymbol(int32_t fileContentId, const SymbolData &symbolData)
{
m_imageMap[fileContentId] = symbolData;
if (symbolData.isXmlSymbol())
emit xmlSymbolAdded(fileContentId, symbolData.operatorName(), symbolData.lastModified(), symbolData.name(), symbolData.xmlContent(), symbolData.usrTags());
else
emit etsSymbolAdded(fileContentId, symbolData.name(), symbolData.image(), symbolData.colorToBeReplaced(), symbolData.usrTags());
return true;
}
bool FlmSymbolProxy::removeSymbol(qint32 fileContentId)
{
SymbolData symbolDat = m_imageMap[fileContentId];
bool ret = m_imageMap.remove(fileContentId) > 0;
if (ret)
{
if (symbolDat.isXmlSymbol())
emit xmlSymbolRemoved(fileContentId);
else
emit etsSymbolRemoved(fileContentId, symbolDat.name());
}
return ret;
}
} // namespace AdvancedSymbology
@@ -0,0 +1,115 @@
/**
* @RDE_HEADER@
* Preprocess symbols of Filemanagement
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
// Own
// Qt
#include <QHash>
#include <QString>
#include <QImage>
//----------------------------------------------------------------------------
namespace AdvancedSymbology
{
class FlmSymbolProxy : public QObject
{
Q_OBJECT
public:
class SymbolData
{
public:
SymbolData() = default;
SymbolData(const QString &name, const QImage &image, const QColor &colorToBeReplaced = QColor())
: m_name(name), m_image(image), m_colorToBeReplaced(colorToBeReplaced), m_xmlContent()
{}
SymbolData(const QString &name, const QString &operatorName, qint64 lastModified, const QByteArray &xmlContent)
: m_name(name), m_operatorName(operatorName), m_lastModified(lastModified), m_image(), m_colorToBeReplaced(), m_xmlContent(QString::fromUtf8(xmlContent))
{}
QString name() const { return m_name; }
void setName(const QString &name) { m_name = name; }
QString operatorName() const { return m_operatorName; }
void setOperatorName(const QString &operatorName) { m_operatorName = operatorName; }
qint64 lastModified() const { return m_lastModified; }
void setLastModified(qint64 lastModified) { m_lastModified = lastModified; }
QImage image() const { return m_image; }
void setImage(const QImage &image) { m_image = image; if (!image.isNull()) m_xmlContent.clear(); }
QColor colorToBeReplaced() const { return m_colorToBeReplaced; }
void setColorToBeReplaced(const QColor &colorToBeReplaced) { m_colorToBeReplaced = colorToBeReplaced; }
QString xmlContent() const { return m_xmlContent; }
void setXmlContent(const QString &xmlContent) { m_xmlContent = xmlContent; }
bool isXmlSymbol() const { return (!m_xmlContent.isEmpty()); }
QStringList usrTags() const { return m_usrTags; }
void setUsrTags(const QStringList &usrTags) { m_usrTags = usrTags; }
void addUsrTag(const QString &tag) { m_usrTags << tag; }
void addUsrTag(const char *tag) { m_usrTags << QLatin1String(tag); }
void clearUsrTags() { m_usrTags.clear(); }
protected:
QString m_name; // file name of symbol from file mamangement service
QString m_operatorName;
qint64 m_lastModified = 0;
QImage m_image; // m_image is defined in case of ETS symbols
QColor m_colorToBeReplaced; // by concrete partyColor (context of ETS symbols)
QString m_xmlContent; // in case of XML symbols image is empty and the m_xmlContent holds the xml description of the symbol
QStringList m_usrTags; // List of tags to look for while searching symbols in dictionary
};
/*! \name Construction, Destruction */
//@{
explicit FlmSymbolProxy(QObject *parent = nullptr);
FlmSymbolProxy(const FlmSymbolProxy &other) = delete;
FlmSymbolProxy &operator=(const FlmSymbolProxy &other) = delete;
//@}
bool isEmpty() const { return m_imageMap.isEmpty(); }
bool containsSymbol(qint32 fileContentId) const { return m_imageMap.contains(fileContentId); }
const QHash<qint32, SymbolData> &getMap() const { return m_imageMap; }
bool setSymbol(int32_t fileContentId, const SymbolData &symbolData);
bool removeSymbol(qint32 fileContentId);
Q_SIGNALS:
void etsSymbolAdded(qint32 fileContentId, const QString &name, const QImage &image, const QColor &colorToBeReplaced, const QStringList &usrTags);
void etsSymbolRemoved(qint32 fileContentId, const QString &name);
void xmlSymbolAdded(qint32 fileContentId, const QString & operatorName, qint64 lastModified, const QString &name, const QString &xmlContent, const QStringList &usrTags);
void xmlSymbolRemoved(qint32 fileContentId);
private:
QHash<qint32, SymbolData> m_imageMap; // fileContentId -> image
};
} // namespace AdvancedSymbology
+21
View File
@@ -0,0 +1,21 @@
#
# $Id$
# $HeadURL$
# $Author$
# Created by Christian Ehrlicher, SLSE, 2017-11-01
#
SET(tmsr_SRCS
table_model_symbol_renderer_base.cpp
table_model_symbol_renderer_base.h
table_model_symbol_renderer.h
)
NGL_ADD_LIBRARY2(WS AsbHelper STATIC ${tmsr_SRCS})
NGL_TARGET_LINK_LIBRARIES(AsbHelper
PUBLIC
Qt5::Core
PRIVATE
Qt5::Gui
AsbDataPluginInterface
NGLLogger
)
@@ -0,0 +1,29 @@
/**
* @RDE_HEADER@
* Helper class template to provide symbol rendering in QAbstractItemModels
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-11-01
*/
#pragma once
#include "table_model_symbol_renderer_base.h"
namespace AdvancedSymbology
{
template <typename SUPER>
class TableModelSymbolRenderer : public TableModelSymbolRendererBase
{
protected:
using TableModelSymbolRendererBase::TableModelSymbolRendererBase;
virtual NGL::INGLLogger &logger() const final { return super()->m_logger; }
virtual QAbstractItemModel *model() final { return super(); }
virtual QModelIndex indexForId(int id, int column) final { return super()->findIndexForId(id, column); }
SUPER *super() { return static_cast<SUPER *>(this); }
const SUPER *super() const { return static_cast<const SUPER *>(this); }
};
} // namespace AdvancedSymbology
@@ -0,0 +1,148 @@
/**
* @RDE_HEADER@
* Helper class to provide symbol rendering in QAbstractItemModels
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-11-01
*/
#include "table_model_symbol_renderer_base.h"
#include <AdvancedSymbology/asb_data_plugin_interface.h>
#include <NGLLogger/INGLLogger.h>
#include <QAbstractItemModel>
#include <QPointer>
namespace AdvancedSymbology
{
TableModelSymbolRendererBase::TableModelSymbolRendererBase(int iconColumn)
: m_partyRole(AdvancedSymbology::Role::Unknown)
, m_iconColumn(iconColumn)
, m_super(nullptr)
{}
void TableModelSymbolRendererBase::init(const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asb,
QObject *super)
{
m_asb = asb;
m_super = super;
}
void TableModelSymbolRendererBase::setDefaultRoleAndColor(const Role &role, const QColor &partyColor)
{
m_partyRole = role;
m_partyColor = partyColor;
}
QVariant TableModelSymbolRendererBase::decorationData(const QModelIndex &idx, int id) const
{
return decorationIcon(idx, id);
}
QIcon TableModelSymbolRendererBase::decorationIcon(const QModelIndex &idx, int id) const
{
if (idx.column() != m_iconColumn)
return QIcon();
auto it = m_symbols.find(id);
if (it != m_symbols.end())
return it.value();
return QIcon();
}
bool TableModelSymbolRendererBase::tryRenderSymbol(const QString &symbol, int id)
{
return tryRenderSymbol(symbol, id, m_partyColor, m_partyRole);
}
bool TableModelSymbolRendererBase::tryRenderSymbol(const QString &symbol, int id, const QColor &color, Role role)
{
if (!m_asb || symbol.isEmpty())
return false;
AdvancedSymbology::SymbolDataToRender symDataToRender(symbol);
symDataToRender.role = role;
if (color.isValid())
{
symDataToRender.fillColor = color;
symDataToRender.fillColorReplace = true;
}
else
{
// User-Defined Symbols (XML) need fillColor:
symDataToRender.fillColor = AdvancedSymbology::SymbolDataToRender::unknownColor();
symDataToRender.fillColorReplace = true;
}
QSharedPointer<AdvancedSymbology::SymbolResult> sr = m_asb->findImage(symDataToRender);
AdvancedSymbology::SymbolResult *ptrSr = sr.data();
if (!ptrSr)
{
WARNING_LOG(logger()) << "Can not render symbol for sidc '" << symbol << "'";
return false;
}
// already a request available?
auto it = m_symbolResultMapping.find(ptrSr);
if (it == m_symbolResultMapping.end())
{
SymbolResultData srd;
srd.result = sr;
srd.ids.push_back(id);
m_symbolResultMapping.insert(ptrSr, srd);
if (ptrSr->isResultReady())
{
symbolRendered(ptrSr);
}
else
{
// queued because the object is destroyed inside symbolRendered() due to QSharedPointer
// works without this as an object because we look for ptrSr (which is a child of this,
// see m_symbolResultMapping container)
Q_ASSERT(m_super);
QPointer<AdvancedSymbology::SymbolResult> qPointer(ptrSr);
QObject::connect(ptrSr,
&AdvancedSymbology::SymbolResult::resultReadyInternal,
m_super ? m_super : ptrSr,
[this, qPointer]() { symbolRendered(qPointer); }, Qt::QueuedConnection);
}
}
else
{
SymbolResultData &srd = it.value();
srd.ids.push_back(id);
}
return true;
}
void TableModelSymbolRendererBase::removeRenderedSymbol(int id)
{
m_symbols.remove(id);
}
void TableModelSymbolRendererBase::symbolRendered(AdvancedSymbology::SymbolResult *sr)
{
if (!sr || !sr->isResultReady())
return;
auto it = m_symbolResultMapping.constFind(sr);
if (it == m_symbolResultMapping.constEnd())
return;
const SymbolResultData &srd = it.value();
const QIcon ico(QPixmap::fromImage(srd.result->symbolImage().image()));
for (int id : srd.ids)
{
DEBUG_LOG(logger()) << "Symbol for id " << id << " ready";
m_symbols[id] = ico;
const QModelIndex idx = indexForId(id, m_iconColumn);
if (idx.isValid())
emit model()->dataChanged(idx, idx, {Qt::DecorationRole});
}
m_symbolResultMapping.erase(it);
}
} // namespace AdvancedSymbology
@@ -0,0 +1,77 @@
/**
* @RDE_HEADER@
* Helper class to provide symbol rendering in QAbstractItemModels
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2017-11-01
*/
#pragma once
#include <memory>
#include <QColor>
#include <QHash>
#include <QIcon>
#include <QSharedPointer>
class QAbstractItemModel;
class QModelIndex;
class QVariant;
namespace NGL
{
class INGLLogger;
}
namespace AdvancedSymbology
{
class SymbolResult;
class ForeignDataInterface;
enum class Role;
class TableModelSymbolRendererBase
{
protected:
explicit TableModelSymbolRendererBase(int iconColumn);
virtual ~TableModelSymbolRendererBase() = default;
void init(const std::shared_ptr<AdvancedSymbology::ForeignDataInterface> &asb,
QObject *super);
void setDefaultRoleAndColor(const Role &role, const QColor &partyColor);
QColor defaultColor() const { return m_partyColor; }
Role defaultRole() const { return m_partyRole; }
QVariant decorationData(const QModelIndex &idx, int id) const;
QIcon decorationIcon(const QModelIndex &idx, int id) const;
bool tryRenderSymbol(const QString &symbol, int id);
bool tryRenderSymbol(const QString &symbol, int id, const QColor &color, Role role);
void removeRenderedSymbol(int id);
private:
void symbolRendered(AdvancedSymbology::SymbolResult *sr);
virtual NGL::INGLLogger &logger() const = 0;
virtual QAbstractItemModel *model() = 0;
virtual QModelIndex indexForId(int id, int column) = 0;
private:
std::shared_ptr<AdvancedSymbology::ForeignDataInterface> m_asb;
struct SymbolResultData
{
QSharedPointer<AdvancedSymbology::SymbolResult> result;
QVector<int> ids;
};
QHash<AdvancedSymbology::SymbolResult *, SymbolResultData> m_symbolResultMapping;
Role m_partyRole;
QColor m_partyColor;
const int m_iconColumn;
// participantId
QHash<int, QIcon> m_symbols;
QObject *m_super; // class which derives us, needed for proper con
};
} // namespace AdvancedSymbology
+66
View File
@@ -0,0 +1,66 @@
/**
* @RDE_HEADER@
* Data Plugin Interface for AdvancedSymbology (Interface for access from other Plugins)
* $Id$
* $HeadURL$
* $Author$
* Created by Christian Ehrlicher, SLSE, 2016-02-29
*/
#pragma once
#include <QColor>
#include <Symbology/symbol_dictionary.h>
#include <PluginInterfaces/data_plugin_interface.h>
namespace ParticipantManagement
{
class Participant;
}
namespace AdvancedSymbology
{
class ForeignDataInterface;
/**
* @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<ForeignDataInterface> getForeignDataInterface() = 0;
};
/**
* @brief The ForeignDataInterface class provides methods and signals for foreign plugins, that need
* access to the data of this DataPlugin
*/
class ForeignDataInterface
{
public:
ForeignDataInterface() = default;
virtual ~ForeignDataInterface() = default;
//
// SymbolDictionary: Access and find methods
//
virtual AdvancedSymbology::SymbolDictionary &getSymbolDictionary(AdvancedSymbology::SymbologyType type) const = 0;
virtual QSharedPointer<SymbolResult> findImage(const SymbolDictionary &dict, const SymbolDataToRender &symDataToRender) const = 0;
virtual QSharedPointer<SymbolResult> findImage(const SymbolDataToRender &symDataToRender) const = 0;
virtual QSharedPointer<SymbolResult> findImage(const ParticipantManagement::Participant &participant, int sizeL = 100, const QColor& desiredColor = QColor()) const = 0;
virtual QSharedPointer<SymbolResult> findPreview(const SymbolDictionary &dict, const QString &sidc) const = 0;
virtual QSharedPointer<SymbolResult> findPreview(const QString &sidc) const = 0;
virtual QSharedPointer<SymbolResult> findBaseSymbol(const SymbolDictionary &dict, const QString &sidc) const = 0;
virtual QSharedPointer<SymbolResult> findBaseSymbol(const QString &sidc) const = 0;
virtual AdvancedSymbology::SymbologyType defaultSymbologyType() const = 0;
};
} //namespace AdvancedSymbology
+26
View File
@@ -0,0 +1,26 @@
/**
* @RDE_HEADER@
* HMI Plugin for AdvancedSymbology (Interface for access from other Plugins)
* $Id$
* $HeadURL$
* $Author$
*
* Created by Hannes Baeuerle, SLSE, 2017-06-13
*/
#pragma once
#include <QString>
namespace AdvancedSymbology
{
class ForeignGuiInterface
{
public:
ForeignGuiInterface() = default;
virtual ~ForeignGuiInterface() = default;
static QString pluginName() { return QStringLiteral("AdvancedSymbology"); }
};
} // namespace AdvancedSymbology
@@ -0,0 +1,44 @@
/**
* @RDE_HEADER@
* HMI Plugin for AdvancedSymbology (Interface for access from other Plugins)
* $Id$
* $HeadURL$
* $Author$
*
* Created by Hannes Baeuerle, SLSE, 2017-06-13
*/
#pragma once
#include <Symbology/symbol_dictionary_types.h>
#include <QString>
namespace AdvancedSymbology
{
// forward
enum class SymbologyType;
class ForeignGuiFlmSymbolsProxyInterface
{
public:
ForeignGuiFlmSymbolsProxyInterface() = default;
virtual ~ForeignGuiFlmSymbolsProxyInterface() = default;
static QString pluginName() { return QStringLiteral("AdvancedSymbology.SymbolProxy"); }
//
// SymbolProxy (transfer Taktical Symbols@FileMngt to ExtraSymbol@SymbolDictionary
//
virtual bool createFlmSymbolProxy(int type_placeholder) = 0; // type_placeholder: GlobalSymbols, ExerciseSymbols...
virtual bool connectFlmSymbolProxy(int type_placeholder, SymbologyType symbologyType) = 0;
};
} // namespace AdvancedSymbology
+202
View File
@@ -0,0 +1,202 @@
#!/usr/bin/python3
# ------------------------------------------------------------------------------------------------
# @RDE_HEADER@
# guezSymbols2Sql.py
# $Id$
# $HeadURL$
# $Author$
# -----------------------------------------------------------------------------------------------
# Creates a sql script to insert existing XML based symbols from GueZ project EXCON database
# There for the existing insert_ppm_values_types.sql will be used as template.
# -----------------------------------------------------------------------------------------------
#
# Hardware-Environment: Intel-PC
# Software-Environment: Windows 7, Linux, SQL
#
# Language ........: python3
#
# -----------------------------------------------------------------------------------------------
#
# Author ...........: Joerg Turla, SPD G, Tel. 3132
#
# -----------------------------------------------------------------------------------------------
#
# Notes .........:
#
# 20.07.2018, JT : First edition
# 23.07.2018, JT : add assignment of SIDC to participant types
# 25.07.2018, JT : use db type dump to assign SIDC to participants
#
# ------------------------------------------------------------------------------------------------
import os
import re
import sys
import shutil
if len(sys.argv) != 2 and len(sys.argv) != 4 :
print("Usage %s directory-path file-path-types-dump [path to insert_ppm_values_types.sql]" % sys.argv[0])
sys.exit
dirPath = os.path.abspath(sys.argv[1])
if not os.path.isdir(dirPath) :
print("directory \"%s\" doesn't exists. Abort ..." % dirPath)
sys.exit
fdSql = open("symbols_insert.sql", "wt")
maxId = -1
nameDict = {}
idDict = {}
symbolCount = 0
print ("\nParsing XML symbol definitions:")
for fileN in os.listdir(dirPath) :
symbolId = -1
if fileN.endswith(".xml") :
fd = open(dirPath + "/"+ fileN,"rt")
xmlContent = fd.read()
fd.close()
# print(xmlContent)
idBegin = xmlContent.find("id=\"")
idEnd = xmlContent.find("\"",idBegin+4)
if idBegin > 0 and idEnd > 0 :
idBegin = idBegin + 4
symbolId = int(xmlContent[idBegin:idEnd],0)
if symbolId >= 0 :
if symbolId > maxId :
maxId = symbolId
nameBegin = xmlContent.find("<name>")
nameEnd = xmlContent.find("</name>")
name = ""
if nameBegin > 0 and nameEnd > 0 :
nameBegin = nameBegin + 6
name = xmlContent[nameBegin:nameEnd]
else :
name = "noname"
nameCount = nameDict.get(name,0) + 1
nameDict[name] = nameCount
if nameCount > 1 :
name = name +"(" + str(nameCount)+")"
symbolCount = symbolCount+1
print(" [%3d] : Insert symbol %s with id=%d to sql database" % (symbolCount,name,symbolId) )
fdSql.write("INSERT INTO flm.flm_file_content (id, name, folder_id, file_category_id, file_type_id, file_status_id, operator_id, properties )")
fdSql.write(" values (" + str(symbolId) + ",'" + name + "', 30, 1, 8, 0, 99, '{\"imageFormat\": \"xml\"}');\n")
symbolPath = "/shd/CTC/TOOLS/TDS/TDS-source/Lts/Tests/DatabaseInitialisation/GuezSymbols/" + fileN
fdSql.write("UPDATE flm.flm_file_content SET content = ( SELECT bytea_import('" + symbolPath + "')) WHERE id = " + str(symbolId) + "; \n")
maxId = maxId + 1
fdSql.write("ALTER SEQUENCE flm.flm_file_content_id_seq RESTART WITH " + str(maxId) + ";")
fdSql.close()
print("\n"+str(symbolCount)+" symbols added to sql script")
if len(sys.argv) == 4 :
typeDump = os.path.abspath(sys.argv[2])
if not os.path.exists(typeDump) :
print("types dump file \"%s\" doesn't exists. Abort ..." % typeDump)
sys.exit
print("\nParsing db type dump \"%s\" ..." % typeDump)
fdTypen = open(typeDump,"rt")
while True:
line = fdTypen.readline()
if (line == "") :
break
typeDataList = line.split("|")
if len(typeDataList) > 4 :
name = typeDataList[2]
symbolId = int(typeDataList[3])
if symbolId > 0 :
nameId = re.sub(r"\s+", "", name, flags=re.UNICODE)
idDict[nameId] = symbolId
print(nameId + " ---> " + str(idDict[nameId]))
fdTypen.close()
# -------------------------------------------------------------------------------------------
print("\nModify insert_ppm_values_types.sql ...")
ppm_script_template = os.path.abspath(sys.argv[3]) + "/insert_ppm_values_types.sql"
ppm_script = os.path.abspath(sys.argv[3]) + "/insert_ppm_values_types_with_symbols.sql"
fdRead = open( ppm_script_template,"rt")
fdWrite = open( ppm_script,"wt")
ppmValueCnt = 0
changeLine = False
while True:
line = fdRead.readline()
if (line == "") :
break
if line.startswith("INSERT INTO ppm.ppm_type (") :
fdWrite.write(line)
changeLine = True
continue
if line.startswith(" VALUES (") and changeLine == True :
nameBegin = line.find("'") + 1
nameEnd = line.find("'",nameBegin)
sidc = ""
if nameBegin > 0 and nameEnd > 0 :
name = line[nameBegin:nameEnd]
name = re.sub(r"\s+", "", name, flags=re.UNICODE)
keyName = name
for key in idDict :
if key != "" :
if name.startswith(key):
keyName = key
break
# special case BPZBÜFFEL is not equal PBZBüFFEL and to lower doesn't help here, why ever????
if key.startswith("BPz3B") and name.startswith("BPz3B"):
keyName = key
break
if idDict.get(keyName,0) > 0 :
symbolBegin = line.find("'",nameEnd+1)+1
symbolEnd = line.find("'",symbolBegin)
if symbolBegin == symbolEnd :
sidc = "NONE|CVLX|" + str(idDict.get(keyName,0))
tmpLine = line[:symbolBegin]+sidc+line[symbolEnd:]
line = tmpLine
ppmValueCnt += 1
else :
sidc = line[symbolBegin:symbolEnd] # only for logging
if sidc == "" :
print("\"" + name + "\" not found in db type dump." )
print(name + " : " + sidc)
fdWrite.write(line)
changeLine = False
fdWrite.close()
fdRead.close()
print("\n%d symbols added to ppm types\n" % ppmValueCnt)
File diff suppressed because it is too large. Load diff
+152
View File
@@ -0,0 +1,152 @@
0|-1|Kein Typ|212|-1|-1|-1|0|0|0|0|-1|||
1|265|ABCAufklTrp|1|1|8|0|0|0|0|0|-1|||
2|266|ABCAufklZg|2|1|5|0|0|0|0|0|-1|||
3|267|LKW 5t mil gl TA|303|3|43|70|0|0|6500|50|-1|||
4|268|Anh MiV|4|3|46|48|0|0|7550|50|-1|||
222||SR Kontr NL|186|6|106|83|0|0|9700|100|-1|||
10|274|BPz 3 BüFFEL|11|4|72|30|1|0|5800|50|-1|||
11|275|BrLPz BIBER|12|4|71|31|1|0|5850|50|-1|||
13|277|BtlGefStd|861|1|2|0|0|0|0|0|-1|||
221||SR Kontr Mine NL|186|6|106|84|0|0|9600|50|-1|||
220||Richtmine NL|268|5|82|82|0|0|9000|50|-1|||
19|283|FschJgGrp|29|1|7|0|0|0|0|0|-1|||
20|284|FschJgKp|31|1|3|0|0|0|0|0|-1|||
21|285|FschJgKpFüGrp|33|1|4|0|0|0|0|0|-1|||
22|286|FschJgZg|35|1|5|0|0|0|0|0|-1|||
23|287|FschJgZgTrp|37|1|6|0|0|0|0|0|-1|||
33|297|GebJgGrp|52|1|7|0|0|0|0|0|-1|||
34|298|GebJgKp|56|1|3|0|0|0|0|0|-1|||
35|299|GebJgKpFüGrp|58|1|4|0|0|0|0|0|-1|||
36|300|GebJgZg|65|1|5|0|0|0|0|0|-1|||
37|301|GebJgZgTrp|67|1|6|0|0|0|0|0|-1|||
44|308|Krad gl|90|5|87|5|0|0|500|2500|-1|||
46|310|LKW 5t tmil gl 4x4 Iveco|303|3|43|71|0|0|6650|100|-1|||
47|311|LKW 10t gl/glw|93|3|44|47|0|0|6950|100|-1|||
48|312|LKW 5t FKue DB|98|3|43|72|0|0|7050|100|-1|||
50|314|LKW 2t gl|96|3|42|42|0|0|6250|200|-1|||
51|315|LKW 5t tmil gl 4x4 DB|98|3|43|44|0|0|6550|100|-1|||
52|316|LKW 5t mil gl/glw|98|3|43|45|0|0|6750|100|-1|||
53|317|LKW 7t mil gl/glw|99|3|44|46|0|0|6850|100|-1|||
54|318|LKW gl le kurz|92|3|41|38|0|0|6050|100|-1|||
56|320|LKW gl le LL|92|3|41|38|0|0|6050|100|-1|||
67|331|MunTrp|121|1|8|0|0|0|0|0|-1|||
68|332|PiErkGrp|163|1|7|0|0|0|0|0|-1|||
69|333|PiPz DACHS|125|4|70|34|1|0|5700|50|-1| | |
71|335|PzAufklKp|128|1|3|0|0|0|0|0|-1|||
75|339|PzAufklZg|132|1|5|0|0|0|0|0|-1|||
79|343|PzGrenGrp|140|1|7|0|0|0|0|0|-1|||
80|344|PzGrenKp|143|1|3|0|0|0|0|0|-1|||
81|345|PzGrenKpFüGrp|145|1|4|0|0|0|0|0|-1|||
82|346|PzGrenTrp|147|1|8|0|0|0|0|0|-1|||
83|347|PzGrenZg|149|1|5|0|0|0|0|0|-1|||
84|348|PzGrenZgTrp|152|1|6|0|0|0|0|0|-1|||
88|352|PzKp|156|1|3|0|0|0|0|0|-1|||
89|353|PzKpFüGrp|158|1|4|0|0|0|0|0|-1|||
94|358|PzPiGrp|163|1|7|0|0|0|0|0|-1|||
95|359|PzPiKp|165|1|3|0|0|0|0|0|-1|||
96|360|PzPiZg|166|1|5|0|0|0|0|0|-1|||
97|361|PzPiZgTrp|167|1|6|0|0|0|0|0|-1|||
98|362|PzZg|168|1|5|0|0|0|0|0|-1|||
100|830|SR (Leiter)|188|6|101|18|0|0|3000|150|-1|||
101|833|SR Fz (Leiter)|429|7|121|100|2|0|7700|150|-1|||
106|576|Soldat/G|180|5|82|5|0|0|500|2500|-1|||
112|376|SR Spezial|188|6|106|18|0|0|3000|150|-1|||
114|378|SR Truppe|188|6|105|18|0|0|3000|150|-1|||
116|380|TVPL|202|1|1|0|0|0|0|0|-1|||
118|382|VB Trp Art|204|1|8|0|0|0|0|0|-1|||
120|384|VersGrp|206|1|7|0|0|0|0|0|-1|||
121|385|Video Dok|208|6|108|19|0|0|3150|50|-1|||
122|386|VVD|209|1|1|0|0|0|0|0|-1|||
123|387|Wtg Trp|210|1|8|0|0|0|0|0|-1|||
128|392|TrpFhr|816|5|81|5|0|0|500|2500|-1|||
129|393|Soldat/MG|107|5|84|5|0|0|500|2500|-1|||
130|394|Soldat/PzF|137|5|85|5|0|0|500|2500|-1|||
131|396|Soldat/MILAN|111|5|86|5|0|0|500|2500|-1|||
140|824|LKW 5t FKue Iveco|98|3|43|73|0|0|7150|100|-1|||
141|835|SR Fz|227|7|124|100|2|0|7700|150|-1|||
142|836|Inst Fz|232|7|126|100|2|0|7700|150|-1|||
143|837|Video Fz|239|7|127|99|1|0|7850|50|-1|||
144|838|Mobiles Auditorium|288|7|128|98|0|0|7900|50|-1|||
145|839|SR Fz (Kp)|289|7|122|100|2|0|7700|150|-1|||
146|840|SR Fz (Zg)|290|7|123|100|2|0|7700|150|-1|||
147|841|SR (Kp)|188|6|102|18|0|0|3000|150|-1|||
148|842|SR (Zg)|188|6|103|18|0|0|3000|150|-1|||
150|843|LKW 14t 8x8 MULTI|294|3|45|74|0|0|7250|100|-1|||
151|845|FzKran le tmil|295|3|47|76|0|0|7450|25|-1|||
152|846|FzKran (MAN/Magierus/KHD)|296|3|47|77|0|0|7475|25|-1|||
154|865|Rgmt|214|1|1|0|0|0|0|0|-1|||
155|866|Btl|215|1|2|0|0|0|0|0|-1|||
156|867|Kp|216|1|3|0|0|0|0|0|-1|||
157|868|KpFüGrp|217|1|4|0|0|0|0|0|-1|||
158|869|Zg|123|1|5|0|0|0|0|0|-1|||
159|872|ZgTrp|226|1|6|0|0|0|0|0|-1|||
160|870|Grp|218|1|7|0|0|0|0|0|-1|||
161|871|Trp|219|1|8|0|0|0|0|0|-1|||
162|873|BtlFüGrp|222|1|2|0|0|0|0|0|-1|||
163|423|FschJgBtl|27|1|2|0|0|0|0|0|-1|||
165|445|GebJgBtl|49|1|2|0|0|0|0|0|-1|||
166|446|GebJgBtlFüGrp|50|1|2|0|0|0|0|0|-1|||
170|523|PzAufklBtl|231|1|2|0|0|0|0|0|-1|||
171|531|PzBtl|135|1|2|0|0|0|0|0|-1|||
173|534|PzGrenBtl|138|1|2|0|0|0|0|0|-1|||
174|585|StabsKp (FschJgBtl)|189|1|3|0|0|0|0|0|-1|||
175|586|StabsKp (GebJgBtl)|190|1|3|0|0|0|0|0|-1|||
177|588|StabsKp (PzBtl)|192|1|3|0|0|0|0|0|-1|||
178|589|StabsKp (PzGrenBtl)|193|1|3|0|0|0|0|0|-1|||
179|2134|SRGrp|220|10|7|0|0|0|0|0|-1|||
181|2136|VideoGrp|208|10|-1|0|0|0|0|0|-1|||
182|2137|VideoTrp|208|10|-1|0|0|0|0|0|-1|||
183|3886|PAH 1A1|124|8|141|90|1|0|7650|50|-1|||
186|3926|KPz LEO 2A6|230|2|21|61|2|0|4100|300|-1| | |
187|3931|FlaRakWaTrgt OZELOT|300|2|28|26|2|0|4900|50|-1|||
188|3932|SpähWg FENNEK|301|2|25|66|2|0|7600|50|-1| | |
189|3935|PzAbwRiMi|310|2|29|0|0|0|0|0|-1|||
190|3936|LKW 7t MULTI|99|3|44|75|0|0|7350|100|-1|||
191|3937|EAG|308|3|48|80|0|0|7500|25|-1|||
192|3938|EAM/AS6M|308|3|48|81|0|0|7525|25|-1|||
193|468|Jabo|72|8|142|89|0|0|8050|50|-1|||
194|4399|TEP|456|1|1|0|0|0|0|0|-1|||
195|4735|Aufklärer|425|8|142|89|0|0|8050|50|-1|||
196|4736|Anflugpunkt|551|8|143|0|0|0|0|0|-1|||
197|4886|TetraDEFla|916|8|142|89|0|0|8050|50|-1| | |
201|4845|MOUT-Ebene|240|1|7|0|0|0|0|0|0|||
224||MUNGO|831|4|64|79|1|0|5550|50|-1| | |
57|321|LKW gl le San|95|3|41|40|1|0|6150|100|-1| | |
58|322|LLPz Wiesel|105|2|23|25|1|0|4750|50|-1| | |
185|3934|ABC-Warngeber|298|5|88|91|0|0|8000|50|-1| | |
136|820|Pz Haubitze M109|229|4|67|69|1|0|5250|50|-1| | |
113|377|SR Stab|188|6|104|18|0|0|3000|150|-1| | |
149|831|Wirkungsdarsteller|293|6|107|18|0|0|3000|150|-1| | |
43|3885|KPz LEO 1A5|230|2|21|55|2|1|3200|300|-1| | |
132|814|KPz LEO 2A4|230|2|21|57|2|1|3500|300|-1| | |
133|815|KPz LEO 2A5|230|2|21|59|2|1|3800|300|-1| | |
8|272|BeobPz Art M113|9|4|66|52|2|0|5300|50|-1| | |
49|313|LKW 2t gl KrKw|95|3|42|43|1|0|6450|50|-1| | |
55|319|LKW gl le kurz/FüFu|92|3|41|38|1|0|6050|100|-1| | |
59|323|LLPz WIESEL TOW|106|2|23|28|1|0|4700|50|-1| | |
60|324|MiRPz KEILER|112|4|69|32|1|0|5600|50|-1| | |
64|328|MiW SKORPION|115|4|68|33|1|0|5650|50|-1| | |
108|372|SpähPz LUCHS|182|2|24|24|2|0|5000|200|-1| | |
109|373|SpürPz FUCHS|183|4|65|36|1|0|6000|50|-1| | |
110|580|SPz MARDER 1A3|184|2|22|21|2|2|4400|300|-1| | |
111|375|SPz MARDER VBMrs|185|2|22|21|2|2|4400|300|-1| | |
115|379|TPz FUCHS (Jäger)|197|4|64|35|1|0|5900|100|-1| | |
134|817|LLPz WIESEL LeFaSys|286|2|23|68|1|0|4950|50|-1| | |
135|819|Pz Haubitze 2000|229|4|67|65|1|0|5200|50|-1| | |
137|821|BeobPz Art LEO 1A5|284|4|67|51|2|0|5350|50|-1| | |
138|822|BPz LEO 1 Standard|11|4|72|64|1|0|5750|50|-1| | |
139|834|WD Fz (DMF)|228|7|125|20|1|0|7950|50|-1| | |
153|844|Soldat/Fu|201|5|83|5|1|0|500|2500|-1| | |
214||Moerser M113|923|4|62|67|1|0|5550|50|-1| | |
215||FüFu M113|929|4|61|53|1|0|5400|100|-1| | |
223||SR Wolf NL|227|7|124|85|2|0|9500|100|-1| | |
227||KrKw M113|95|4|63|50|1|0|5500|50|-1| | |
232||TPz FUCHS (1A8)|197|4|64|37|1|0|0|0|-1| | |
233||LKW NLK 0.5t|0|3|41|6|0|0|0|0|-1| | |
230||KPz LEO 2A5 (F)|230|2|21|60|2|1|3800|300|-1| | |
125|389|KpChef|813|5|81|5|1|0|500|2500|-1| | |
126|390|ZgFhr|814|5|81|5|1|0|500|2500|-1| | |
127|391|GrpFhr|815|5|81|5|1|0|500|2500|-1| | |
124|388|BtlKdr|811|5|81|5|1|0|500|2500|-1| | |
231||KPz LEO 2A7|230|2|21|63|2|0|0|0|-1| | |
234||GTF 15t|294|4|67|87|1|0|0|0|-1| | |