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 "conductorcreator.h"
19 #include "diagram.h"
20 #include "qgraphicsitem.h"
21 #include "terminal.h"
22 #include "conductor.h"
23 #include "potentialselectordialog.h"
24 #include "diagramcommands.h"
25 #include "conductorautonumerotation.h"
26 #include "element.h"
27
28 #include <QPolygonF>
29
30 /**
31 * @brief ConductorCreator::ConductorCreator
32 * Create an electrical potential between all terminals of @terminals_list.
33 * the terminals of the list must be in the same diagram.
34 * @param terminals_list
35 */
ConductorCreator(Diagram * d,QList<Terminal * > terminals_list)36 ConductorCreator::ConductorCreator(Diagram *d, QList<Terminal *> terminals_list) :
37 m_terminals_list(terminals_list)
38 {
39 if (m_terminals_list.size() <= 1) {
40 return;
41 }
42 m_properties = m_terminals_list.first()->diagram()->defaultConductorProperties;
43
44 setUpPropertieToUse();
45 Terminal *hub_terminal = hubTerminal();
46
47 d->undoStack().beginMacro(QObject::tr("Création de conducteurs"));
48
49 QList<Conductor *> c_list;
50 for (Terminal *t : m_terminals_list)
51 {
52 if (t == hub_terminal) {
53 continue;
54 }
55
56 Conductor *cond = new Conductor(hub_terminal, t);
57 cond->setProperties(m_properties);
58 cond->setSequenceNum(m_sequential_number);
59 d->undoStack().push(new AddItemCommand<Conductor *>(cond, d));
60
61 c_list.append(cond);
62 }
63 d->undoStack().endMacro();
64
65 for(Conductor *c : c_list) {
66 c->refreshText();
67 }
68 }
69
70 /**
71 * @brief ConductorCreator::create
72 * Create an electrical potential between the terminals of the diagram d, contained in the polygon
73 * @param d
74 * @param polygon : polygon in diagram coordinate
75 */
create(Diagram * d,const QPolygonF & polygon)76 void ConductorCreator::create(Diagram *d, const QPolygonF &polygon)
77 {
78 QList<Terminal *> t_list;
79
80 for (QGraphicsItem *item : d->items(polygon))
81 {
82 if (item->type() == Terminal::Type) {
83 t_list.append(qgraphicsitem_cast<Terminal *>(item));
84 }
85 }
86
87 if (t_list.size() <= 1) {
88 return;
89 } else {
90 ConductorCreator cc(d, t_list);
91 }
92 }
93
94 /**
95 * @brief ConductorCreator::propertieToUse
96 * @return the conductor properties to use for the new conductors.
97 */
setUpPropertieToUse()98 void ConductorCreator::setUpPropertieToUse()
99 {
100 QList<Conductor *> potentials = existingPotential();
101
102 //There is an existing potential
103 //we get one of them
104 if (!potentials.isEmpty())
105 {
106 if (potentials.size() >= 2)
107 {
108 QList <ConductorProperties> cp_list;
109 for(Conductor *c : potentials) {
110 cp_list.append(c->properties());
111 }
112
113 m_properties = PotentialSelectorDialog::chosenProperties(cp_list);
114 for (Conductor *c : potentials) {
115 if (c->properties() == m_properties) {
116 m_sequential_number = c->sequenceNum();
117 }
118 }
119 }
120 else if (potentials.size() == 1)
121 {
122 m_properties = potentials.first()->properties();
123 m_sequential_number = potentials.first()->sequenceNum();
124 }
125 return;
126 }
127
128 //get a new properties
129 ConductorAutoNumerotation::newProperties(m_terminals_list.first()->diagram(), m_properties, m_sequential_number);
130 }
131
132 /**
133 * @brief ConductorCreator::existingPotential
134 * Return the list of existing potential of
135 * the terminal list
136 * @return
137 */
existingPotential()138 QList<Conductor *> ConductorCreator::existingPotential()
139 {
140 QList<Conductor *> c_list;
141 QList<Terminal *> t_exclude;
142
143 for (Terminal *t : m_terminals_list)
144 {
145 if (t_exclude.contains(t)) {
146 continue;
147 }
148
149 if (!t->conductors().isEmpty())
150 {
151 c_list.append(t->conductors().first());
152
153 //We must to check m_terminals_list contain a terminal
154 //in the same potential of c, and if true, exclude this terminal from the search.
155 for (Conductor *c : t->conductors().first()->relatedPotentialConductors(false))
156 {
157 if (m_terminals_list.contains(c->terminal1)) {
158 t_exclude.append(c->terminal1);
159 } else if (m_terminals_list.contains(c->terminal2)) {
160 t_exclude.append(c->terminal2);
161 }
162 }
163 }
164 else if (t->parentElement()->linkType() & Element::AllReport && !t->parentElement()->isFree())
165 {
166 Element *linked_report = t->parentElement()->linkedElements().first();
167 if (!linked_report->conductors().isEmpty()) {
168 c_list.append(linked_report->conductors().first());
169 }
170 }
171 }
172
173 return c_list;
174 }
175
176 /**
177 * @brief ConductorCreator::hubTerminal
178 * @return
179 */
hubTerminal()180 Terminal *ConductorCreator::hubTerminal()
181 {
182 Terminal *hub_terminal = m_terminals_list.first();
183
184 for (Terminal *tt : m_terminals_list)
185 {
186 if (tt->scenePos().x() < hub_terminal->scenePos().x()) {
187 hub_terminal = tt;
188 } else if (tt->scenePos().x() == hub_terminal->scenePos().x()) {
189 if (tt->scenePos().y() < hub_terminal->scenePos().y()) {
190 hub_terminal = tt;
191 }
192 }
193 }
194
195 return hub_terminal;
196 }
197