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

1029 lines
35 KiB
C++
Executable File

/**
**
** @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 <QtCore/QMultiMap>
#include <QtCore/QObject>
#include <QtCore/QPair>
#include <QtCore/QPointF>
#include <QtCore/QRectF>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
#include <QColor>
#include <QMetaType>
#include <Common/id_handler.h>
#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<Node>;
//! 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<int> &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<QPointF> &points
, const QList<QPair<Attribute, QVariant> > &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<QPointF> &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<QPair<Attribute, QVariant> > &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<QPointF> 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 <class T, class GeometryModelType> T getAttribute(const Node &node, Attribute attribute) const
{
const GeometryModelType *geoModelPtr = dynamic_cast<const GeometryModelType *>(this);
if (geoModelPtr)
return geoModelPtr->template getAttribute<T>(node, attribute);
return T();
} // template <class T, class GeometryModelType> 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<Attribute> 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<int, Node> 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<QString, QVariant> &attrMap) const = 0;
/**
Build attribute string to store at dictionary symbol.
*/
virtual QString buildSymbolAttributeString(const QMap<QString, QVariant> &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