1 /*
2 	Copyright 2006-2019 The QElectroTech Team
3 	This file is part of QElectroTech.
4 
5 	QElectroTech is free software: you can redistribute it and/or modify
6 	it under the terms of the GNU General Public License as published by
7 	the Free Software Foundation, either version 2 of the License, or
8 	(at your option) any later version.
9 
10 	QElectroTech is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU General Public License for more details.
14 
15 	You should have received a copy of the GNU General Public License
16 	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 #ifndef ELEMENT_H
19 #define ELEMENT_H
20 
21 #include "qet.h"
22 #include "qetgraphicsitem.h"
23 #include "diagramcontext.h"
24 #include "assignvariables.h"
25 #include "elementslocation.h"
26 #include "nameslist.h"
27 
28 #include <algorithm>
29 #include <QPicture>
30 
31 class QETProject;
32 class Terminal;
33 class Conductor;
34 class DynamicElementTextItem;
35 class ElementTextItemGroup;
36 
37 /**
38 	This is the base class for electrical elements.
39 */
40 class Element : public QetGraphicsItem
41 {
42 	friend class DiagramEventAddElement;
43 
44 	Q_OBJECT
45 	public:
46 			/**
47 			 * @brief The kind enum
48 			 * Used to know the kind of this element (master, slave, report ect...)
49 			 */
50 		enum kind {Simple = 1,
51 				   NextReport = 2,
52 				   PreviousReport = 4,
53 				   AllReport = 6,
54 				   Master = 8,
55 				   Slave = 16,
56 				   Terminale = 32};
57 
58 		Element(const ElementsLocation &location, QGraphicsItem * = nullptr, int *state = nullptr, Element::kind link_type = Element::Simple);
59 		~Element() override;
60 	private:
61 		Element(const Element &);
62 
63 		// attributes
64 	public:
65 			/**
66 			 * Enable the use of qgraphicsitem_cast to safely cast a QGraphicsItem into an Element.
67 			 * @return the QGraphicsItem type
68 			 */
69 		enum { Type = UserType + 1000 };
type()70 		int type() const override { return Type; }
71 
72 	signals:
73 		void linkedElementChanged(); //This signal is emited when the linked elements with this element change
74 		void elementInfoChange(DiagramContext old_info, DiagramContext new_info);
75 		void textAdded(DynamicElementTextItem *deti);
76 		void textRemoved(DynamicElementTextItem *deti);
77 		void textsGroupAdded(ElementTextItemGroup *group);
78 		void textsGroupAboutToBeRemoved(ElementTextItemGroup *group);
79 		void textAddedToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
80 		void textRemovedFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
81 
82 
83 	public:
84 		QList<Terminal *> terminals() const;
85 		QList<Conductor *> conductors() const;
86 		QList <QPair <Terminal *, Terminal *> > AlignedFreeTerminals () const;
87 
88 			//METHODS related to information
elementInformations()89 		DiagramContext  elementInformations    ()const              {return m_element_informations;}
90 		virtual void    setElementInformations (DiagramContext dc);
kindInformations()91 		DiagramContext  kindInformations       () const             {return m_kind_informations;}	//@kind_information_ is used to store more information
92 																									//about the herited class like contactelement for know
93 																									// kind of contact (simple tempo) or number of contact show by the element.
94 
sequenceStruct()95 		autonum::sequentialNumbers sequenceStruct () const {return m_autoNum_seq;}
rSequenceStruct()96 		autonum::sequentialNumbers& rSequenceStruct()      {return m_autoNum_seq;}
97 		void setUpFormula(bool code_letter = true);
98 		void setPrefix(QString);
99 		QString getPrefix() const;
100 		void freezeLabel(bool freeze);
isFreezeLabel()101 		bool isFreezeLabel() const {return m_freeze_label;}
102 		void freezeNewAddedElement();
103 
104 		QString name() const override;
105 		ElementsLocation location() const;
106 		virtual void setHighlighted(bool);
107 		void displayHelpLine(bool b = true);
108 		QSize size() const;
109 		QPixmap pixmap();
110         QPoint setHotspot(QPoint);
111         QPoint hotspot() const;
112         void editProperty() override;
113         static bool valideXml(QDomElement &);
114         virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &, bool = false);
115         virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
116         QUuid uuid() const;
117         int orientation() const;
118 
119 			//METHODS related to texts
120         void addDynamicTextItem(DynamicElementTextItem *deti = nullptr);
121         void removeDynamicTextItem(DynamicElementTextItem *deti);
122         QList<DynamicElementTextItem *> dynamicTextItems() const;
123 		ElementTextItemGroup *addTextGroup(const QString &name);
124 		void addTextGroup(ElementTextItemGroup *group);
125 		void removeTextGroup(ElementTextItemGroup *group);
126 		ElementTextItemGroup *textGroup(const QString &name) const;
127 		QList<ElementTextItemGroup *> textGroups() const;
128 		bool addTextToGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
129 		bool removeTextFromGroup(DynamicElementTextItem *text, ElementTextItemGroup *group);
130 
131 			//METHODS related to linked element
132 				bool isFree            () const;
linkToElement(Element *)133 		virtual void linkToElement     (Element *) {}
unlinkAllElements()134 		virtual void unlinkAllElements () {}
unlinkElement(Element *)135 		virtual void unlinkElement     (Element *) {}
136 		virtual void initLink          (QETProject *);
137 		QList<Element *> linkedElements ();
linkType()138 		virtual kind linkType() const {return m_link_type;} // @return the linkable type
newUuid()139 		void newUuid() {m_uuid = QUuid::createUuid();} 	//create new uuid for this element
140 
141 	protected:
142 		void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
143 		void setSize(int, int);
144 
145 	private:
146 		void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
147 		void drawHighlight(QPainter *, const QStyleOptionGraphicsItem *);
148 		bool buildFromXml(const QDomElement &, int * = nullptr);
149 		bool parseElement(const QDomElement &dom);
150 		bool parseInput(const QDomElement &dom_element);
151 		DynamicElementTextItem *parseDynamicText(const QDomElement &dom_element);
152 		Terminal *parseTerminal(const QDomElement &dom_element);
153 
154 		//Reimplemented from QGraphicsItem
155 	public:
156 		void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
157 		QRectF boundingRect() const override;
158 	protected:
159 		void mouseMoveEvent    ( QGraphicsSceneMouseEvent *event ) override;
160 		void mouseReleaseEvent ( QGraphicsSceneMouseEvent *event ) override;
161 		void hoverEnterEvent   ( QGraphicsSceneHoverEvent * ) override;
162 		void hoverLeaveEvent   ( QGraphicsSceneHoverEvent * ) override;
163 
164 	protected:
165 			// @m_converted_text_from_description, when a element is created from his description, the old element text item (tagged as 'input' in the xml)
166 			// are converted to dynamic text field, the QPointF is the original position of the text item, because the origin transformation point of text item
167 			// and dynamic text item are not the same, so we must to keep a track of this value, to be use in the function element::fromXml
168 		QHash <DynamicElementTextItem *, QPointF> m_converted_text_from_xml_description;
169 
170 			//ATTRIBUTES related to linked element
171 		QList <Element *> connected_elements;
172 		QList <QUuid>     tmp_uuids_link;
173 		QUuid             m_uuid;
174 		kind              m_link_type = Element::Simple;
175 
176 			//ATTRIBUTES related to informations
177 		DiagramContext m_element_informations, m_kind_informations;
178 		autonum::sequentialNumbers m_autoNum_seq;
179 		bool m_freeze_label = false;
180 		QString m_F_str;
181 
182 		ElementsLocation m_location;
183 		NamesList m_names;
184 		QList <Terminal *> m_terminals;
185 		const QPicture m_picture;
186 		const QPicture m_low_zoom_picture;
187 
188 	private:
189 		bool m_must_highlight = false;
190 		QSize   dimensions;
191 		QPoint  hotspot_coord;
192 		bool m_mouse_over = false;
193 		QString m_prefix;
194         QList <DynamicElementTextItem *> m_dynamic_text_list;
195 		QList <ElementTextItemGroup *> m_texts_group;
196 
197 };
198 
199 bool comparPos(const Element * elmt1, const Element * elmt2);
200 
isFree()201 inline bool Element::isFree() const {
202 	return (connected_elements.isEmpty());
203 }
204 
205 /**
206 	Indicate the current orientation of this element
207 	O = 0°
208 	1 = 90°
209 	2 = 180°
210 	3 = 270°
211 	@return the current orientation of this element
212 */
orientation()213 inline int Element::orientation() const {
214 	return(QET::correctAngle(rotation())/90);
215 }
216 
217 /**
218  * @brief Element::uuid
219  * @return the uuid of this element
220  */
uuid()221 inline QUuid Element::uuid() const {
222 	return m_uuid;
223 }
224 
225 /**
226  * @brief Element::linkedElements
227  * @return the list of linked elements, the list is sorted by position
228  */
linkedElements()229 inline QList <Element *> Element::linkedElements() {
230 	 std::sort(connected_elements.begin(), connected_elements.end(), comparPos);
231 	return connected_elements;
232 }
233 
234 #endif
235