317 lines
11 KiB
C++
Executable File
317 lines
11 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "symbol_writer.h"
|
|
#include "primitive.h"
|
|
#include "attribute_data.h"
|
|
|
|
#include <QFile>
|
|
#include <QXmlStreamWriter>
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
|
|
namespace SymbologyXML
|
|
{
|
|
|
|
SymbolWriter::SymbolWriter()
|
|
: logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("AdvSymbologyXML.SymbolWriter"))
|
|
{
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
} // SymbolWriter::SymbolWriter()
|
|
|
|
bool SymbolWriter::toFile(const Symbol &symbol, QFile *file, t_attFilterPrimitive attributeFilter) const
|
|
{
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
if (!file->isOpen() && !file->open(QIODevice::WriteOnly))
|
|
{
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return false;
|
|
}
|
|
file->write(toString(symbol, attributeFilter));
|
|
file->close();
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return true;
|
|
} // bool SymbolWriter::toFile(const Symbol& symbol, QFile* file, t_attFilterPrimitive attributeFilter)
|
|
|
|
|
|
QByteArray SymbolWriter::toString(const Symbol& symbol, t_attFilterPrimitive attributeFilter) const
|
|
{
|
|
DEBUG_LOG(logger) << LOGFUNCTION ;
|
|
|
|
QByteArray xml;
|
|
QXmlStreamWriter sw(&xml);
|
|
sw.setAutoFormatting(true);
|
|
sw.setAutoFormattingIndent(2);
|
|
sw.setCodec("UTF-8");
|
|
sw.writeStartDocument(QStringLiteral("1.0"), true);
|
|
sw.writeDTD(QStringLiteral("<!DOCTYPE symboltable SYSTEM \"symbole.dtd\">"));
|
|
sw.writeStartElement(QStringLiteral("symbol"));
|
|
sw.writeAttribute(QStringLiteral("version"), QString::fromLatin1(Symbol::SymbolVersion));
|
|
|
|
// Tag symbol, attribute id
|
|
sw.writeAttribute(QStringLiteral("id"), QString::number(symbol.id()));
|
|
|
|
// Tag symbol, attribute dimen
|
|
sw.writeAttribute(QStringLiteral("dimen"), SymbolTypes::instance()->getDimen()->convert_enum2str(symbol.getDimen()));
|
|
|
|
// Tag symbol, attribute affil
|
|
sw.writeAttribute(QStringLiteral("affil"), SymbolTypes::instance()->getAffil()->convert_enum2str(symbol.getAffil()));
|
|
|
|
// Tag symbol, attribute transformed
|
|
sw.writeAttribute(QStringLiteral("transformed"), symbol.transformed() ? QStringLiteral("1") : QStringLiteral("0"));
|
|
|
|
// Tag symbol, attribute bcdab
|
|
sw.writeAttribute(QStringLiteral("bcdab"), SymbolTypes::instance()->getBcdab()->convert_enum2str(symbol.getBcdab()));
|
|
|
|
// Tag symbol, attribute command_level
|
|
sw.writeAttribute(QStringLiteral("command_level"), SymbolTypes::instance()->getCommandLevel()->convert_enum2str(symbol.getCommandLevel()));
|
|
|
|
// Tag symbol, attribute headquarter
|
|
sw.writeAttribute(QStringLiteral("headquarter"), symbol.getHeadquarter() ? QStringLiteral("true") : QStringLiteral("false"));
|
|
|
|
// Tag symbol, attribute mob
|
|
sw.writeAttribute(QStringLiteral("mob"), SymbolTypes::instance()->getMob()->convert_enum2str(symbol.getMob()));
|
|
|
|
// Tag symbol, attribute vehicle
|
|
sw.writeAttribute(QStringLiteral("vehicle"), SymbolTypes::instance()->getVehicle()->convert_enum2str(symbol.getVehicle()));
|
|
|
|
// Tag symbol, attribute intrinsicmob
|
|
sw.writeAttribute(QStringLiteral("intrinsicmob"), SymbolTypes::instance()->getIntrinsicMob()->convert_enum2str(symbol.getIntrinsicMob()));
|
|
|
|
// Tag symbol, attribute arming
|
|
sw.writeAttribute(QStringLiteral("arming"), SymbolTypes::instance()->getArming()->convert_enum2str(symbol.getArming()));
|
|
|
|
// Tag name
|
|
sw.writeTextElement(QStringLiteral("name"), symbol.getName());
|
|
|
|
// Tag APP6 class
|
|
{
|
|
sw.writeStartElement(QStringLiteral("app6class"));
|
|
sw.writeAttribute(QStringLiteral("classname"), symbol.getClassName());
|
|
sw.writeAttribute(QStringLiteral("classhierarchy"), symbol.getClassHierarchy());
|
|
sw.writeAttribute(QStringLiteral("classcodeid"), symbol.getClassCodeId());
|
|
sw.writeEndElement();
|
|
}
|
|
|
|
// Tag(s) misc with attribute class
|
|
{
|
|
NGL::BitSet<qint64> misc = symbol.getMiscTags();
|
|
QVectorIterator<SymbolTypes::t_misc> it = SymbolTypes::instance()->getMisc()->getIterator();
|
|
SymbolTypes::t_misc val;
|
|
while (it.hasNext())
|
|
{
|
|
val = it.next();
|
|
if (misc[val])
|
|
{
|
|
sw.writeStartElement(QStringLiteral("misc"));
|
|
sw.writeAttribute(QStringLiteral("class"), SymbolTypes::instance()->getMisc()->convert_enum2str(val));
|
|
sw.writeEndElement();
|
|
}
|
|
}
|
|
}
|
|
|
|
{
|
|
// Tag(s) branch with attribute class
|
|
NGL::BitSet<qint64> branches = symbol.getBranchTags();
|
|
QVectorIterator<SymbolTypes::t_branch> it = SymbolTypes::instance()->getBranch()->getIterator();
|
|
SymbolTypes::t_branch val;
|
|
while (it.hasNext())
|
|
{
|
|
val = it.next();
|
|
if (branches[val])
|
|
{
|
|
sw.writeStartElement(QStringLiteral("branch"));
|
|
sw.writeAttribute(QStringLiteral("class"), SymbolTypes::instance()->getBranch()->convert_enum2str(val));
|
|
sw.writeEndElement();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Tag text with attribute maxdatalength
|
|
Symbol::t_text textType = symbol.getTextType();
|
|
if (textType != Symbol::TEXT_UNDEFINED)
|
|
{
|
|
sw.writeStartElement(QStringLiteral("text%1").arg(textType));
|
|
sw.writeAttribute(QStringLiteral("maxdatalength"), QString::number(symbol.maxStringLength()));
|
|
// Add tag data with attribute align to text
|
|
for (int i = Symbol::TEXT1; i <= symbol.getTextType(); ++i)
|
|
{
|
|
sw.writeStartElement(QStringLiteral("data"));
|
|
switch (symbol.getTextAlign(i))
|
|
{
|
|
case Symbol::LEFT:
|
|
sw.writeAttribute(QStringLiteral("align"), QStringLiteral("left"));
|
|
break;
|
|
case Symbol::ALIGNMENT_UNDEFINED:
|
|
case Symbol::CENTER:
|
|
sw.writeAttribute(QStringLiteral("align"), QStringLiteral("center"));
|
|
break;
|
|
case Symbol::RIGHT:
|
|
sw.writeAttribute(QStringLiteral("align"), QStringLiteral("right"));
|
|
break;
|
|
}
|
|
sw.writeCharacters(symbol.getText(i));
|
|
sw.writeEndElement(); // data
|
|
}
|
|
sw.writeEndElement(); // text%1
|
|
}
|
|
// Tag graphic with attribute scale
|
|
{
|
|
sw.writeStartElement(QStringLiteral("graphic"));
|
|
sw.writeAttribute(QStringLiteral("scale"), QString::number(symbol.getScale()));
|
|
QLinkedListIterator<Primitive*> pi(symbol.getPrimitives());
|
|
// Add all primitive-tags to graphic
|
|
while (pi.hasNext())
|
|
primitiveToString(sw, pi.next(), attributeFilter);
|
|
sw.writeEndElement();
|
|
}
|
|
sw.writeEndElement(); // symbol
|
|
|
|
DEBUG_LOG(logger) << "END " << LOGFUNCTION ;
|
|
return xml;
|
|
} // QString SymbolWriter::toString(const Symbol& symbol, t_attFilterPrimitive attributeFilter)
|
|
|
|
static inline QString lineStyle2String(const Primitive *p)
|
|
{
|
|
switch (p->getLineStyle())
|
|
{
|
|
case Primitive::DASHED_DOTTED:
|
|
return QStringLiteral("dashed_dotted");
|
|
case Primitive::DOTTED:
|
|
return QStringLiteral("dotted");
|
|
case Primitive::DASHED:
|
|
return QStringLiteral("dashed");
|
|
case Primitive::SOLID:
|
|
return QStringLiteral("solid");
|
|
}
|
|
return QStringLiteral("solid");
|
|
}
|
|
|
|
static inline QString color2Name(const Primitive *p)
|
|
{
|
|
const QColor pColor = p->getColor();
|
|
// why not pColor.name(QColor::HexArgb) ?
|
|
return pColor.name() + QString::number(pColor.alpha(), 16);
|
|
}
|
|
|
|
static inline bool isNotFiltered(SymbolWriter::t_attFilterPrimitive attributeFilter,
|
|
SymbolWriter::t_attFilterPrimitive attr)
|
|
{
|
|
return (attributeFilter & attr) == 0;
|
|
}
|
|
|
|
void SymbolWriter::writePrimitiveAttributes(QXmlStreamWriter &sw, const Primitive *p, t_attFilterPrimitive attributeFilter)
|
|
{
|
|
if (isNotFiltered(attributeFilter, AFP_TRANSFORM))
|
|
sw.writeAttribute(QStringLiteral("transform"), p->getTransform() ? QStringLiteral("true") : QStringLiteral("false"));
|
|
if (isNotFiltered(attributeFilter, AFP_ROTATE))
|
|
sw.writeAttribute(QStringLiteral("rotate"), QString::number(p->getRotation()));
|
|
if (isNotFiltered(attributeFilter, AFP_COLOR))
|
|
sw.writeAttribute(QStringLiteral("color"), color2Name(p));
|
|
if (isNotFiltered(attributeFilter, AFP_LINEWIDTH))
|
|
sw.writeAttribute(QStringLiteral("linewidth"), QString::number(p->getLineWidth()));
|
|
if (isNotFiltered(attributeFilter, AFP_LINESTYLE))
|
|
sw.writeAttribute(QStringLiteral("linestyle"), lineStyle2String(p));
|
|
|
|
if (p->type() == Primitive::ELLIPSE ||
|
|
p->type() == Primitive::POLYGON ||
|
|
p->type() == Primitive::RECT)
|
|
{
|
|
if (isNotFiltered(attributeFilter, AFP_CLOSED))
|
|
sw.writeAttribute(QStringLiteral("closed"), QString::number(p->closed()));
|
|
if (isNotFiltered(attributeFilter, AFP_FILL))
|
|
sw.writeAttribute(QStringLiteral("fill"), QString::number(p->fill()));
|
|
}
|
|
|
|
if (p->type() == Primitive::ELLIPSE)
|
|
{
|
|
if (isNotFiltered(attributeFilter, AFP_START))
|
|
sw.writeAttribute(QStringLiteral("start"), QString::number(p->getStartAngle()));
|
|
if (isNotFiltered(attributeFilter, AFP_EXTENT))
|
|
sw.writeAttribute(QStringLiteral("extent"), QString::number(p->getExtent()));
|
|
}
|
|
|
|
if (p->type() == Primitive::ICON)
|
|
{
|
|
sw.writeAttribute(QStringLiteral("id"), QString::number(p->icon()));
|
|
sw.writeAttribute(QStringLiteral("icon_type"), SymbolTypes::instance()->getIconType()->convert_enum2str(p->iconType()));
|
|
sw.writeAttribute(QStringLiteral("position"), SymbolTypes::instance()->getSectorPosition()->convert_enum2str(p->position()));
|
|
|
|
if((p->rectpos() != SymbolTypes::SECTOR_RECTPOS_UNDEFINED) &&
|
|
(p->rectpos() != SymbolTypes::SECTOR_RECTPOS_DEFAULT))
|
|
sw.writeAttribute(QStringLiteral("rectpos"), SymbolTypes::instance()->getSectorRectpos()->convert_enum2str(p->rectpos()));
|
|
|
|
if (p->scalemode() == Primitive::Scalemode_Unproport)
|
|
sw.writeAttribute(QStringLiteral("scalemode"), Primitive::scalemode(p->scalemode()));
|
|
}
|
|
if (p->type() == Primitive::TEXT)
|
|
{
|
|
// split p->text() in two strings:
|
|
const auto strL = p->text().split(QLatin1Char('\n'));
|
|
if (strL.size() > 0)
|
|
sw.writeAttribute(QStringLiteral("sval1"), strL.at(0));
|
|
if (strL.size() > 1)
|
|
sw.writeAttribute(QStringLiteral("sval2"), strL.at(1));
|
|
}
|
|
}
|
|
|
|
void SymbolWriter::primitiveToString(QXmlStreamWriter &sw, const Primitive *p, t_attFilterPrimitive attributeFilter)
|
|
{
|
|
// Fill in data from primitive into templates
|
|
switch (p->type())
|
|
{
|
|
case Primitive::LINE:
|
|
sw.writeStartElement(QStringLiteral("line"));
|
|
break;
|
|
case Primitive::ELLIPSE:
|
|
sw.writeStartElement(QStringLiteral("ellipse"));
|
|
break;
|
|
case Primitive::POLYGON:
|
|
sw.writeStartElement(QStringLiteral("polygon"));
|
|
break;
|
|
case Primitive::RECT:
|
|
sw.writeStartElement(QStringLiteral("rect"));
|
|
break;
|
|
case Primitive::ICON:
|
|
sw.writeStartElement(QStringLiteral("icon"));
|
|
break;
|
|
case Primitive::TEXT:
|
|
sw.writeStartElement(QStringLiteral("text"));
|
|
break;
|
|
default:
|
|
Q_ASSERT(false);
|
|
return;
|
|
}
|
|
writePrimitiveAttributes(sw, p, attributeFilter);
|
|
|
|
// Create point-tags and insert into primitive-tag
|
|
const QPolygonF pointList = p->getPoints();
|
|
// specials for Primitive::ICON
|
|
bool ignorePoints = false;
|
|
if (p->type() == Primitive::ICON && pointList.size() == 2)
|
|
{
|
|
const QRectF rect = QRectF(pointList.at(0), pointList.at(1));
|
|
if (rect == SymbolTypes::getDefaultRect(p->position(), p->rectpos()))
|
|
ignorePoints = true;
|
|
}
|
|
|
|
if (!ignorePoints)
|
|
{
|
|
for (const QPointF &pLocal : pointList)
|
|
{
|
|
sw.writeStartElement(QStringLiteral("point"));
|
|
sw.writeAttribute(QStringLiteral("x"), QString::number(pLocal.x()));
|
|
sw.writeAttribute(QStringLiteral("y"), QString::number(pLocal.y()));
|
|
sw.writeEndElement();
|
|
}
|
|
}
|
|
sw.writeEndElement();
|
|
} // QString SymbolWriter::primitiveToString (Primitive* p, t_attFilterPrimitive attributeFilter)
|
|
|
|
} // namespace SymbologyXML
|