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 "styleeditor.h"
19 #include "customelementgraphicpart.h"
20 #include "QPropertyUndoCommand/qpropertyundocommand.h"
21 #include <QComboBox>
22 #include <QCheckBox>
23 #include <QVBoxLayout>
24 #include <QHBoxLayout>
25 #include <QLabel>
26 
27 /**
28 	Constructeur
29 	@param editor L'editeur d'element concerne
30 	@param p La partie a editer
31 	@param parent le Widget parent
32 */
StyleEditor(QETElementEditor * editor,CustomElementGraphicPart * p,QWidget * parent)33 StyleEditor::StyleEditor(QETElementEditor *editor, CustomElementGraphicPart *p, QWidget *parent) :
34 	ElementItemEditor(editor, parent),
35 	part(p)
36 {
37 	// couleur
38 	outline_color = new QComboBox(this);
39 	outline_color -> addItem(tr("Noir", "element part color"), CustomElementGraphicPart::BlackColor);
40 	outline_color -> addItem(tr("Blanc", "element part color"), CustomElementGraphicPart::WhiteColor);
41 	outline_color -> addItem(tr("Vert", "element part color"), CustomElementGraphicPart::GreenColor);
42 	outline_color -> addItem(tr("Rouge", "element part color"), CustomElementGraphicPart::RedColor);
43 	outline_color -> addItem(tr("Bleu", "element part color"), CustomElementGraphicPart::BlueColor);
44 	outline_color -> addItem(tr("Gris", "element part color"), CustomElementGraphicPart::GrayColor);
45 	outline_color -> addItem(tr("Marron", "element part color"), CustomElementGraphicPart::BrunColor);
46 	outline_color -> addItem(tr("Jaune", "element part color"), CustomElementGraphicPart::YellowColor);
47 	outline_color -> addItem(tr("Cyan", "element part color"), CustomElementGraphicPart::CyanColor);
48 	outline_color -> addItem(tr("Magenta", "element part color"), CustomElementGraphicPart::MagentaColor);
49 	outline_color -> addItem(tr("Gris clair", "element part color"), CustomElementGraphicPart::LightgrayColor);
50 	outline_color -> addItem(tr("Orange", "element part color"), CustomElementGraphicPart::OrangeColor);
51 	outline_color -> addItem(tr("Violet", "element part color"), CustomElementGraphicPart::PurpleColor);
52 	outline_color -> addItem(tr("Aucun", "element part color"), CustomElementGraphicPart::NoneColor);
53 
54 	// style
55 	line_style = new QComboBox(this);
56 	line_style -> addItem(tr("Normal",       "element part line style"), CustomElementGraphicPart::NormalStyle);
57 	line_style -> addItem(tr("Tiret",        "element part line style"), CustomElementGraphicPart::DashedStyle);
58 	line_style -> addItem(tr("Pointillé", "element part line style"), CustomElementGraphicPart::DottedStyle);
59 	line_style -> addItem(tr("Traits et points", "element part line style"), CustomElementGraphicPart::DashdottedStyle);
60 	//normal_style -> setChecked(true);
61 
62 	// epaisseur
63 	size_weight = new QComboBox(this);
64 	size_weight -> addItem(tr("Nulle", "element part weight"),  CustomElementGraphicPart::NoneWeight);
65 	size_weight -> addItem(tr("Fine", "element part weight"),  CustomElementGraphicPart::ThinWeight);
66 	size_weight -> addItem(tr("Normale", "element part weight"),  CustomElementGraphicPart::NormalWeight);
67 	size_weight -> addItem(tr("Forte", "element part weight"),  CustomElementGraphicPart::UltraWeight);
68 	size_weight -> addItem(tr("Élevé", "element part weight"),  CustomElementGraphicPart::BigWeight);
69 
70 	// remplissage
71 	filling_color = new QComboBox (this);
72 	filling_color -> addItem(tr("Aucun", "element part filling"), CustomElementGraphicPart::NoneFilling);
73 	filling_color -> addItem(tr("Noir", "element part filling"), CustomElementGraphicPart::BlackFilling);
74 	filling_color -> addItem(tr("Blanc", "element part filling"), CustomElementGraphicPart::WhiteFilling);
75 	filling_color -> addItem(tr("Vert", "element part filling"), CustomElementGraphicPart::GreenFilling);
76 	filling_color -> addItem(tr("Rouge", "element part filling"), CustomElementGraphicPart::RedFilling);
77 	filling_color -> addItem(tr("Bleu", "element part filling"), CustomElementGraphicPart::BlueFilling);
78 	filling_color -> addItem(tr("Gris", "element part filling"), CustomElementGraphicPart::GrayFilling);
79 	filling_color -> addItem(tr("Marron", "element part filling"), CustomElementGraphicPart::BrunFilling);
80 	filling_color -> addItem(tr("Jaune", "element part filling"), CustomElementGraphicPart::YellowFilling);
81 	filling_color -> addItem(tr("Cyan", "element part filling"), CustomElementGraphicPart::CyanFilling);
82 	filling_color -> addItem(tr("Magenta", "element part filling"), CustomElementGraphicPart::MagentaFilling);
83 	filling_color -> addItem(tr("Gris clair", "element part filling"), CustomElementGraphicPart::LightgrayFilling);
84 	filling_color -> addItem(tr("Orange", "element part filling"), CustomElementGraphicPart::OrangeFilling);
85 	filling_color -> addItem(tr("Violet", "element part filling"), CustomElementGraphicPart::PurpleFilling);
86 	filling_color -> addItem(tr("Lignes Horizontales", "element part filling"), CustomElementGraphicPart::HorFilling);
87 	filling_color -> addItem(tr("Lignes Verticales", "element part filling"), CustomElementGraphicPart::VerFilling);
88 	filling_color -> addItem(tr("Hachures gauche", "element part filling"), CustomElementGraphicPart::BdiagFilling);
89 	filling_color -> addItem(tr("Hachures droite", "element part filling"), CustomElementGraphicPart::FdiagFilling);
90 
91 	// antialiasing
92 	antialiasing = new QCheckBox(tr("Antialiasing"));
93 
94 	updateForm();
95 
96 	main_layout = new QVBoxLayout();
97 	main_layout -> setMargin(0);
98 
99 	main_layout -> addWidget(new QLabel("<u>" + tr("Apparence :") + "</u> "));
100 
101 	QHBoxLayout *color_layout = new QHBoxLayout();
102 	color_layout -> addWidget(new QLabel(tr("Contour :")), 0, Qt::AlignRight);
103 	color_layout -> addWidget(outline_color);
104 	color_layout -> addSpacing(10);
105 	color_layout -> addWidget(new QLabel(tr("Remplissage :")), 0, Qt::AlignRight);
106 	color_layout -> addWidget(filling_color);
107 	main_layout -> addLayout(color_layout);
108 
109 	QHBoxLayout *style_layout = new QHBoxLayout();
110 	style_layout -> addWidget(new QLabel(tr("Style : ")), 0, Qt::AlignRight);
111 	style_layout -> addWidget(line_style);
112 	style_layout -> addSpacing(10);
113 	style_layout -> addWidget(new QLabel(tr("Épaisseur : ")), 0, Qt::AlignRight);
114 	style_layout -> addWidget(size_weight);
115 	main_layout -> addLayout(style_layout);
116 
117 	main_layout -> addWidget(antialiasing);
118 
119 	main_layout -> addSpacing(10);
120 	main_layout -> addWidget(new QLabel("<u>" + tr("Géométrie :") + "</u> "));
121 	setLayout(main_layout);
122 }
123 
124 /// Destructeur
~StyleEditor()125 StyleEditor::~StyleEditor() {
126 }
127 
128 /// Update antialiasing with undo command
updatePartAntialiasing()129 void StyleEditor::updatePartAntialiasing() {
130 	makeUndo(tr("style antialiasing"), "antialias", antialiasing -> isChecked());
131 }
132 
133 /// Update color with undo command
updatePartColor()134 void StyleEditor::updatePartColor() {
135 	makeUndo(tr("style couleur"),"color", outline_color->itemData(outline_color -> currentIndex()));
136 }
137 
138 /// Update style with undo command
updatePartLineStyle()139 void StyleEditor::updatePartLineStyle() {
140 	makeUndo(tr("style ligne"), "line_style", line_style->itemData(line_style -> currentIndex()));
141 }
142 
143 /// Update weight with undo command
updatePartLineWeight()144 void StyleEditor::updatePartLineWeight() {
145 	makeUndo(tr("style epaisseur"), "line_weight", size_weight->itemData(size_weight -> currentIndex()));
146 }
147 
148 /// Update color filling with undo command
updatePartFilling()149 void StyleEditor::updatePartFilling() {
150 	makeUndo(tr("style remplissage"), "filling", filling_color->itemData(filling_color -> currentIndex()));
151 }
152 
153 /**
154  * @brief StyleEditor::updateForm
155  * Update the edition form according to the value of edited part(s)
156  */
updateForm()157 void StyleEditor::updateForm()
158 {
159 	if (!part && m_part_list.isEmpty()) return;
160 	activeConnections(false);
161 
162 	if (part)
163 	{
164 		antialiasing -> setChecked(part -> antialiased());
165 		outline_color -> setCurrentIndex(part -> color());
166 		line_style    -> setCurrentIndex(part -> lineStyle());
167 		size_weight   -> setCurrentIndex(part -> lineWeight());
168 		filling_color -> setCurrentIndex(part -> filling());
169 	}
170 	else if (m_part_list.size())
171 	{
172 		CustomElementGraphicPart *first_part = m_part_list.first();
173 		antialiasing -> setChecked(first_part -> antialiased());
174 		outline_color -> setCurrentIndex(first_part -> color());
175 		line_style    -> setCurrentIndex(first_part -> lineStyle());
176 		size_weight   -> setCurrentIndex(first_part -> lineWeight());
177 		filling_color -> setCurrentIndex(first_part -> filling());
178 
179 		foreach (CustomElementGraphicPart *cegp, m_part_list)
180 		{
181 			if (first_part -> antialiased() != cegp -> antialiased()) antialiasing -> setChecked(false);
182 			if (first_part -> color()       != cegp -> color())      outline_color -> setCurrentIndex(-1);
183 			if (first_part -> lineStyle()   != cegp -> lineStyle())  line_style    -> setCurrentIndex(-1);
184 			if (first_part -> lineWeight()  != cegp -> lineWeight()) size_weight   -> setCurrentIndex(-1);
185 			if (first_part -> filling()     != cegp -> filling())    filling_color -> setCurrentIndex(-1);
186 		}
187 	}
188 
189 	activeConnections(true);
190 }
191 
192 /**
193  * @brief StyleEditor::setPart
194  * Set the part to edit by this editor.
195  * Note : editor can accept or refuse to edit a part
196  * @param new_part : part to edit
197  * @return  true if editor accept to edit this CustomElementPart otherwise false
198  */
setPart(CustomElementPart * new_part)199 bool StyleEditor::setPart(CustomElementPart *new_part) {
200 	m_part_list.clear();
201 
202 	if (!new_part)
203 	{
204 		part = nullptr;
205 		return(true);
206 	}
207 
208 	if (CustomElementGraphicPart *part_graphic = dynamic_cast<CustomElementGraphicPart *>(new_part))
209 	{
210 		part = part_graphic;
211 		updateForm();
212 		return(true);
213 	}
214 
215 	return(false);
216 }
217 
218 /**
219  * @brief StyleEditor::setParts
220  * Set several parts to edit by this editor.
221  * Note : editor can accept or refuse to edit several parts.
222  * @param part_list
223  * @return true if every customeElementPart stored in part_list can
224  * be edited by this part editor, otherwise return false
225  * (see StyleEditor::isStyleEditable)
226  */
setParts(QList<CustomElementPart * > part_list)227 bool StyleEditor::setParts(QList<CustomElementPart *> part_list)
228 {
229 	if (part_list.isEmpty()) return false;
230 	if (part_list.size() == 1) return setPart(part_list.first());
231 
232 	part = nullptr;
233 	m_part_list.clear();
234 	m_cep_list.clear();
235 
236 	if (!isStyleEditable(part_list)) return false;
237 
238 	foreach (CustomElementPart *cep, part_list)
239 	{
240 		if (CustomElementGraphicPart *cegp = dynamic_cast<CustomElementGraphicPart *>(cep))
241 			m_part_list << cegp;
242 		else
243 			return false;
244 	}
245 
246 	foreach (CustomElementGraphicPart *cegp, m_part_list)
247 		m_cep_list << cegp;
248 
249 	updateForm();
250 	return true;
251 }
252 
253 /**
254 	@return la primitive actuellement editee, ou 0 si ce widget n'en edite pas
255 */
currentPart() const256 CustomElementPart *StyleEditor::currentPart() const {
257 	return(part);
258 }
259 
260 /**
261  * @brief StyleEditor::isStyleEditable
262  * @param cep_list
263  * @return true if all of the content of cep_list can be edited by style editor, else return false.
264  */
isStyleEditable(QList<CustomElementPart * > cep_list)265 bool StyleEditor::isStyleEditable(QList<CustomElementPart *> cep_list)
266 {
267 	QStringList str;
268 	str << "arc" << "ellipse" << "line" << "polygon" << "rect";
269 
270 	foreach (CustomElementPart *cep, cep_list)
271 		if (!str.contains(cep -> xmlName()))
272 			return false;
273 
274 	return true;
275 }
276 
277 /**
278 	Active ou desactive les connexionx signaux/slots entre les widgets internes.
279 	@param active true pour activer les connexions, false pour les desactiver
280 */
activeConnections(bool active)281 void StyleEditor::activeConnections(bool active) {
282 	if (active) {
283 		connect (outline_color, SIGNAL(activated(int)), this, SLOT(updatePartColor()));
284 		connect(line_style,        SIGNAL(activated(int)), this, SLOT(updatePartLineStyle()));
285 		connect(size_weight,       SIGNAL(activated(int)), this, SLOT(updatePartLineWeight()));
286 		connect(filling_color, SIGNAL(activated(int)), this, SLOT(updatePartFilling()));
287 		connect(antialiasing, SIGNAL(stateChanged(int)),  this, SLOT(updatePartAntialiasing()));
288 	} else {
289 		disconnect(outline_color, SIGNAL(activated(int)), this, SLOT(updatePartColor()));
290 		disconnect(line_style,        SIGNAL(activated(int)), this, SLOT(updatePartLineStyle()));
291 		disconnect(size_weight,       SIGNAL(activated(int)), this, SLOT(updatePartLineWeight()));
292 		disconnect(filling_color, SIGNAL(activated(int)), this, SLOT(updatePartFilling()));
293 		disconnect(antialiasing, SIGNAL(stateChanged(int)),  this, SLOT(updatePartAntialiasing()));
294 	}
295 }
296 
makeUndo(const QString & undo_text,const char * property_name,const QVariant & new_value)297 void StyleEditor::makeUndo(const QString &undo_text, const char *property_name, const QVariant &new_value)
298 {
299 	QPropertyUndoCommand *undo = nullptr;
300 	if (part && (new_value != part->property(property_name)))
301 	{
302 		undo = new QPropertyUndoCommand(part, property_name, part->property(property_name), new_value);
303 		undo->setText(undo_text);
304 		undoStack().push(undo);
305 		return;
306 	}
307 	else if (!m_part_list.isEmpty())
308 	{
309 		foreach (CustomElementGraphicPart *cegp, m_part_list)
310 		{
311 			if (!undo)
312 			{
313 				undo = new QPropertyUndoCommand(cegp, property_name, cegp->property(property_name), new_value);
314 				undo->setText(undo_text);
315 			}
316 			else
317 				new QPropertyUndoCommand(cegp, property_name, cegp->property(property_name), new_value, undo);
318 		}
319 		undoStack().push(undo);
320 	}
321 }
322