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

@@ -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