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 #include "masterelement.h"
19 #include "crossrefitem.h"
20 #include "diagram.h"
21 #include "dynamicelementtextitem.h"
22 #include <QRegularExpression>
23 
24 /**
25  * @brief MasterElement::MasterElement
26  * Default constructor
27  * @param location location of xml definition
28  * @param qgi parent QGraphicItem
29  * @param s parent diagram
30  * @param state int used to know if the creation of element have error
31  */
MasterElement(const ElementsLocation & location,QGraphicsItem * qgi,int * state)32 MasterElement::MasterElement(const ElementsLocation &location, QGraphicsItem *qgi, int *state) :
33 	Element(location, qgi, state, Element::Master)
34 {}
35 
36 /**
37  * @brief MasterElement::~MasterElement
38  * default destructor
39  */
~MasterElement()40 MasterElement::~MasterElement() {
41 	unlinkAllElements();
42 }
43 
44 /**
45  * @brief MasterElement::linkToElement
46  * Link this master to another element
47  * For this class element must be a slave
48  * @param elmt
49  */
linkToElement(Element * elmt)50 void MasterElement::linkToElement(Element *elmt)
51 {
52 		// check if element is slave and if isn't already linked
53 	if (elmt->linkType() == Slave && !connected_elements.contains(elmt))
54 	{
55 		connected_elements << elmt;
56 		elmt->linkToElement(this);
57 
58 		XRefProperties xrp = diagram()->project()->defaultXRefProperties(kindInformations()["type"].toString());
59 		if (!m_Xref_item && xrp.snapTo() == XRefProperties::Bottom)
60 			m_Xref_item = new CrossRefItem(this); //create cross ref item if not yet
61 		else
62 			aboutDeleteXref();
63 
64 		emit linkedElementChanged();
65 	}
66 }
67 
68 /**
69  * @brief MasterElement::unlinkAllElements
70  * Unlink all of the element in the QList connected_elements
71  */
unlinkAllElements()72 void MasterElement::unlinkAllElements()
73 {
74 		// if this element is free no need to do something
75 	if (!isFree())
76 	{
77 		foreach(Element *elmt, connected_elements)
78 			unlinkElement(elmt);
79 		emit linkedElementChanged();
80 	}
81 }
82 
83 /**
84  * @brief MasterElement::unlinkElement
85  * Unlink the given elmt in parametre
86  * @param elmt element to unlink from this
87  */
unlinkElement(Element * elmt)88 void MasterElement::unlinkElement(Element *elmt)
89 {
90 		//Ensure elmt is linked to this element
91 	if (connected_elements.contains(elmt))
92 	{
93 		connected_elements.removeOne(elmt);
94 		elmt -> unlinkElement  (this);
95 		elmt -> setHighlighted (false);
96 
97 		aboutDeleteXref();
98 		emit linkedElementChanged();
99 	}
100 }
101 
102 /**
103  * @brief MasterElement::initLink
104  * @param project
105  * Call init Link from custom element and after
106  * call update label for setup it.
107  */
initLink(QETProject * project)108 void MasterElement::initLink(QETProject *project) {
109 	//Create the link with other element if needed
110 	Element::initLink(project);
111 }
112 
113 /**
114  * @brief MasterElement::XrefBoundingRect
115  * @return The bounding rect of the Xref, if this element
116  * haven't got a xref, return a default QRectF
117  */
XrefBoundingRect() const118 QRectF MasterElement::XrefBoundingRect() const
119 {
120 	if(m_Xref_item)
121 		return m_Xref_item->boundingRect();
122 	else
123 		return QRectF();
124 }
125 
itemChange(QGraphicsItem::GraphicsItemChange change,const QVariant & value)126 QVariant MasterElement::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
127 {
128 	if(change == QGraphicsItem::ItemSceneHasChanged && m_first_scene_change)
129 	{
130 		m_first_scene_change = false;
131 		connect(diagram()->project(), &QETProject::XRefPropertiesChanged, this, &MasterElement::xrefPropertiesChanged);
132 	}
133 	return Element::itemChange(change, value);
134 }
135 
xrefPropertiesChanged()136 void MasterElement::xrefPropertiesChanged()
137 {
138 	if(!diagram())
139 		return;
140 
141 	XRefProperties xrp = diagram()->project()->defaultXRefProperties(kindInformations()["type"].toString());
142 	if(xrp.snapTo() == XRefProperties::Bottom)
143 	{
144 			//We create a Xref, and just after we call aboutDeleteXref,
145 			//because the Xref may be useless.
146 		if(!m_Xref_item)
147 			m_Xref_item = new CrossRefItem(this);
148 	}
149 	aboutDeleteXref();
150 }
151 
152 /**
153  * @brief MasterElement::aboutDeleteXref
154  * Check if Xref item must be displayed, if not, delete it.
155  * If Xref item is deleted or already not used (nullptr) return true;
156  * Else return false if Xref item is used
157  * NOTICE : Xref can display nothing but not be deleted so far.
158  * For exemple, if Xref is display has cross, only power contact are linked and
159  * option show power contact is disable, the cross isn't draw.
160  * @return
161  */
aboutDeleteXref()162 void MasterElement::aboutDeleteXref()
163 {
164 	if(!m_Xref_item)
165 		return;
166 
167 	XRefProperties xrp = diagram()->project()->defaultXRefProperties(kindInformations()["type"].toString());
168 	if (xrp.snapTo() != XRefProperties::Bottom && m_Xref_item)
169 	{
170 		delete m_Xref_item;
171 		m_Xref_item = nullptr;
172 		return;
173 	}
174 
175 	if (m_Xref_item->boundingRect().isNull())
176 	{
177 		delete m_Xref_item;
178 		m_Xref_item = nullptr;
179 		return;
180 	}
181 }
182