/** ** ** @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 ** 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 #include #include #include #include #include #include #include #include #include #include #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 &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 &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 &points , const QList > &attributes , int userData = -1 , const QString &textData = QString() , GeometryModel::HorizontalAlign textAlign = HorizontalAlign::Left) override; bool setPrimitivePoints(const GeometryModel::Node &node, const QList &points) override; GeometryModel::Node addText(const GeometryModel::Node &parent , const QString &textData , GeometryModel::HorizontalAlign textAlign , const QList > &attributes , int userData) override; GeometryModel::Node getText(const GeometryModel::Node &parent) const override; QString getTextData(const GeometryModel::Node &textNode) const override; QList 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 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 supportedAttributes(GeometryModel::PrimitiveType type) const override; GeometryModel::Node createGroup(const QList &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 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 &attrMap) const override; QString buildSymbolAttributeString(const QMap &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 _primitiveSupportedAttributes; //! Mappings between all primitive-types and their string/tag-name static QMap _primitiveTagsTypes; static QMap _primitiveTagsStrings; //! Default-Values for all supported attributes static QMap, QString> _attributeDefaults; //! Mapping between Attributes and their QVariant-Type. static QMap _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 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 &primitives); QMultiMap 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 _undoStack; QStack _undoHistory; QStack _redoStack; QStack _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 T GeometryModelQDom::getAttribute(const Node &node, Attribute attribute) const { const QVariant &v = getAttribute(node, attribute); switch (qMetaTypeId()) { case QMetaType::QPointF: case QMetaType::QColor: { T result; valueFromVariant(v, result); return result; } break; default: break; } return v.value(); } // template T GeometryModelQDom::getAttribute( const Node & node, Attribute attribute ) const } // namespace SituationMap