/** ** ** @RDE_HEADER@ ** GeometryModel to write and read PlanEditor plans. ** $Id$ ** $HeadURL$ ** $Author$ ** ** ----------------------------------------------------------------------------------------------- ** ** Hardware-Environment: Intel-PC ** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5 ** ** Language ........: C++ 11 ** ** ----------------------------------------------------------------------------------------------- ** ** Author ...........: Jörg Turla, SPD G, Tel. 3132 ** ** ----------------------------------------------------------------------------------------------- ** ** Notes .........: ** ** 11.11.2015, JT : First edition for use with Qt5 ** ** ----------------------------------------------------------------------------------------------- */ // clazy:excludeall=const-signal-or-slot #pragma once #include #include #include #include #include #include #include #include #include #include #include #include "geometry_model_export.h" class QIODevice; class QTransform; namespace SituationMap { class Referenced; /** Interface to Read/Write plan(s) */ class GEOMETRYMODEL_EXPORT GeometryModel : public QObject { Q_OBJECT public: class GEOMETRYMODEL_EXPORT Node { public: class Implementation; Node(); Node(const Implementation &other); // do not use explicit here to avoid a lot of writing stuff to explicit casts Node(const Node &other); virtual ~Node(); Node &operator = (const Node &other); Node &operator = (Node &&other); const Implementation &get() const; Implementation &get(); bool isValid() const; bool isRootNode() const; Node parentNode() const; bool hasChildNodes() const; Node next() const; Node firstChildNode() const; Node firstChildNode(const QString &nodeName) const; bool operator ==(const Node &) const; bool operator !=(const Node &) const; uint makeConnection(Referenced *) const; bool unlinkConnection() const; uint connectedId() const; Referenced *connected() const; private: Implementation *_d; }; // Node explicit GeometryModel(QObject *parent = nullptr); GeometryModel(const GeometryModel &); //!< Copy-Constructor GeometryModel& operator = (const GeometryModel &) = delete; // copy allowed but no assigment? /** Converts the geometry model to its textual representation. @{ */ virtual QByteArray toByteArray() const = 0; /** Converts the geometry model to QString by retaining userData. */ virtual QByteArray toByteArrayDebug() const = 0; /** @} */ /** Converts textual representation of geometry model to binary representation. @{ */ virtual bool fromByteArray(const QByteArray &content) = 0; /** @} */ /** Reads textual representation of geometry model from device and converts to binary representation. */ virtual bool fromDevice(QIODevice *device) = 0; /** Converts textual representation of geometry model to binary representation by retaining userData. */ virtual bool fromByteArrayDebug(const QByteArray &content) = 0; /** Check for existens of primitives. */ virtual bool isEmpty() const = 0; /** Retrieve the root node to traverse the model. */ virtual Node getRootNode() const = 0; /** Retrieve the node to store default map settings. */ virtual Node getMapDefaultSettingsNode() const = 0; using NodeList = QList; //! Types of Primitives for \sa { addPrimitive(), getType() } enum class PrimitiveType { DictionarySymbol , ParticipantSymbol , Ellipse , Line , Polyline , Rectangle , Spline , Symbol , Text , Node , RootNode , MapDefaults , Unknown }; // PrimitiveType //! Horizontal Alignment-Enum for Text enum class HorizontalAlign { Left = 0, HCenter = 1, Right = 2 }; //! Vertical Alignment-Enum for Text enum class VerticalAlign { Bottom = 0, VCenter = 1, Top = 2 }; //! Enum for positioning Arrows at (Poly)Lines enum class Arrows {NoArrows, Start, End, Both}; //! Enum for Fill-Patterns enum class FillPattern {None, Dots, Hor1, Hor2, Ver1, Ver2, Diag1, Diag2, Solid}; //! Enum for Fill-Style of Ellipsis enum class FillStyle {Chord, Pieslice, Open}; //! Enum for Line-Styles enum class LineStyle {LineSolid, Dashed, Dotted, DashedDotted}; //! Enum for Text-Fonts enum class Font {SansSerif, Serif, Fixed, Decorative}; //! Enum for different types of maps - extends the types from GDW::MapType in //! GDW/src/GDWUtils/LoadMapControl.h enum class MapType {Raster, Vector, Contour, Elevation, RasterElevation, MapUnknown}; //! Enum for tactical state of a symbol: ts_* = tactical state... enum class vbg_et { EINSATZBEREIT = 0, LEICHTER_TREFFER = 1, MITTLERER_TREFFER = 2, SCHWERER_TREFFER = 3, BEWEGUNGSUNFAEHIG = 4, BEWEGUNGSUNFAEHIG_SICHTB = 5, AUSFALL_WAFFENANLAGE = 6, AUSFALL_WAFFENANLAGE_SICHTB = 7, TOTALAUSFALL = 8, ZEITLICHER_AUSFALL = 9, ANNAEHENDER_TREFFER = 10, TREFFER_OHNE_WIRKUNG = 11, }; using t_vbg_et = vbg_et; /* enum t_w_vbg_et { ts_einsatzbereit, ts_treffer_ohne_wirkung, ts_annaehender_treffer, ts_zeitlicher_ausfall, ts_leichter_treffer, ts_mittlerer_treffer, ts_schwerer_treffer, ts_bewegungsunfaehig, ts_bewegungsunfaehig_sichtb, ts_ausfall_waffenanlage, ts_ausfall_waffenanlage_sichtb, ts_totalausfall }; */ //! Re-order Primitives enum class PrimitivOrder { Lower, Raise }; //! Enum for all known attributes enum class Attribute { None, // Only for changed signal, can not be set AbcProtection, // Available for: symbol - Type: bool Affiliation, // Available for: symbol - Type: Symbol::t_affil Alignment, // Available for: text_data - Type: HorizontalAlign AnchorHorizontal, // Available for: text - Type: HorizontalAlign AnchorVertical, // Available for: text - Type: t_valign ArrowClampHeight, // Available for: line polyline spline - Type: double ArrowHeight, // Available for: line polyline spline - Type: double ArrowLineWidth, // Available for: line polyline spline - Type: double Arrows, // Available for: line polyline spline - Type: t_arrows ArrowWidth, // Available for: line polyline spline - Type: double Box, // Available for: text - Type: bool Center, // Available for: ellpise rectangle - Type QPointF Close, // Available for: polyline spline - Type: bool Color, // Available for: ellipse line polyline rectangle spline text - Type: QColor Extent, // Available for: ellipse - Type: double Fill, // Available for: ellipse polyline rectangle spline text - Type: bool FillColor, // Available for: ellipse polyline rectangle spline text - Type: QColor FillPattern, // Available for: ellipse polyline rectangle spline text - Type: t_fillPattern FillStyle, // Available for: ellipse - Type: t_fillStyle Font, // Available for: text - Type: t_font FontBold, // Available for: text - Type: bool FontItalic, // Available for: text - Type: bool FontSize, // Available for: text - Type: int Height, // Available for: ellipse rectangle - Type: double Injury, // Available for: ParticipantSymbol - Type int LineColor, // Available for: text - Type: QColor LineStyle, // Available for: ellipse line polyline rectangle spline text - Type: t_lineStyle LineWidth, // Available for: ellipse line polyline rectangle spline text - Type: double MarginHorizontal, // Available for: text - Type: int MarginVertical, // Available for: text - Type: int Mobility, // Available for: symbol - Type: Symbol::t_mob SIDC, // Available for: dictionary symbol - Type: QString SIDC_Color, // Available for: dictionary symbol - Type: QColor SIDC_Attributes, // Available for: dictionary symbol - Type: QString AttributeName=AttributeValue;AttributeName.... SymbolId, // Available for: symbol - Type: int SymbolOffsetX, // Available for: symbol - Type: int SymbolOffsetY, // Available for: symbol - Type: int SymbolDirection, // Available for: symbol - Type: double ForceId, // Available for: symbol - Type: int SymbolState, // Available for: - Type: enum t_state (aus symbol_types.h) SymbolUncertainty, // Available for: - Type: enum t_uncertainty (aus symbol_types.h) SymbolExplicitScale, // Available for: symbol DamageForceId, // Available for: symbol - Type: int PeMapBrightness, // Available for: plan - Type: double PeMapCenterX, // Available for: plan - Type: int PeMapCenterY, // Available for: plan - Type: int PeMapSaturation, // Available for: plan - Type: double PeMapRotation, // Available for: plan - Type: double PeMapType, // Available for: plan - Type: t_mapType PeMapZoom, // Available for: plan - Type: double PeShowUtm, // Available for: plan - Type: bool PeSymbolOpacity, // Available for: plan - Type: double 0..1.0 (0=keine Deckkraft, 1.0 deckend) PeSymbolFillType, // Available for: plan - Type: Type: enum t_fillType (aus symbol_types.h) PeSymbolScale, // Available for: plan - Type: double 0..2.0 MetaDataTitle, MetaDataAuthor, MetaDataDate, MetaDataDesciption, MetaDataMinScale, MetaDataMaxScale, MetaPixelBasedTextBoxes, Rotate, // Available for: ellipse rectangle text - Type: double Rounding, // Available for: rectangle - Type: double Start, // Available for: ellipse - Type: double Text_EF, // Available for: symbol - Type: QString Text_G, // Available for: symbol - Type: QString Text_H, // Available for: symbol - Type: QString Text_KLNPJ, // Available for: symbol - Type: QString Text_M, // Available for: symbol - Type: QString Text_T, // Available for: symbol - Type: QString Text_V, // Available for: symbol - Type: QString Text_W, // Available for: symbol - Type: QString Text_XY, // Available for: symbol - Type: QString Text_Z, // Available for: symbol - Type: QString UtmEast, // Available for: plan - Type: int UtmGrid, // Available for: plan - Type: QString UtmNorth, // Available for: plan - Type: int UtmZone, // Available for: plan - Type: QString Width, // Available for: ellipse rectangle - Type: double att_vbg_et, // Available for: symbol - Type: t_w_vbg_et MaxAttributes }; // enum class Attribute /** Set a value for a global model-attribute. If the attribute does not exist in the model or the given value is invalid, a setAttributeError()-signal is emitted. Signal changed() ist emitted. \sa { getModelAttribute(), setAttributeError(), hasAttribute(), attributeType() } \param attribute: the attribute to set \param value: the value of the attribute */ virtual void setModelAttribute(Attribute attribute, const QVariant &value) = 0; /** Set a value for a plan-editor-attribute. If the attribute does not exist in the plan-editor or the given value is invalid, a setAttributeError()-signal is emitted. Signal planEditorChanged() ist emitted. \sa { getAttribute(), setAttributeError(), hasAttribute(), attributeType() } \param attribute: the attribute to set \param value: the value of the attribute */ virtual void setModelEditorAttribute(Attribute attribute, const QVariant &value) = 0; /** Set a value for a primitive-attribute. If the attribute does not exist in the primitive or the given value is invalid, a setAttributeError()-signal is emitted. Signal changed() ist emitted. \sa { getAttribute(), setAttributeError(), hasAttribute(), attributeType() } \param node: reference to the primitive-node \param attribute: the attribute to set \param value: the value of the attribute */ virtual void setPrimitiveAttribute(const Node &node, Attribute attribute, const QVariant &value) = 0; /** Move a primitive or a group-node into another group-node. If the moved primitive is already child of a group-node, it ist moved to the group and removed from the previous one. If the target is not a group-node, a typeError()-signal is emitted. Signal changed() ist emitted. \param primitive: the primitive or group-node to move into a group \param target: the target group-node */ virtual void movePrimitiveIntoGroup(const Node &primitive, const Node &target) = 0; /** Remove a group, but not its children. This means, that all children of the given group are moved one level up the tree and then the group is deleted. If group is not a group-node, a typeError()-signal is emitted. Signal changed() ist emitted. \param group: the group */ virtual void releaseGroup(const Node &group) = 0; /** Remove a group AND all its children. If group is not a group-node, a typeError()-signal is emitted. Signal changed() ist emitted. \param group: the group */ virtual void deleteGroup(const Node &group) = 0; /** Remove and delete the given primitive from the plan (and possibly all of its children). Signal changed() ist emitted. \param primitive: reference to the primitive-node */ virtual void removePrimitive(const Node &primitive) = 0; /** Remove and delete all primitives from the plan (and possibly all of their children), that match the userData in the given list. Signal changed() ist emitted, after all primitves have been removed. \param primitive: reference to the primitive-node */ virtual void removePrimitivesByUserData(const QList &userDataList) = 0; /** Remove Text from a primitive, if any. Signal changed() ist emitted. \param parent: The node where to remove the text from */ virtual void removeText(Node &parent) = 0; /** Set the text-data of a text-node. If the given node is not a text-node, a typeError()-signal is emitted. Signal changed() ist emitted. \sa{ addText(), getText(), getTextData() } \param textNode: the text-node \param data: the text-data \param textAlign: the alignment of the text-data */ virtual void setTextData(const Node &textNode, const QString &data, HorizontalAlign textAlign) = 0; /** Translate a group or primitive. Signal changed() ist emitted. \param node: reference to the primitive-node \param x: translate horizontally by this value \param y: translate vertically by this value */ virtual void translateNode(const Node &node, double x, double y) = 0; /** Move a group or primitive to the given coordinates. Signal changed() ist emitted. \param node: reference to the primitive-node \param x: move horizontally to this value \param y: move vertically to this value */ virtual void moveNode(const Node &node, double x, double y) = 0; /** Scale the group or primitive. A primitive is scaled around the center of its bounding box. If a group is scaled, all children are scaled around the center of the groups bounding box. Signal changed() ist emitted. \param node: reference to the primitive-node \param scaleX: the x-scale-factor \param scaleY: the y-scale-factor */ virtual void scaleNode(const Node &node, double scaleX, double scaleY) = 0; /** Rotate a group or primitive. A primitive is rotated around the center of its bounding box. If a group is rotated, all children are rotated around the center of the groups bounding box. Signal changed() ist emitted. \param node: reference to the primitive or group \param angle: the rotation angle (ccw, 360 degree) */ virtual void rotateNode(const Node &node, double angle) = 0; /** Reorder Primitives in the plan. Signal changed() ist emitted. \param nodes: The primitives to reorder \param order: Move primitives up (Raise) or down (Lower) */ virtual void reorderPrimitives(const NodeList &nodes, PrimitivOrder order) = 0; /** Merge another Node into this one. All Primitives and GroupNodes of other are copied and added (appended) to this. Signal changed() ist emitted. \param other: the other plan or Node \param skipUndo: if true, the undo-stack is not updated \param intoNewGroup: If true, all merged primitives go into a new Group, while groups from the merged plan are removed. */ virtual void merge(const Node &other, bool skipUndo = false, bool intoNewGroup = false) = 0; /** Merge another plan into this one. All Primitives and GroupNodes of other are copied and added (appended) to this. Signal changed() ist emitted. \param other: the other plan or Node \param skipUndo: if true, the undo-stack is not updated \param intoNewGroup: If true, all merged primitives go into a new Group, while groups from the merged plan are removed. */ virtual void merge(GeometryModel *other, bool skipUndo = false, bool intoNewGroup = false) = 0; /** Undo the last change on the undo()-stack. To check, if there are undo()-steps available, check the size of the undo-stack with undoSteps() If inside of an undo-block, the block is closed, even if nested. Signal changed() ist emitted. \param steps: Go this many steps back in undo-history. If less than 1, undo does nothing, if greater than undo-steps available, undo goes only back that many steps. */ virtual void undo(unsigned int steps = 1) = 0; /** Redo the last change on redo-stack. To check, if there are redo-steps available, check the size of the redo-stack with redoSteps() \param steps: Go this many steps back in undo-history. If less than 1, redo does nothing, if greater than redo-steps available, redo goes only back that many steps. */ virtual void redo(unsigned int steps = 1) = 0; /** Enable or disable undo(). While undo() is disabled, no new actions will be recorded in the undo-stack. \param enabled: Bool to enable/disable undo() */ virtual void enableUndo(bool enable) = 0; /** Start a block of collected undo-steps. All modifications until endUndoBlock() are collected into one undo-Step. Nested undoBlocks are not possible. If already inside an undo-block, this method does nothing. undo() ends an undo-block. */ virtual void startUndoBlock() = 0; /** End a block of collected undo-steps. All collected modifications since the startUndoBlock() are now pushed into one undo-Step. Nested undoBlocks are not possible. If not inside an undo-block, this method does nothing. undo() also ends an undo-block. \param eventDescription: describe the last change. If == "", use last automatic entry. */ virtual void endUndoBlock(const QString &eventDescription = QString()) = 0; /** Abort recording a block of collected undo-steps. */ virtual void abortUndoBlock() = 0; /** Set the maximum number of undo-Steps. Default is 100. \param max: number of undo-Steps */ virtual void setMaxUndoSteps(unsigned int max) = 0; /** Return maximum number of undo-steps. */ virtual unsigned int maxUndoSteps() const = 0; /** Counting modifications of the model. */ virtual unsigned int modificationCounter() const = 0; /** Reset modification counter. */ virtual void resetModificationCounter() = 0; /** Remove all User-Data-Values-Attributes and empty groups from the model. ATTENTION: After this, many methods may return unexpected results. This slot/method should only be used before the model is written to a file or database. For each cleaned Attribute the signal userDataCleanup() is emitted. */ virtual void cleanModel() = 0; /** Clear the model. This deletes all primitives and groups. Signal changed() is emitted. */ virtual void clearModel() = 0; /** Add a primitive to the plan. If the given primitive-type does not exist, a typeError()-signal is emitted. Signal changed() ist emitted. \sa { typeError() } \param type: the type of a primitive \param points: a list of points to define the position/geometry of the primitive \param attributes: a list of attribute/value-pairs. If the list contains attributes, that are not supported by the primitive, or values, that do not fit into the attributes, a setAttributeError()-signal is emitted. \param userData: An int for creating simIDs \param textData: Add this text to the Primitive, if this is a text-Primitive \param textAlign: the alignment of the text-data, only used for text-primitive \return a reference to the new tree-element */ virtual Node addPrimitive(PrimitiveType type , const QList &points , const QList > &attributes , int userData = SituationMap::IdHandler::BadId , const QString &textData = QString() , HorizontalAlign textAlign = HorizontalAlign::Left) = 0; /** Set the defining points of a primitive If the number of points does not match the Primitives-definition, an attributeError() is emitted. \param node: reference to the primitive-node \param points: a list of points to define the position/geometry of the primitive \return true on success, false otherwise (i.e. wrong number of points) */ virtual bool setPrimitivePoints(const Node &node, const QList &points) = 0; /** Add a text-primitive to another primitive. A typeError()-signal is emitted, if the given parent-node can not have text. The returned node is a text-node. Signal changed() ist emitted. \sa { typeError(), addPrimitive(), setPrimitiveAttribute(), setTextData() } \param parent: The node where to insert text \param textData: Initial string for the text-element. \param textAlign: Initial aligment of the text-data. \param attributes: a list of attribute/value-pairs. If the list contains attributes, that are not supported by text-primitives, or values, that do not fit into the attributes, a setAttributeError()-signal is emitted. \param userData: An int for creating simIDs \return a reference to the new tree-element */ virtual Node addText(const Node &parent , const QString &textData , HorizontalAlign textAlign , const QList > &attributes , int userData = SituationMap::IdHandler::BadId) = 0; /** Retrieve the text-element from a primitive, if any. \param parent: the primitive where to get the text-node from \return the text-node, or a null-node, if parent has no text. */ virtual Node getText(const Node &parent) const = 0; /** Retrieve the text-data from a text-node. If the given node is not a text-node, a typeError() is emitted and an empty string returned. \sa{ getText() } \param textNode: the text-node \return a string with the text-data */ virtual QString getTextData(const Node &textNode) const = 0; /** Retrieve the defining points of a primitive If the primitive has no points, a signal planModelError() is emitted, since the model does not contain points where the user believes it should. \param node: reference to the primitive-node \return QList containing the QPointF of the primitive */ virtual QList getPrimitivePoints(const Node &node) const = 0; /** Return the bounding box of a primitive or group of primitives or the whole plan. If the given node has no bounding box (i.e. not a primitive) the resulting rect is not valid. \sa {translateNode(), moveNode(), rotateNode(), scaleNode() QRectF::isValid()} \param node: The primitive or group. */ virtual QRectF getBoundingBox(const Node &node) const = 0; /** Set user defined name of node, that will be used in GUI to label nodes. \param node The primitive or group \param name The name string */ virtual void setNodeDisplayName(const Node &node, const QString &name) = 0; /** Set user defined name of node, that will be used in GUI to label nodes. \param node The primitive or group */ virtual QString getNodeDisplayName(const Node &node) const = 0; /** Get a value for a global model-attribute. If the attribute does not exist in the model a setAttributeError()-signal is emitted. \sa { setModelAttribute(), setAttributeError(), hasAttribute(), attributeType() } \param attribute: the attribute to get */ virtual QVariant getModelAttribute(Attribute attribute) const = 0; /** Get the value of an attribute. If the attribute does not exist in the given node, a setAttributeError()-signal is emitted. \sa { setAttributeError(), hasAttribute(), attributeType() } \param node: reference to the primitive-node \param attribute: the attribute to get */ virtual QVariant getAttribute(const Node &node, Attribute attribute) const = 0; /** Get the value of an attribute of class type T from geometry model of type GeometryModelType. \see getAttribute */ template T getAttribute(const Node &node, Attribute attribute) const { const GeometryModelType *geoModelPtr = dynamic_cast(this); if (geoModelPtr) return geoModelPtr->template getAttribute(node, attribute); return T(); } // template T getAttribute( const Node & node, Attribute attribute ) const /** Check, if a given node has a specific attribute. \sa { setPlanAttribute(), getAttribute(), setAttributeError(), attributeType() } \param node: reference to the primitive-node \param attribute: the attribute to check */ virtual bool hasAttribute(const Node &node, Attribute attribute) const = 0; /** Get the type a an attribute. The type returned is a QVariant-type. \sa { setPlanAttribute(), getAttribute(), setAttributeError(), hasAttribute() } \param node: reference to the primitive-node \param attribute: the attribute to check */ virtual QVariant::Type attributeType(const Attribute &attribute) const = 0; /** Get a list of supported attributes from a primitive/node-type. If the given type does not exist, a typeError()-signal is emitted. \sa { setPlanAttribute(), getAttribute(), setAttributeError(), hasAttribute(), attributeType() } \param type: the type of a primitive */ virtual QList supportedAttributes(PrimitiveType type) const = 0; /** Create a group from a list of primitives. Signal changed() ist emitted. \sa{ addPrimitive() } \param primitives: A list of Elements which build the new group. May be empty. Primitives can be added later to the group with movePrimitiveIntoGroup() \return a reference to the new group */ virtual Node createGroup(const NodeList &primitives) = 0; /** If the given Primitive is in a group, return the Group-Node, otherwise return a Null-Node. \param primitive: The primitive to look up. \return A group-node or a Null-Node */ virtual Node isInGroup(const Node &primitive) const = 0; /** Return all primitives inside this group. If the given Node isn't a group, a typeError() is emitted. \param node: A group-node \return: List of primitives in this group, possibly empty. */ virtual NodeList getGroupPrimitives(const Node &node) = 0; /** Find a primitive by its corresponding userData-int. If there is no Primitive that corresponds to the userData, a Null-Node is returned. \sa{ QDomNode::isNull() } \param userData: An int for creating simIDs \return pointer to primitive-node or NULL */ virtual Node findPrimitive(int userData) const = 0; /** Return \c true in case of existing user data. Otherwise the return value is false. */ virtual bool hasUserData(const Node &node) const = 0; /** Get the userData from its corresponding primitive if any. If no userData is associated with this Primitive, 0 is returned and a typeError()-signal is sent and the bool opinted to by ok is set to false. Otherwise it is set to true. \param node: the primitive-node \return userData-int */ virtual int getUserData(const Node &node, bool *ok = nullptr) const = 0; /** Set the userData of a primitive. If this primitive can not have userData, a typeError()-signal is sent. \param node: pointer to the primitive-node \param userData: an int */ virtual void setUserData(const Node &node, int userData) = 0; /** Create and return a MultiMap with all UserData as Keys and the Primitives, that contain that data as values. Used for searching Primitives by their UserData (for example Selection-Check in GDW) \param node: Start search for UserData at this node. This is normally a Null-Node to search the whole tree. \return QMultiMap with UserData and corresponding Primitives */ virtual QMultiMap userDataMap(const Node &node = Node()) = 0; /** Create a copy of a group or primitive and insert it into the tree. If a group is copied, a deep copy including all its children is created. Signal changed() ist emitted. \param node: the group or primitive to copy. \param userData: An int for creating simIDs \return a reference to the new group (or NULL) */ virtual Node copy(const Node &node, int userData = SituationMap::IdHandler::BadId) = 0; /** Return the type of the given primitive. \param node: the primitive or group \return the type */ virtual PrimitiveType getType(const Node &node) const = 0; /** Return the number of undo-steps available. \return number of undo-steps on the undo-stack */ virtual unsigned int undoSteps() const = 0; /** Return the number of redo-steps available. \return number of redo-steps on the redo-stack */ virtual unsigned int redoSteps() const = 0; /** Return the undo history containing strings that describe the available undo-steps \return A list of strings */ virtual QStringList undoHistory() const = 0; /** Return the redo history containing strings that describe the available redo-steps \return A list of strings */ virtual QStringList redoHistory() const = 0; /** Clear the undo-stack */ virtual void clearUndoStack() = 0; /** Clear the redo-stack */ virtual void clearRedoStack() = 0; /** Return a attribute-name from the enum for signals and logging \param attribute: enum-value of attribute \return name of attribute as string */ virtual QString attributeToString(const Attribute &attribute) const = 0; /** Parsing the attribute string of a dictionary symbol. The result is written to \c attrMap \param sidcAttributes Attribute string \param attrMap Result of parsing process \return true in case of none errors, else false */ virtual bool parseSymbolAttributeString(const QString &sidcAttributes, QMap &attrMap) const = 0; /** Build attribute string to store at dictionary symbol. */ virtual QString buildSymbolAttributeString(const QMap &attrMap) const = 0; signals: /** A signal, that is emitted, when the plan changed. Only real changes are signaled to reduce unnecessary updates. \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 changed(const Node &node, GeometryModel::Attribute att, bool coordsChanged); /** A signal, that is emitted, when the settings of the plan-editor have changed. \param what: Short description of the change for logging */ void modelChanged(const QString &what); /** A signal, that is emitted, when an invalid type-parameter was given as argument. \param error: Short description of the error for logging */ void typeError(const QString &error); /** A signal, that is emitted, when an invalid attribute-parameter was given as argument. \param error: Short description of the error for logging */ void attributeError(const QString &error); /** A signal, that is emitted, when a method detects an error or inconsistency in the model. \param error: Short description of the error for logging */ void modelError(const QString &error); /** A signal, that is emitted, when a methode detects an error. */ void criticalError(const QString &error); /** This signal is emitted for each userData, when cleanModel() is called. \param userData: an int */ void userDataCleanup(int userData); /** The signal is emitted when undo has been called. */ void nodeCleanup(const Node &node); /** This signal is emitted for each connection created with \c Node::makeConnection() function, when cleanModel() is called. \param connectedPtr: an IdHandler::AccessableId * */ void connectionCleanup(Referenced *connectedPtr); /** This signal is emitted when the modification counter has been changed */ void modificationCount(unsigned int); }; } // namespace SituationMap