Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/GeometryModel/geometry_model_q_dom.h
T
2026-08-13 18:33:10 +02:00

375 lines
13 KiB
C++
Executable File

/**
**
** @RDE_HEADER@
** GeometryModel implementation to write and read PlanEditor plans from/to XML and manipulate DOM-tree.
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Stephan Kuhagen <kuhagen@rheinmetall-de.com>
** Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** ??.??.200?, SK : First edition for use with Qt4
** 11.11.2015, JT : Splitting interface and implementation
**
** -----------------------------------------------------------------------------------------------
*/
// clazy:excludeall=const-signal-or-slot
#pragma once
#include <QtGui/QColor>
#include <QtXml/QDomDocument>
#include <QtCore/QMultiMap>
#include <QtCore/QObject>
#include <QtCore/QPair>
#include <QtCore/QPointF>
#include <QtCore/QRectF>
#include <QtCore/QStack>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include "geometry_model.h"
class QTransform;
namespace SituationMap
{
// exported for unit test only
class GEOMETRYMODEL_EXPORT GeometryModelQDom : public GeometryModel, public QDomDocument
{
Q_OBJECT
public:
explicit GeometryModelQDom(QObject *parent = nullptr);
//! Copy-Constructor
GeometryModelQDom(const GeometryModelQDom &other);
~GeometryModelQDom();
GeometryModelQDom & operator = (const GeometryModelQDom &other);
QByteArray toByteArray() const override;
QByteArray toByteArrayDebug() const override;
bool fromByteArray(const QByteArray &content) override;
bool fromDevice(QIODevice *device) override;
bool fromByteArrayDebug(const QByteArray &content) override;
bool isEmpty() const override;
Node getRootNode() const override;
Node getMapDefaultSettingsNode() const override;
void setModelAttribute(GeometryModel::Attribute attribute, const QVariant &value) override;
void setModelEditorAttribute(GeometryModel::Attribute attribute, const QVariant &value) override;
void setPrimitiveAttribute(const GeometryModel::Node &node, GeometryModel::Attribute attribute, const QVariant &value) override;
void movePrimitiveIntoGroup(const GeometryModel::Node &primitive, const GeometryModel::Node &target) override;
void releaseGroup(const GeometryModel::Node &group) override;
void deleteGroup(const GeometryModel::Node &group) override;
void removePrimitive(const GeometryModel::Node &primitive) override;
void removePrimitivesByUserData(const QList<int> &userDataList) override;
void removeText(GeometryModel::Node &parent) override;
void setTextData(const GeometryModel::Node &textNode, const QString &data, GeometryModel::HorizontalAlign textAlign) override;
void clearModel() override;
void translateNode(const GeometryModel::Node &node, double x, double y) override;
void moveNode(const GeometryModel::Node &node, double x, double y) override;
void scaleNode(const GeometryModel::Node &node, double scaleX, double scaleY) override;
void rotateNode(const GeometryModel::Node &node, double angle) override;
void reorderPrimitives(const QList<GeometryModel::Node> &nodes, GeometryModel::PrimitivOrder order) override;
void merge(const GeometryModel::Node &other, bool skipUndo = false, bool intoNewGroup = false) override;
void merge(GeometryModel *other, bool skipUndo = false, bool intoNewGroup = false) override;
unsigned int modificationCounter() const override;
void resetModificationCounter() override;
void undo(unsigned int steps = 1) override;
void redo(unsigned int steps = 1) override;
void enableUndo(bool enable) override;
void startUndoBlock() override;
void endUndoBlock(const QString &eventDescription = QString()) override;
void abortUndoBlock() override;
void setMaxUndoSteps(unsigned int max) override;
unsigned int maxUndoSteps() const override;
void cleanModel() override;
GeometryModel::Node addPrimitive(GeometryModel::PrimitiveType type
, const QList<QPointF> &points
, const QList<QPair<GeometryModel::Attribute, QVariant> > &attributes
, int userData = -1
, const QString &textData = QString()
, GeometryModel::HorizontalAlign textAlign = HorizontalAlign::Left) override;
bool setPrimitivePoints(const GeometryModel::Node &node, const QList<QPointF> &points) override;
GeometryModel::Node addText(const GeometryModel::Node &parent
, const QString &textData
, GeometryModel::HorizontalAlign textAlign
, const QList<QPair<GeometryModel::Attribute, QVariant> > &attributes
, int userData) override;
GeometryModel::Node getText(const GeometryModel::Node &parent) const override;
QString getTextData(const GeometryModel::Node &textNode) const override;
QList<QPointF> getPrimitivePoints(const GeometryModel::Node &node) const override;
QRectF getBoundingBox(const GeometryModel::Node &node) const override;
void setNodeDisplayName(const Node &node, const QString &name) override;
QString getNodeDisplayName(const Node &node) const override;
QVariant getModelAttribute(Attribute attribute) const override;
QVariant getAttribute(const GeometryModel::Node &node, GeometryModel::Attribute attribute) const override;
template <class T> T getAttribute(const Node &node, Attribute attribute) const;
bool hasAttribute(const GeometryModel::Node &node, GeometryModel::Attribute attribute) const override;
QVariant::Type attributeType(const GeometryModel::Attribute &attribute) const override;
QList<GeometryModel::Attribute> supportedAttributes(GeometryModel::PrimitiveType type) const override;
GeometryModel::Node createGroup(const QList<GeometryModel::Node> &primitives) override;
GeometryModel::Node isInGroup(const GeometryModel::Node &primitive) const override;
GeometryModel::NodeList getGroupPrimitives(const GeometryModel::Node &node) override;
GeometryModel::Node findPrimitive(int userData) const override;
bool hasUserData(const Node &node) const override;
int getUserData(const GeometryModel::Node &node, bool *ok = nullptr) const override;
void setUserData(const GeometryModel::Node &node, int userData) override;
QMultiMap<int, GeometryModel::Node> userDataMap(const GeometryModel::Node &node = GeometryModel::Node()) override;
GeometryModel::Node copy(const GeometryModel::Node &node, int userData = 0) override;
GeometryModel::PrimitiveType getType(const GeometryModel::Node &node) const override;
unsigned int undoSteps() const override;
unsigned int redoSteps() const override;
QStringList undoHistory() const override { return _undoHistory.toList(); }
QStringList redoHistory() const override { return _redoHistory.toList(); }
void clearUndoStack() override
{
_undoStack.clear();
_undoHistory.clear();
} // clearUndoStack
void clearRedoStack() override
{
_redoStack.clear();
_redoHistory.clear();
} // clearRedoStack
QString attributeToString(const GeometryModel::Attribute &attribute) const override;
bool parseSymbolAttributeString(const QString &sidcAttributes, QMap<QString, QVariant> &attrMap) const override;
QString buildSymbolAttributeString(const QMap<QString, QVariant> &attrMap) const override;
static void cleanupStaticMember();
private:
static void valueFromVariant(const QVariant &v, QPointF &result);
static void valueFromVariant(const QVariant &v, QColor &result);
/**
convert to QString (with non locale-aware conversions)
*/
static QString variant2XmlString(const QVariant &v);
/**
Create a QColor from an attribute-value with alpha-channel (QVariant
ignores Alpha)
\param attColor: The QString-QVariant from an attribute of Type QColor
\return QColor with alpha-channel or invalid QColor, if the value could be parsed.
*/
static QColor colorFromString(const QString &attColor);
/**
Create a QPoint from an attribute-value
\param attPoint: The QString-QVariant from an attribute of Type QPointF
\return QPointF
*/
static QPointF pointFromString(const QString &attPoint);
//! A mapping between all primitives and the attributes they support
static QMultiMap<GeometryModel::PrimitiveType, GeometryModel::Attribute> _primitiveSupportedAttributes;
//! Mappings between all primitive-types and their string/tag-name
static QMap<QString, GeometryModel::PrimitiveType> _primitiveTagsTypes;
static QMap<GeometryModel::PrimitiveType, QString> _primitiveTagsStrings;
//! Default-Values for all supported attributes
static QMap<QPair<GeometryModel::PrimitiveType, GeometryModel::Attribute>, QString> _attributeDefaults;
//! Mapping between Attributes and their QVariant-Type.
static QMap<GeometryModel::Attribute, QVariant::Type> _attributeTypes;
//! Bool to check, if static class variables have been initialized
static bool _staticInitDone;
/**
Init data of the object
*/
void init();
/**
Transform the points of a primitive.
\sa {translateNode(), moveNode(), rotateNode(), scaleNode()}
\param node: The primitive to transform.
\param t: The transformation-matrix.
*/
void transformNode(const QDomNode &node, const QTransform &t);
GeometryModel::PrimitiveType getType(const QDomNode &node) const;
bool hasUserData(const QDomNode &node) const;
int getUserData(const QDomNode &node, bool *okPtr) const;
QRectF getBoundingBox(const QDomNode &node) const;
QList<QPointF> getPrimitivePoints(const QDomNode &node) const;
bool hasAttribute(const QDomNode &node, GeometryModel::Attribute attribute) const;
QVariant getAttribute(const QDomNode &node, GeometryModel::Attribute attribute) const;
void removePrimitive(const QDomNode &primitive);
void translateNode(const QDomNode &node, double x, double y);
void moveNode(const QDomNode &node, double x, double y);
void scaleNode(const QDomNode &node, double scaleX, double scaleY);
void rotateNode(const QDomNode &node, double angle);
void merge(const QDomNode &other, bool skipUndo = false, bool intoNewGroup = false);
QDomNode createGroup(const QList<QDomNode> &primitives);
QMultiMap<int, QDomNode> userDataMap(const QDomNode &node) const;
/**
Wrapper for signal changed(), checks _skipChangedSignal
!!! ATTENTION: Do not use the signal changed directly.
Use emitChangedSignal() instead !!!
\param what: Short description of the change for logging
\param node: the changed node (if this is a Null-Node, the Root-Node of
the plan has changed)
\param att: The attribute, that changed. If att==MaxAttributes, then
multiple attributes are changed
\param coordsChanged: if true, the coordinated of the primitive are changed
*/
void emitChangedSignal(const Node &node, Attribute att, bool coordsChanged);
//! Lock for temporarily blocking changed()-Signals
bool _skipChangedSignal;
//! Undo-Stack
bool _undoEnabled;
unsigned int _maxUndoSteps;
QStack<QDomNode> _undoStack;
QStack<QString> _undoHistory;
QStack<QDomNode> _redoStack;
QStack<QString> _redoHistory;
//! Undo-blocks
QDomNode _undoBlock;
QString _undoHistoryBlock;
bool _insideUndoBlock;
unsigned int _modificationCounter;
//! Push/pop current state to undo-stack, if not locked
void pushUndo(const QString &eventDescription = QString());
GeometryModel::Node popUndo();
}; // GeometryModelQDom
template <class T> T GeometryModelQDom::getAttribute(const Node &node, Attribute attribute) const
{
const QVariant &v = getAttribute(node, attribute);
switch (qMetaTypeId<T>())
{
case QMetaType::QPointF:
case QMetaType::QColor:
{
T result; valueFromVariant(v, result); return result;
} break;
default: break;
}
return v.value<T>();
} // template <class T> T GeometryModelQDom::getAttribute( const Node & node, Attribute attribute ) const
} // namespace SituationMap