1029 lines
35 KiB
C++
Executable File
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
|
|
|
|
|