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 "conductorproperties.h"
19 #include <QPainter>
20 #include <utility>
21 
22 /**
23 	Constructeur par defaut
24 */
SingleLineProperties()25 SingleLineProperties::SingleLineProperties() :
26 	hasGround(true),
27 	hasNeutral(true),
28 	is_pen(false),
29 	phases(1)
30 {
31 }
32 
33 /// Destructeur
~SingleLineProperties()34 SingleLineProperties::~SingleLineProperties() {
35 }
36 
37 /**
38 	Definit le nombre de phases (0, 1, 2, ou 3)
39 	@param n Nombre de phases
40 */
setPhasesCount(int n)41 void SingleLineProperties::setPhasesCount(int n) {
42 	phases = qBound(0, n, 3);
43 }
44 
45 /// @return le nombre de phases (0, 1, 2, ou 3)
phasesCount()46 unsigned short int SingleLineProperties::phasesCount() {
47 	return(phases);
48 }
49 
50 /**
51 	@return true if the singleline conductor should be drawn using the PEN
52 	(Protective Earth Neutral) representation and if it features the ground and
53 	the neutral.
54 */
isPen() const55 bool SingleLineProperties::isPen() const {
56 	return(hasNeutral && hasGround && is_pen);
57 }
58 
59 /**
60 	Dessine les symboles propres a un conducteur unifilaire
61 	@param painter QPainter a utiliser pour dessiner les symboles
62 	@param direction direction du segment sur lequel les symboles apparaitront
63 	@param rect rectangle englobant le dessin ; utilise pour specifier a la fois la position et la taille du dessin
64 */
draw(QPainter * painter,QET::ConductorSegmentType direction,const QRectF & rect)65 void SingleLineProperties::draw(QPainter *painter, QET::ConductorSegmentType direction, const QRectF &rect) {
66 	// s'il n'y a rien a dessiner, on retourne immediatement
67 	if (!hasNeutral && !hasGround && !phases) return;
68 
69 	// prepare le QPainter
70 	painter -> save();
71 	QPen pen(painter -> pen());
72 	pen.setCapStyle(Qt::FlatCap);
73 	pen.setJoinStyle(Qt::MiterJoin);
74 	pen.setStyle(Qt::SolidLine);
75 	pen.setWidthF(1);
76 	painter -> setPen(pen);
77 	painter -> setRenderHint(QPainter::Antialiasing, true);
78 
79 	uint symbols_count = (hasNeutral ? 1 : 0) + (hasGround ? 1 : 0) - (isPen() ? 1 : 0) + phases;
80 	qreal interleave_base = (direction == QET::Horizontal ? rect.width() : rect.height());
81 	qreal interleave = interleave_base / (symbols_count + 1);;
82 	qreal symbol_width = interleave_base / 12;
83 
84 	for (uint i = 1 ; i <= symbols_count ; ++ i) {
85 		// dessine le tronc du symbole
86 		QPointF symbol_p1, symbol_p2;
87 		if (direction == QET::Horizontal) {
88 			symbol_p1 = QPointF(rect.x() + (i * interleave) + symbol_width, rect.y() + rect.height() * 0.75);
89 			symbol_p2 = QPointF(rect.x() + (i * interleave) - symbol_width, rect.y() + rect.height() * 0.25);
90 		} else {
91 			symbol_p2 = QPointF(rect.x() + rect.width() * 0.75, rect.y() + (i * interleave) - symbol_width);
92 			symbol_p1 = QPointF(rect.x() + rect.width() * 0.25, rect.y() + (i * interleave) + symbol_width);
93 		}
94 		painter -> drawLine(QLineF(symbol_p1, symbol_p2));
95 
96 		// dessine le reste des symboles terre et neutre
97 		if (isPen()) {
98 			if (i == 1) {
99 				drawPen(painter, direction, symbol_p2, symbol_width);
100 			}
101 		} else {
102 			if (hasGround && i == 1) {
103 				drawGround(painter, direction, symbol_p2, symbol_width * 2.0);
104 			} else if (hasNeutral && ((i == 1 && !hasGround) || (i == 2 && hasGround))) {
105 				drawNeutral(painter, direction, symbol_p2, symbol_width * 1.5);
106 			}
107 		}
108 	}
109 	painter -> restore();
110 }
111 
112 /**
113 	Dessine le segment correspondant au symbole de la terre sur un conducteur unifilaire
114 	@param painter QPainter a utiliser pour dessiner le segment
115 	@param direction direction du segment sur lequel le symbole apparaitra
116 	@param center centre du segment
117 	@param size taille du segment
118 */
drawGround(QPainter * painter,QET::ConductorSegmentType direction,QPointF center,qreal size)119 void SingleLineProperties::drawGround(QPainter *painter, QET::ConductorSegmentType direction, QPointF center, qreal size) {
120 	painter -> save();
121 
122 	// prepare le QPainter
123 	painter -> setRenderHint(QPainter::Antialiasing, false);
124 	QPen pen2(painter -> pen());
125 	pen2.setCapStyle(Qt::SquareCap);
126 	painter -> setPen(pen2);
127 
128 	// dessine le segment representant la terre
129 	qreal half_size = size / 2.0;
130 	QPointF offset_point(
131 		(direction == QET::Horizontal) ? half_size : 0.0,
132 		(direction == QET::Horizontal) ? 0.0 : half_size
133 	);
134 	painter -> drawLine(
135 		QLineF(
136 			center + offset_point,
137 			center - offset_point
138 		)
139 	);
140 
141 	painter -> restore();
142 }
143 
144 /**
145 	Dessine le cercle correspondant au symbole du neutre sur un conducteur unifilaire
146 	@param painter QPainter a utiliser pour dessiner le segment
147 	@param direction direction du segment sur lequel le symbole apparaitra
148 	@param center centre du cercle
149 	@param size diametre du cercle
150 */
drawNeutral(QPainter * painter,QET::ConductorSegmentType direction,QPointF center,qreal size)151 void SingleLineProperties::drawNeutral(QPainter *painter, QET::ConductorSegmentType direction, QPointF center, qreal size) {
152 	Q_UNUSED(direction);
153 	painter -> save();
154 
155 	// prepare le QPainter
156 	if (painter -> brush() == Qt::NoBrush) painter -> setBrush(Qt::black);
157 	painter -> setPen(Qt::NoPen);
158 
159 	// desine le cercle representant le neutre
160 	painter -> drawEllipse(
161 		QRectF(
162 			center - QPointF(size / 2.0, size / 2.0),
163 			QSizeF(size, size)
164 		)
165 	);
166 
167 	painter -> restore();
168 }
169 
170 /**
171 	Draw the PEN (Protective Earth Neutral) symbol using \a painter at position \a
172 	center, using a size hint of \a size.
173 	@param direction Indicate the direction of the underlying conductor segment
174 */
drawPen(QPainter * painter,QET::ConductorSegmentType direction,QPointF center,qreal size)175 void SingleLineProperties::drawPen(QPainter *painter, QET::ConductorSegmentType direction, QPointF center, qreal size) {
176 	painter -> save();
177 
178 	//painter -> setBrush(Qt::white);
179 	// desine le cercle representant le neutre
180 	//painter -> drawEllipse(
181 	//	QRectF(
182 	//		center - QPointF(size * 1.5 / 2.0, size * 1.5 / 2.0),
183 	//		QSizeF(size * 1.5, size * 1.5)
184 	//	)
185 	//);
186 	drawNeutral(painter, direction, center, size * 1.5);
187 
188 	int offset = (size * 1.5 / 2.0);
189 	QPointF pos = center + (direction == QET::Horizontal ? QPointF(0.0, -offset - 0.5) : QPointF(offset + 0.5, 0.0));
190 	drawGround(painter, direction, pos, 2.0 * size);
191 	painter -> restore();
192 }
193 
194 /**
195 	Exporte les parametres du conducteur unifilaire sous formes d'attributs XML
196 	ajoutes a l'element e.
197 	@param e Element XML auquel seront ajoutes des attributs
198 */
toXml(QDomElement & e) const199 void SingleLineProperties::toXml(QDomElement &e) const {
200 	e.setAttribute("ground",  hasGround  ? "true" : "false");
201 	e.setAttribute("neutral", hasNeutral ? "true" : "false");
202 	e.setAttribute("phase",   phases);
203 	if (isPen()) e.setAttribute("pen", "true");
204 }
205 
206 /**
207 	Importe les parametres du conducteur unifilaire a partir des attributs XML
208 	de l'element e
209 	@param e Element XML dont les attributs seront lus
210 */
fromXml(QDomElement & e)211 void SingleLineProperties::fromXml(QDomElement &e) {
212 	hasGround  = e.attribute("ground")  == "true";
213 	hasNeutral = e.attribute("neutral") == "true";
214 	setPhasesCount(e.attribute("phase").toInt());
215 	is_pen = (hasGround && hasNeutral && e.attribute("pen", "false") == "true");
216 }
217 
218 /**
219 	Constructeur : par defaut, les proprietes font un conducteur
220 	multifilaire noir dont le texte est "_"
221 */
ConductorProperties()222 ConductorProperties::ConductorProperties() :
223 	type(Multi),
224 	color(Qt::black),
225 	text("_"),
226 	text_size(9),
227 	cond_size(1),
228 	verti_rotate_text(270),
229 	horiz_rotate_text(0),
230 	m_show_text(true),
231 	m_one_text_per_folio(false),
232 	style(Qt::SolidLine)
233 {}
234 
235 /**
236 	Destructeur
237 */
~ConductorProperties()238 ConductorProperties::~ConductorProperties() {
239 }
240 
241 
242 /**
243  * @brief ConductorProperties::toXml
244  * Export conductor propertie, in the XML element 'e'
245  * @param e the xml element
246  */
toXml(QDomElement & e) const247 void ConductorProperties::toXml(QDomElement &e) const
248 {
249 	e.setAttribute("type", typeToString(type));
250 
251 	if (color != QColor(Qt::black))
252 		e.setAttribute("color", color.name());
253 
254 	e.setAttribute("bicolor", m_bicolor? "true" : "false");
255 	e.setAttribute("color2", m_color_2.name());
256 	e.setAttribute("dash-size", QString::number(m_dash_size));
257 
258 	if (type == Single)
259 		singleLineProperties.toXml(e);
260 
261 	e.setAttribute("num", text);
262 	e.setAttribute("formula", m_formula);
263 	e.setAttribute("function", m_function);
264 	e.setAttribute("tension-protocol", m_tension_protocol);
265 	e.setAttribute("numsize", QString::number(text_size));
266 	e.setAttribute("condsize", QString::number(cond_size));
267 	e.setAttribute("displaytext", m_show_text);
268 	e.setAttribute("onetextperfolio", m_one_text_per_folio);
269 	e.setAttribute("vertirotatetext", QString::number(verti_rotate_text));
270 	e.setAttribute("horizrotatetext", QString::number(horiz_rotate_text));
271 
272 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
273 	e.setAttribute("horizontal-alignment", me.valueToKey(m_horizontal_alignment));
274 	e.setAttribute("vertical-alignment", me.valueToKey(m_vertical_alignment));
275 
276 	QString conductor_style = writeStyle();
277 	if (!conductor_style.isEmpty())
278 		e.setAttribute("style", conductor_style);
279 }
280 
281 
282 /**
283  * @brief ConductorProperties::fromXml
284  * Import conductor propertie, from the attribute of the xml element 'e'
285  * @param e the xml document
286  */
fromXml(QDomElement & e)287 void ConductorProperties::fromXml(QDomElement &e)
288 {
289 		// get conductor color
290 	QColor xml_color= QColor(e.attribute("color"));
291 	color = (xml_color.isValid()? xml_color : QColor(Qt::black));
292 
293 	QString bicolor_str = e.attribute("bicolor", "false");
294 	m_bicolor = bicolor_str == "true"? true : false;
295 
296     QColor xml_color_2 = QColor(e.attribute("color2"));
297 	m_color_2 = xml_color_2.isValid()? xml_color_2 : QColor(Qt::black);
298 
299 	m_dash_size = e.attribute("dash-size", QString::number(1)).toInt();
300 
301 		// read style of conductor
302 	readStyle(e.attribute("style"));
303 
304 	if (e.attribute("type") == typeToString(Single))
305 	{
306 			// get specific properties for single conductor
307 		singleLineProperties.fromXml(e);
308 		type = Single;
309 	}
310 	else
311 		type = Multi;
312 
313 	text                 = e.attribute("num");
314 	m_formula            = e.attribute("formula");
315 	m_function           = e.attribute("function");
316 	m_tension_protocol   = e.attribute("tension-protocol");
317 	text_size            = e.attribute("numsize", QString::number(9)).toInt();
318 	cond_size            = e.attribute("condsize", QString::number(1)).toDouble();
319 	m_show_text          = e.attribute("displaytext", QString::number(1)).toInt();
320 	m_one_text_per_folio = e.attribute("onetextperfolio", QString::number(0)).toInt();
321 	verti_rotate_text    = e.attribute("vertirotatetext").toDouble();
322 	horiz_rotate_text    = e.attribute("horizrotatetext").toDouble();
323 
324 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
325 	m_horizontal_alignment = Qt::Alignment(me.keyToValue(e.attribute("horizontal-alignment", "AlignBottom").toStdString().data()));
326 	m_vertical_alignment = Qt::Alignment(me.keyToValue(e.attribute("vertical-alignment", "AlignRight").toStdString().data()));
327 
328 		//Keep retrocompatible with version older than 0,4
329 		//If the propertie @type is simple (removed since QET 0,4), we set text no visible.
330 		//@TODO remove this code for qet 0.6 or later
331 	if (e.attribute("type") == "simple") m_show_text = false;
332 }
333 
334 /**
335 	@param settings Parametres a ecrire
336 	@param prefix prefixe a ajouter devant les noms des parametres
337 */
toSettings(QSettings & settings,const QString & prefix) const338 void ConductorProperties::toSettings(QSettings &settings, const QString &prefix) const
339 {
340 	settings.setValue(prefix + "color", color.name());
341 	settings.setValue(prefix + "bicolor", m_bicolor);
342 	settings.setValue(prefix + "color2", m_color_2.name());
343 	settings.setValue(prefix + "dash-size", m_dash_size);
344 	settings.setValue(prefix + "style", writeStyle());
345 	settings.setValue(prefix + "type", typeToString(type));
346 	settings.setValue(prefix + "text", text);
347 	settings.setValue(prefix + "formula", m_formula);
348 	settings.setValue(prefix + "function", m_function);
349 	settings.setValue(prefix + "tension-protocol", m_tension_protocol);
350 	settings.setValue(prefix + "textsize", QString::number(text_size));
351 	settings.setValue(prefix + "size", QString::number(cond_size));
352 	settings.setValue(prefix + "displaytext", m_show_text);
353 	settings.setValue(prefix + "onetextperfolio", m_one_text_per_folio);
354 	settings.setValue(prefix + "vertirotatetext", QString::number(verti_rotate_text));
355 	settings.setValue(prefix + "horizrotatetext", QString::number(horiz_rotate_text));
356 
357 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
358 	settings.setValue(prefix + "horizontal-alignment", me.valueToKey(m_horizontal_alignment));
359 	settings.setValue(prefix + "vertical-alignment", me.valueToKey(m_vertical_alignment));
360 
361 	singleLineProperties.toSettings(settings, prefix);
362 }
363 
364 /**
365 	@param settings Parametres a lire
366 	@param prefix prefixe a ajouter devant les noms des parametres
367 */
fromSettings(QSettings & settings,const QString & prefix)368 void ConductorProperties::fromSettings(QSettings &settings, const QString &prefix)
369 {
370 	QColor settings_color = QColor(settings.value(prefix + "color").toString());
371 	color = (settings_color.isValid()? settings_color : QColor(Qt::black));
372 
373 	QColor settings_color_2 = QColor(settings.value(prefix + "color2").toString());
374 	m_color_2 = (settings_color_2.isValid()? settings_color_2 : QColor(Qt::black));
375 
376 	m_bicolor   = settings.value(prefix + "bicolor", false).toBool();
377 	m_dash_size = settings.value(prefix + "dash-size", 1).toInt();
378 
379 	QString setting_type = settings.value(prefix + "type", typeToString(Multi)).toString();
380 	type = (setting_type == typeToString(Single)? Single : Multi);
381 
382 	singleLineProperties.fromSettings(settings, prefix);
383 
384 	text                 = settings.value(prefix + "text", "_").toString();
385 	m_formula            = settings.value(prefix + "formula", "").toString();
386 	m_function           = settings.value(prefix + "function", "").toString();
387 	m_tension_protocol   = settings.value(prefix + "tension-protocol", "").toString();
388 	text_size            = settings.value(prefix + "textsize", "7").toInt();
389 	cond_size            = settings.value(prefix + "size", "1").toInt();
390 	m_show_text          = settings.value(prefix + "displaytext", true).toBool();
391 	m_one_text_per_folio = settings.value(prefix + "onetextperfolio", false).toBool();
392 	verti_rotate_text    = settings.value((prefix + "vertirotatetext"), "270").toDouble();
393 	horiz_rotate_text    = settings.value((prefix + "horizrotatetext"), "0").toDouble();
394 
395 	QMetaEnum me = QMetaEnum::fromType<Qt::Alignment>();
396 	m_horizontal_alignment = Qt::Alignment(me.keyToValue(settings.value(prefix + "horizontal-alignment", "AlignBottom").toString().toStdString().data()));
397 	m_vertical_alignment = Qt::Alignment(me.keyToValue(settings.value(prefix + "vertical-alignment", "AlignRight").toString().toStdString().data()));
398 
399 	readStyle(settings.value(prefix + "style").toString());
400 }
401 
402 /**
403 	@param t type du conducteur
404 */
typeToString(ConductorType t)405 QString ConductorProperties::typeToString(ConductorType t)
406 {
407 	switch(t)
408 	{
409 		case Single: return("single");
410 		case Multi:  return("multi");
411 	}
412 	return QString();
413 }
414 
415 /**
416  * @brief ConductorProperties::applyForEqualAttributes
417  * Test each attribute of properties in the list separatly.
418  * For each attributes, if is equal, the attribute is apply to this.
419  * @param list
420  */
applyForEqualAttributes(QList<ConductorProperties> list)421 void ConductorProperties::applyForEqualAttributes(QList<ConductorProperties> list)
422 {
423 	const QList<ConductorProperties> clist = std::move(list);
424 
425 	if (clist.isEmpty())
426 		return;
427 
428 	if (clist.size() == 1)
429 	{
430 		ConductorProperties cp = clist.first();
431 		color                = cp.color;
432 		m_bicolor            = cp.m_bicolor;
433 		m_color_2            = cp.m_color_2;
434 		m_dash_size          = cp.m_dash_size;
435 		text                 = cp.text;
436 		m_formula            = cp.m_formula;
437 		m_function           = cp.m_function;
438 		m_tension_protocol   = cp.m_tension_protocol;
439 		text_size            = cp.text_size;
440 		cond_size            = cp.cond_size;
441 		m_show_text          = cp.m_show_text;
442 		m_one_text_per_folio = cp.m_one_text_per_folio;
443 		verti_rotate_text    = cp.verti_rotate_text;
444 		horiz_rotate_text    = cp.horiz_rotate_text;
445 		m_vertical_alignment = cp.m_vertical_alignment;
446 		m_horizontal_alignment = cp.m_horizontal_alignment;
447 
448 		return;
449 	}
450 
451 	bool equal = true;
452 	QColor c_value;
453 	bool b_value;
454 	QString s_value;
455 	int i_value;
456 	double d_value;
457 	Qt::Alignment align_value;
458 
459 		//Color
460 	c_value = clist.first().color;
461 	for(ConductorProperties cp : clist)
462 	{
463 		if (cp.color != c_value)
464 			equal = false;
465 	}
466 	if (equal)
467 		color = c_value;
468 	equal = true;
469 
470 		//bicolor
471 	b_value = clist.first().m_bicolor;
472 	for(ConductorProperties cp : clist)
473 	{
474 		if (cp.m_bicolor != b_value)
475 			equal = false;
476 	}
477 	if (equal)
478 		m_bicolor = b_value;
479 	equal = true;
480 
481 		//second color
482 	c_value = clist.first().m_color_2;
483 	for(ConductorProperties cp : clist)
484 	{
485 		if (cp.m_color_2 != c_value)
486 			equal = false;
487 	}
488 	if (equal)
489 		m_color_2 = c_value;
490 	equal = true;
491 
492 		//Dash size
493 	i_value = clist.first().m_dash_size;
494 	for(ConductorProperties cp : clist)
495 	{
496 		if (cp.m_dash_size != i_value)
497 			equal = false;
498 	}
499 	if (equal)
500 		m_dash_size = i_value;
501 	equal = true;
502 
503 		//text
504 	s_value = clist.first().text;
505 	for(ConductorProperties cp : clist)
506 	{
507 		if (cp.text != s_value)
508 			equal = false;
509 	}
510 	if (equal)
511 		text = s_value;
512 	equal = true;
513 
514 		//formula
515 	s_value = clist.first().m_formula;
516 	for(ConductorProperties cp : clist)
517 	{
518 		if (cp.m_formula != s_value)
519 			equal = false;
520 	}
521 	if (equal)
522 		m_formula = s_value;
523 	equal = true;
524 
525 		//function
526 	s_value = clist.first().m_function;
527 	for(ConductorProperties cp : clist)
528 	{
529 		if (cp.m_function != s_value)
530 			equal = false;
531 	}
532 	if (equal)
533 		m_function = s_value;
534 	equal = true;
535 
536 		//Tension protocol
537 	s_value = clist.first().m_tension_protocol;
538 	for(ConductorProperties cp : clist)
539 	{
540 		if (cp.m_tension_protocol != s_value)
541 			equal = false;
542 	}
543 	if (equal)
544 		m_tension_protocol = s_value;
545 	equal = true;
546 
547 		//text size
548 	i_value = clist.first().text_size;
549 	for(ConductorProperties cp : clist)
550 	{
551 		if (cp.text_size != i_value)
552 			equal = false;
553 	}
554 	if (equal)
555 		text_size = i_value;
556 	equal = true;
557 
558 		//conductor size
559 	d_value = clist.first().cond_size;
560 	for(ConductorProperties cp : clist)
561 	{
562 		if (cp.cond_size != d_value)
563 			equal = false;
564 	}
565 	if (equal)
566 		cond_size = d_value;
567 	equal = true;
568 
569 		//show text
570 	b_value = clist.first().m_show_text;
571 	for(ConductorProperties cp : clist)
572 	{
573 		if (cp.m_show_text != b_value)
574 			equal = false;
575 	}
576 	if (equal)
577 		m_show_text = b_value;
578 	equal = true;
579 
580 		//One text per folio
581 	b_value = clist.first().m_one_text_per_folio;
582 	for(ConductorProperties cp : clist)
583 	{
584 		if (cp.m_one_text_per_folio != b_value)
585 			equal = false;
586 	}
587 	if (equal)
588 		m_one_text_per_folio = b_value;
589 	equal = true;
590 
591 		//Text rotation for vertical conducor
592 	d_value = clist.first().verti_rotate_text;
593 	for(ConductorProperties cp : clist)
594 	{
595 		if (cp.verti_rotate_text != d_value)
596 			equal = false;
597 	}
598 	if (equal)
599 		verti_rotate_text = d_value;
600 	equal = true;
601 
602 		//Text rotation for horizontal conducor
603 	d_value = clist.first().horiz_rotate_text;
604 	for(ConductorProperties cp : clist)
605 	{
606 		if (cp.horiz_rotate_text != d_value)
607 			equal = false;
608 	}
609 	if (equal)
610 		horiz_rotate_text = d_value;
611 	equal = true;
612 
613 		//Text alignment for horizontal conducor
614 	align_value = clist.first().m_horizontal_alignment;
615 	for(ConductorProperties cp : clist)
616 	{
617 		if (cp.m_horizontal_alignment != align_value)
618 			equal = false;
619 	}
620 	if (equal)
621 		m_horizontal_alignment = align_value;
622 	equal = true;
623 
624 		//Text alignment for vertical conducor
625 	align_value = clist.first().m_vertical_alignment;
626 	for(ConductorProperties cp : clist)
627 	{
628 		if (cp.m_vertical_alignment != align_value)
629 			equal = false;
630 	}
631 	if (equal)
632 		m_vertical_alignment = align_value;
633 	equal = true;
634 }
635 
636 /**
637  * @brief ConductorProperties::defaultProperties
638  * @return the default properties stored in the setting file
639  */
defaultProperties()640 ConductorProperties ConductorProperties::defaultProperties()
641 {
642 	QSettings settings;
643 
644 	ConductorProperties def;
645 	def.fromSettings(settings, "diagrameditor/defaultconductor");
646 
647 	return(def);
648 }
649 
650 /**
651  * @brief ConductorProperties::operator ==
652  * @param other
653  * @return true if other == this
654  */
operator ==(const ConductorProperties & other) const655 bool ConductorProperties::operator==(const ConductorProperties &other) const
656 {
657 	return(
658 		other.type == type &&\
659 		other.color == color &&\
660 		other.m_bicolor == m_bicolor &&\
661 		other.m_color_2 == m_color_2 &&\
662 		other.m_dash_size == m_dash_size &&\
663 		other.style == style &&\
664 		other.text == text &&\
665 		other.m_formula == m_formula &&\
666 		other.m_function == m_function &&\
667 		other.m_tension_protocol == m_tension_protocol &&\
668 		other.m_show_text == m_show_text &&\
669 		other.text_size == text_size &&\
670 		other.cond_size == cond_size &&\
671 		other.verti_rotate_text == verti_rotate_text &&\
672 		other.horiz_rotate_text == horiz_rotate_text &&\
673 		other.singleLineProperties == singleLineProperties &&\
674 		other.m_one_text_per_folio == m_one_text_per_folio &&\
675 		other.m_horizontal_alignment == m_horizontal_alignment &&\
676 		other.m_vertical_alignment == m_vertical_alignment
677 	);
678 }
679 
680 /**
681 	@param other l'autre ensemble de proprietes avec lequel il faut effectuer la comparaison
682 	@return true si les deux ensembles de proprietes sont differents, false sinon
683 */
operator !=(const ConductorProperties & other) const684 bool ConductorProperties::operator!=(const ConductorProperties &other) const{
685 	return(!(*this == other));
686 }
687 
688 /**
689 	Applique les styles passes en parametre dans cet objet
690 	@param style_string Chaine decrivant le style du conducteur
691 */
readStyle(const QString & style_string)692 void ConductorProperties::readStyle(const QString &style_string) {
693 	style = Qt::SolidLine; // style par defaut
694 
695 	if (style_string.isEmpty()) return;
696 
697 	// recupere la liste des couples style / valeur
698 	QStringList styles = style_string.split(";", QString::SkipEmptyParts);
699 
700 	QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
701 	foreach (QString style_str, styles) {
702 		if (rx.exactMatch(style_str)) {
703 			QString style_name = rx.cap(1);
704 			QString style_value = rx.cap(2);
705 			if (style_name == "line-style") {
706 				if (style_value == "dashed") style = Qt::DashLine;
707 				else if (style_value == "dashdotted") style = Qt::DashDotLine;
708 				else if (style_value == "normal") style = Qt::SolidLine;
709 			}
710 		}
711 	}
712 }
713 
714 /**
715 	Exporte le style du conducteur sous forme d'une chaine de caracteres
716 	@return une chaine de caracteres decrivant le style du conducteur
717 */
writeStyle() const718 QString ConductorProperties::writeStyle() const {
719 	if (style == Qt::DashLine) {
720 		return("line-style: dashed;");
721 	} else if (style == Qt::DashDotLine) {
722 		return("line-style: dashdotted");
723 	} else {
724 		return(QString());
725 	}
726 }
727 
728 /**
729 	@param other l'autre ensemble de proprietes avec lequel il faut effectuer la comparaison
730 	@return true si les deux ensembles de proprietes sont identiques, false sinon
731 */
operator ==(const SingleLineProperties & other) const732 int SingleLineProperties::operator==(const SingleLineProperties &other) const {
733 	return(
734 		other.hasGround == hasGround &&\
735 		other.hasNeutral == hasNeutral &&\
736 		other.is_pen == is_pen &&\
737 		other.phases == phases
738 	);
739 }
740 
741 /**
742 	@param other l'autre ensemble de proprietes avec lequel il faut effectuer la comparaison
743 	@return true si les deux ensembles de proprietes sont differents, false sinon
744 */
operator !=(const SingleLineProperties & other) const745 int SingleLineProperties::operator!=(const SingleLineProperties &other) const {
746 	return(!(other == (*this)));
747 }
748 
749 /**
750 	@param settings Parametres a ecrire
751 	@param prefix prefix a ajouter devant les noms des parametres
752 */
toSettings(QSettings & settings,const QString & prefix) const753 void SingleLineProperties::toSettings(QSettings &settings, const QString &prefix) const {
754 	settings.setValue(prefix + "hasGround",  hasGround);
755 	settings.setValue(prefix + "hasNeutral", hasNeutral);
756 	settings.setValue(prefix + "phases",     phases);
757 	settings.setValue(prefix + "pen",        is_pen);
758 }
759 
760 /**
761 	@param settings Parametres a lire
762 	@param prefix prefix a ajouter devant les noms des parametres
763 */
fromSettings(QSettings & settings,const QString & prefix)764 void SingleLineProperties::fromSettings(QSettings &settings, const QString &prefix) {
765 	hasGround  = settings.value(prefix + "hasGround",  true).toBool();
766 	hasNeutral = settings.value(prefix + "hasNeutral", true).toBool();
767 	phases     = settings.value(prefix + "phases",     1).toInt();
768 	is_pen     = settings.value(prefix + "pen",        false).toBool();
769 }
770