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 "arceditor.h"
19 #include "styleeditor.h"
20 #include "partarc.h"
21 #include "QPropertyUndoCommand/qpropertyundocommand.h"
22 #include "elementscene.h"
23 
24 /**
25 	Constructeur
26 	@param editor L'editeur d'element concerne
27 	@param arc L'arc a editer
28 	@param parent le Widget parent
29 */
ArcEditor(QETElementEditor * editor,PartArc * arc,QWidget * parent)30 ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) :
31 	ElementItemEditor(editor, parent),
32 	part(arc),
33 	m_locked(false)
34 {
35 	style_ = new StyleEditor(editor);
36 	x = new QDoubleSpinBox();
37 	y = new QDoubleSpinBox();
38 	h = new QDoubleSpinBox();
39 	v = new QDoubleSpinBox();
40 	start_angle = new QSpinBox();
41 	angle       = new QSpinBox();
42 	start_angle -> setRange(-360, 360);
43 	angle       -> setRange(-360, 360);
44 
45 	x->setRange(-5000, 5000);
46 	y->setRange(-5000, 5000);
47 	h->setRange(-5000, 5000);
48 	v->setRange(-5000, 5000);
49 
50 	QVBoxLayout *v_layout = new QVBoxLayout(this);
51 
52 	QGridLayout *grid = new QGridLayout();
53 	grid -> addWidget(new QLabel(tr("Centre : ")),            0, 0);
54 	grid -> addWidget(new QLabel("x"),                        1, 0, Qt::AlignRight);
55 	grid -> addWidget(x,                                      1, 1);
56 	grid -> addWidget(new QLabel("y"),                        1, 2);
57 	grid -> addWidget(y,                                      1, 3);
58 	grid -> addWidget(new QLabel(tr("Diamètres : ")),      2, 0);
59 	grid -> addWidget(new QLabel(tr("horizontal :")),         3, 0);
60 	grid -> addWidget(h,                                      3, 1);
61 	grid -> addWidget(new QLabel(tr("vertical :")),           4, 0);
62 	grid -> addWidget(v,                                      4, 1);
63 	grid -> addWidget(new QLabel(tr("Angle de départ :")), 5, 0);
64 	grid -> addWidget(start_angle,                            5, 1);
65 	grid -> addWidget(new QLabel(tr("Angle :")),              6, 0);
66 	grid -> addWidget(angle,                                  6, 1);
67 
68 	v_layout -> addWidget(style_);
69 	v_layout -> addLayout(grid);
70 	v_layout->addStretch();
71 
72 	updateForm();
73 
74 	activeConnections(true);
75 }
76 
77 /// Destructeur
~ArcEditor()78 ArcEditor::~ArcEditor() {}
79 
80 /**
81  * @brief ArcEditor::setPart
82  * Specifie to this editor the part to edit.
83  * Note that an editor can accept or refuse to edit a part. This editor accept only partArc.
84  * @param new_part
85  * @return
86  */
setPart(CustomElementPart * new_part)87 bool ArcEditor::setPart(CustomElementPart *new_part)
88 {
89 	if (!new_part)
90 	{
91 		if (part)
92 		{
93 			disconnect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm);
94 			disconnect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm);
95 			disconnect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm);
96 		}
97 		part = nullptr;
98 		style_ -> setPart(nullptr);
99 		return(true);
100 	}
101 
102 	if (PartArc *part_arc = dynamic_cast<PartArc *>(new_part))
103 	{
104 		if (part == part_arc) return true;
105 		if (part)
106 		{
107 			disconnect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm);
108 			disconnect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm);
109 			disconnect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm);
110 		}
111 		part = part_arc;
112 		style_ -> setPart(part);
113 		updateForm();
114 		connect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm);
115 		connect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm);
116 		connect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm);
117 		return(true);
118 	}
119 
120 	return(false);
121 }
122 
123 /**
124  * @brief ArcEditor::currentPart
125  * @return the curent edited part, or 0 if there is no edited part
126  */
currentPart() const127 CustomElementPart *ArcEditor::currentPart() const {
128 	return(part);
129 }
130 
131 /**
132  * @brief ArcEditor::updateArcS
133  * Update the start angle of the arc according to  the edited value.
134  */
updateArcS()135 void ArcEditor::updateArcS()
136 {
137 	if (m_locked) return;
138 	m_locked = true;
139 	double value = start_angle->value() * 16;
140 
141 	if (value != part->property("startAngle"))
142 	{
143 		QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "startAngle", part->property("startAngle"), value);
144 		undo->setText("Modifier l'angle de depart d'un arc");
145 		undo->enableAnimation();
146 		elementScene()->undoStack().push(undo);
147 	}
148 
149 	m_locked = false;
150 }
151 
152 /**
153  * @brief ArcEditor::updateArcA
154  * Update the span angle of the arc according to  the edited value.
155  */
updateArcA()156 void ArcEditor::updateArcA()
157 {
158 	if (m_locked) return;
159 	m_locked = true;
160 	double value = angle->value() * 16;
161 
162 	if (value != part->property("spanAngle"))
163 	{
164 		QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "spanAngle", part->property("spanAngle"), value);
165 		undo->setText("Modifier l'angle d'un arc");
166 		undo->enableAnimation();
167 		elementScene()->undoStack().push(undo);
168 	}
169 
170 	m_locked = false;
171 }
172 
173 /**
174  * @brief ArcEditor::updateArcRect
175  * Update the geometrie of the rect that define this arc according the the edited values
176  */
updateArcRect()177 void ArcEditor::updateArcRect()
178 {
179 	if (m_locked) return;
180 	m_locked = true;
181 	QPointF point = part->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2);
182 	QRectF rect(point, QSizeF(h->value(), v->value()));
183 
184 	if (rect != part->property("rect"))
185 	{
186 		QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "rect", part->property("rect"), rect);
187 		undo->setText("Modifier un arc");
188 		undo->enableAnimation();
189 		elementScene()->undoStack().push(undo);
190 	}
191 
192 	m_locked = false;
193 }
194 
195 /**
196  * @brief ArcEditor::updateForm
197  * Update the value of the widgets
198  */
updateForm()199 void ArcEditor::updateForm()
200 {
201 	if (!part) return;
202 	activeConnections(false);
203 	QRectF rect = part->property("rect").toRectF();
204 	x->setValue(part->mapToScene(rect.topLeft()).x() + (rect.width()/2));
205 	y->setValue(part->mapToScene(rect.topLeft()).y() + (rect.height()/2));
206 	h->setValue(rect.width());
207 	v->setValue(rect.height());
208 	start_angle->setValue(part->property("startAngle").toInt()/16);
209 	angle->setValue(part->property("spanAngle").toInt()/16);
210 	activeConnections(true);
211 }
212 
213 /**
214  * @brief ArcEditor::activeConnections
215  * Enable/disable connection between editor widget and slot editingFinished
216  * True == enable | false == disable
217  * @param active
218  */
activeConnections(bool active)219 void ArcEditor::activeConnections(bool active)
220 {
221 	if (active)
222 	{
223 		connect(x,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
224 		connect(y,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
225 		connect(h,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
226 		connect(v,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
227 		connect(start_angle, SIGNAL(editingFinished()), this, SLOT(updateArcS()));
228 		connect(angle,       SIGNAL(editingFinished()), this, SLOT(updateArcA()));
229 	}
230 	else
231 	{
232 		disconnect(x,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
233 		disconnect(y,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
234 		disconnect(h,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
235 		disconnect(v,           SIGNAL(editingFinished()), this, SLOT(updateArcRect()));
236 		disconnect(start_angle, SIGNAL(editingFinished()), this, SLOT(updateArcS()));
237 		disconnect(angle,       SIGNAL(editingFinished()), this, SLOT(updateArcA()));
238 	}
239 }
240