diff --git a/conducer.cpp b/conducer.cpp index 4acffba28..dc94270ad 100644 --- a/conducer.cpp +++ b/conducer.cpp @@ -1,6 +1,7 @@ #include #include "conducer.h" #include "conducersegment.h" +#include "conducersegmentprofile.h" #include "element.h" #define PR(x) qDebug() << #x " = " << x; @@ -15,17 +16,23 @@ QBrush Conducer::conducer_brush = QBrush(); @param parent Element parent du conducteur (0 par defaut) @param scene QGraphicsScene auquelle appartient le conducteur */ -Conducer::Conducer(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene *scene) : QGraphicsPathItem(parent, scene) { - // bornes que le conducteur relie - terminal1 = p1; - terminal2 = p2; +Conducer::Conducer(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene *scene) : + QGraphicsPathItem(parent, scene), + terminal1(p1), + terminal2(p2), + destroyed(false), + segments(NULL), + previous_z_value(zValue()), + modified_path(false), + has_to_save_profile(false) +{ // ajout du conducteur a la liste de conducteurs de chacune des deux bornes bool ajout_p1 = terminal1 -> addConducer(this); bool ajout_p2 = terminal2 -> addConducer(this); + // en cas d'echec de l'ajout (conducteur deja existant notamment) if (!ajout_p1 || !ajout_p2) return; - destroyed = false; - modified_path = false; + // attributs de dessin par defaut (communs a tous les conducteurs) if (!pen_and_brush_initialized) { conducer_pen.setJoinStyle(Qt::MiterJoin); @@ -37,12 +44,11 @@ Conducer::Conducer(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene * conducer_brush.setStyle(Qt::NoBrush); pen_and_brush_initialized = true; } + // calcul du rendu du conducteur - segments = NULL; priv_calculeConducer(terminal1 -> amarrageConducer(), terminal1 -> orientation(), terminal2 -> amarrageConducer(), terminal2 -> orientation()); setFlags(QGraphicsItem::ItemIsSelectable); setAcceptsHoverEvents(true); - previous_z_value = zValue(); // ajout du champ de texte editable text_item = new QGraphicsTextItem(); @@ -148,51 +154,125 @@ void Conducer::segmentsToPath() { @param o2 Orientation de la borne 2 */ void Conducer::priv_modifieConducer(const QPointF &p1, QET::Orientation, const QPointF &p2, QET::Orientation) { - Q_ASSERT_X(nbSegments() > 1, "priv_modifieConducer", "pas de points a modifier"); + // determine le nombre de segments horizontaux et verticaux + uint nb_horiz_segments = conducer_profile.nbSegments(QET::Horizontal); + uint nb_verti_segments = conducer_profile.nbSegments(QET::Vertical); - // recupere les dernieres coordonnees connues des bornes - QPointF old_p1 = mapFromScene(terminal1 -> amarrageConducer()); - QPointF old_p2 = mapFromScene(terminal2 -> amarrageConducer()); + Q_ASSERT_X(nb_horiz_segments + nb_verti_segments > 1, "Conducer::priv_modifieConducer", "pas de points a modifier"); + Q_ASSERT_X(!conducer_profile.isNull(), "Conducer::priv_modifieConducer", "pas de profil utilisable"); // recupere les coordonnees fournies des bornes QPointF new_p1 = mapFromScene(p1); QPointF new_p2 = mapFromScene(p2); + QRectF new_rect = QRectF(new_p1, new_p2); - // les distances horizontales et verticales entre les anciennes bornes - // sont stockees dans orig_dist_2_terms_x et orig_dist_2_terms_y + // recupere la largeur et la hauteur du profil + qreal profile_width = conducer_profile.width(); + qreal profile_height = conducer_profile.height(); - // calcule les distances horizontales et verticales entre les nouvelles bornes - qreal new_dist_2_terminals_x = new_p2.x() - new_p1.x(); - qreal new_dist_2_terminals_y = new_p2.y() - new_p1.y(); + // calcule les differences verticales et horizontales a appliquer + qreal h_diff = (qAbs(new_rect.width()) - qAbs(profile_width) ) * getSign(profile_width); + qreal v_diff = (qAbs(new_rect.height()) - qAbs(profile_height)) * getSign(profile_height); + + // applique les differences aux segments + QHash segments_lengths; + segments_lengths.unite(shareOffsetBetweenSegments(h_diff, conducer_profile.horizontalSegments())); + segments_lengths.unite(shareOffsetBetweenSegments(v_diff, conducer_profile.verticalSegments())); + + // en deduit egalement les coefficients d'inversion (-1 pour une inversion, +1 pour conserver le meme sens) + int horiz_coeff = getCoeff(new_rect.width(), profile_width); + int verti_coeff = getCoeff(new_rect.height(), profile_height); - // en deduit les coefficients de "redimensionnement" - qreal coeff_x = new_dist_2_terminals_x / orig_dist_2_terms_x; - qreal coeff_y = new_dist_2_terminals_y / orig_dist_2_terms_y; - /* - if (!orig_dist_2_terms_x || !orig_dist_2_terms_y) { - qDebug() << "ca va planter"; - PR(coeff_x) - PR(coeff_y) - } - */ // genere les nouveaux points - int limite = moves_x.size() - 1; - int coeff = type_trajet_x ? 1 : -1; - QList points; - points << (type_trajet_x ? new_p1 : new_p2); - for (int i = 0 ; i < limite ; ++ i) { + points << new_p1; + int limit = conducer_profile.segments.count() - 1; + for (int i = 0 ; i < limit ; ++ i) { + // dernier point QPointF previous_point = points.last(); - points << QPointF ( - previous_point.x() + (moves_x.at(i) * coeff_x * coeff), - previous_point.y() + (moves_y.at(i) * coeff_y * coeff) - ); + + // profil de segment de conducteur en cours + ConducerSegmentProfile *csp = conducer_profile.segments.at(i); + + // coefficient et offset a utiliser pour ce point + qreal coeff = csp -> isHorizontal ? horiz_coeff : verti_coeff; + qreal offset_applied = segments_lengths[csp]; + + // applique l'offset et le coeff au point + if (csp -> isHorizontal) { + points << QPointF ( + previous_point.x() + (coeff * offset_applied), + previous_point.y() + ); + } else { + points << QPointF ( + previous_point.x(), + previous_point.y() + (coeff * offset_applied) + ); + } } - points << (type_trajet_x ? new_p2 : new_p1); + points << new_p2; pointsToSegments(points); segmentsToPath(); } +/** + @param offset Longueur a repartir entre les segments + @param segments_list Segments sur lesquels il faut repartir la longueur + @param precision seuil en-deca duquel on considere qu'il ne reste rien a repartir +*/ +QHash Conducer::shareOffsetBetweenSegments( + const qreal &offset, + const QList &segments_list, + const qreal &precision +) const { + // construit le QHash qui sera retourne + QHash segments_hash; + foreach(ConducerSegmentProfile *csp, segments_list) { + segments_hash.insert(csp, csp -> length); + } + + // memorise le signe de la longueur de chaque segement + QHash segments_signs; + foreach(ConducerSegmentProfile *csp, segments_hash.keys()) { + segments_signs.insert(csp, getSign(csp -> length)); + } + + //qDebug() << "repartition d'un offset de" << offset << "px sur" << segments_list.count() << "segments"; + + // repartit l'offset sur les segments + qreal remaining_offset = offset; + while (remaining_offset > precision || remaining_offset < -precision) { + // recupere le nombre de segments differents ayant une longueur non nulle + uint segments_count = 0; + foreach(ConducerSegmentProfile *csp, segments_hash.keys()) if (segments_hash[csp]) ++ segments_count; + //qDebug() << " remaining_offset =" << remaining_offset; + qreal local_offset = remaining_offset / segments_count; + //qDebug() << " repartition d'un offset local de" << local_offset << "px sur" << segments_count << "segments"; + remaining_offset = 0.0; + foreach(ConducerSegmentProfile *csp, segments_hash.keys()) { + // ignore les segments de longueur nulle + if (!segments_hash[csp]) continue; + // applique l'offset au segment + //qreal segment_old_length = segments_hash[csp]; + segments_hash[csp] += local_offset; + + // (la longueur du segment change de signe) <=> (le segment n'a pu absorbe tout l'offset) + if (segments_signs[csp] != getSign(segments_hash[csp])) { + + // on remet le trop-plein dans la reserve d'offset + remaining_offset += qAbs(segments_hash[csp]) * getSign(local_offset); + //qDebug() << " trop-plein de" << qAbs(segments_hash[csp]) * getSign(local_offset) << "remaining_offset =" << remaining_offset; + segments_hash[csp] = 0.0; + } else { + //qDebug() << " offset local de" << local_offset << "accepte"; + } + } + } + + return(segments_hash); +} + /** Calcule un trajet "par defaut" pour le conducteur @param p1 Coordonnees du point d'amarrage de la borne 1 @@ -207,7 +287,6 @@ void Conducer::priv_calculeConducer(const QPointF &p1, QET::Orientation o1, cons // s'assure qu'il n'y a ni points QList points; - type_trajet_x = p1.x() < p2.x(); // mappe les points par rapport a la scene sp1 = mapFromScene(p1); sp2 = mapFromScene(p2); @@ -282,6 +361,13 @@ void Conducer::priv_calculeConducer(const QPointF &p1, QET::Orientation o1, cons // prolongement de la borne d'arrivee points << arrivee0; + // inverse eventuellement l'ordre des points afin que le trajet soit exprime de la borne 1 vers la borne 2 + if (newp1.x() > newp2.x()) { + QList points2; + for (int i = points.size() - 1 ; i >= 0 ; -- i) points2 << points.at(i); + points = points2; + } + pointsToSegments(points); segmentsToPath(); } @@ -480,7 +566,7 @@ void Conducer::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { // application du deplacement modified_path = true; - updatePoints(); + has_to_save_profile = true; segmentsToPath(); calculateTextItemPosition(); } @@ -496,6 +582,10 @@ void Conducer::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { // clic gauche moving_point = false; moving_segment = false; + if (has_to_save_profile) { + saveProfile(); + has_to_save_profile = false; + } setZValue(previous_z_value); QGraphicsPathItem::mouseReleaseEvent(e); calculateTextItemPosition(); @@ -577,24 +667,6 @@ QPainterPath Conducer::shape() const { return(area); } -/** - Met à jour deux listes de reels. -*/ -void Conducer::updatePoints() { - QList points = segmentsToPoints(); - int s = points.size(); - moves_x.clear(); - moves_y.clear(); - for (int i = 1 ; i < s ; ++ i) { - moves_x << points.at(i).x() - points.at(i - 1).x(); - moves_y << points.at(i).y() - points.at(i - 1).y(); - } - QPointF b1 = points.at(0); - QPointF b2 = points.at(s - 1); - orig_dist_2_terms_x = b2.x() - b1.x(); - orig_dist_2_terms_y = b2.y() - b1.y(); -} - /** Renvoie une valeur donnee apres l'avoir bornee entre deux autres valeurs, en y ajoutant une marge interne. @@ -603,8 +675,8 @@ void Conducer::updatePoints() { @param bound2 borne 2 @return La valeur bornee */ -qreal Conducer::conducer_bound(qreal tobound, qreal bound1, qreal bound2) { - qreal space = 5.0; +qreal Conducer::conducer_bound(qreal tobound, qreal bound1, qreal bound2, qreal space) { + qDebug() << "will bound" << tobound << "between" << bound1 << "and" << bound2 ; if (bound1 < bound2) { return(qBound(bound1 + space, tobound, bound2 - space)); } else { @@ -625,15 +697,15 @@ qreal Conducer::conducer_bound(qreal tobound, qreal bound, bool positive) { } /** + @param type Type de Segments @return Le nombre de segments composant le conducteur. */ -int Conducer::nbSegments() const { - if (segments == NULL) return(0); - int nb_seg = 1; - ConducerSegment *segment = segments; - while (segment -> hasNextSegment()) { - ++ nb_seg; - segment = segment -> nextSegment(); +uint Conducer::nbSegments(QET::ConducerSegmentType type) const { + QList segments_list = segmentsList(); + if (type == QET::Both) return(segments_list.count()); + uint nb_seg = 0; + foreach(ConducerSegment *conducer_segment, segments_list) { + if (conducer_segment -> type() == type) ++ nb_seg; } return(nb_seg); } @@ -740,15 +812,14 @@ bool Conducer::fromXml(QDomElement &e) { // s'il n'y a pas de segments, on renvoie true if (!segments_x.size()) return(true); - // les longueurs recueillies doivent etre coherentes avec les positions des bornes qreal width = 0.0, height = 0.0; foreach (qreal t, segments_x) width += t; foreach (qreal t, segments_y) height += t; QPointF t1 = terminal1 -> amarrageConducer(); QPointF t2 = terminal2 -> amarrageConducer(); - qreal expected_width = qAbs(t2.x() - t1.x()); - qreal expected_height = qAbs(t2.y() - t1.y()); + qreal expected_width = t2.x() - t1.x(); + qreal expected_height = t2.y() - t1.y(); qreal precision = std::numeric_limits::epsilon(); if ( expected_width > width + precision ||\ @@ -760,7 +831,7 @@ bool Conducer::fromXml(QDomElement &e) { /* on recree les segments a partir des donnes XML */ // cree la liste de points QList points_list; - points_list << (t1.x() < t2.x() ? t1 : t2); + points_list << t1; for (int i = 0 ; i < segments_x.size() ; ++ i) { points_list << QPointF( points_list.last().x() + segments_x.at(i), @@ -772,11 +843,7 @@ bool Conducer::fromXml(QDomElement &e) { // initialise divers parametres lies a la modification des conducteurs modified_path = true; - moves_x = segments_x; - moves_y = segments_y; - type_trajet_x = t1.x() < t2.x(); - orig_dist_2_terms_x = points_list.at(points_list.size() - 1).x() - points_list.at(0).x(); - orig_dist_2_terms_y = points_list.at(points_list.size() - 1).y() - points_list.at(0).y(); + saveProfile(); segmentsToPath(); return(true); @@ -800,20 +867,29 @@ QDomElement Conducer::toXml(QDomDocument &d, QHash &table_adr_i if (!modified_path) return(e); // parcours et export des segments - ConducerSegment *segment = segments; QDomElement current_segment; - while (segment -> hasNextSegment()) { + foreach(ConducerSegment *segment, segmentsList()) { current_segment = d.createElement("segment"); current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical"); current_segment.setAttribute("length", segment -> length()); e.appendChild(current_segment); + } + return(e); +} + +/// @return les segments de ce conducteur +const QList Conducer::segmentsList() const { + if (segments == NULL) return(QList()); + + QList segments_vector; + ConducerSegment *segment = segments; + + while (segment -> hasNextSegment()) { + segments_vector << segment; segment = segment -> nextSegment(); } - current_segment = d.createElement("segment"); - current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical"); - current_segment.setAttribute("length", segment -> length()); - e.appendChild(current_segment); - return(e); + segments_vector << segment; + return(segments_vector); } /** @@ -859,3 +935,28 @@ ConducerSegment *Conducer::middleSegment() { void Conducer::calculateTextItemPosition() { text_item -> setPos(middleSegment() -> middle()); } + +/** + Sauvegarde le profil courant du conducteur pour l'utiliser ulterieurement + dans priv_modifieConducer. +*/ +void Conducer::saveProfile() { + conducer_profile = ConducerProfile(this); +} + +/** + @param value1 Premiere valeur + @param value2 Deuxieme valeur + @return 1 si les deux valeurs sont de meme signe, -1 sinon +*/ +int Conducer::getCoeff(const qreal &value1, const qreal &value2) { + return(getSign(value1) * getSign(value2)); +} + +/** + @param value valeur + @return 1 si valeur est negatif, 1 s'il est positif ou nul +*/ +int Conducer::getSign(const qreal &value) { + return(value < 0 ? -1 : 1); +} diff --git a/conducer.h b/conducer.h index d321bb32b..6fa707c27 100644 --- a/conducer.h +++ b/conducer.h @@ -2,6 +2,7 @@ #define CONDUCTEUR_H #include #include "terminal.h" +#include "conducerprofile.h" class ConducerSegment; class Element; /** @@ -20,6 +21,7 @@ class Conducer : public QGraphicsPathItem { // attributs public: enum { Type = UserType + 1001 }; + ///Premiere borne a laquelle le fil est rattache Terminal *terminal1; ///Deuxieme borne a laquelle le fil est rattache @@ -30,11 +32,6 @@ class Conducer : public QGraphicsPathItem { bool destroyed; QGraphicsTextItem *text_item; ConducerSegment *segments; - QList moves_x; - QList moves_y; - qreal orig_dist_2_terms_x; - qreal orig_dist_2_terms_y; - bool type_trajet_x; QPointF press_point; bool moving_point; bool moving_segment; @@ -42,6 +39,8 @@ class Conducer : public QGraphicsPathItem { qreal previous_z_value; ConducerSegment *moved_segment; bool modified_path; + bool has_to_save_profile; + ConducerProfile conducer_profile; static QPen conducer_pen; static QBrush conducer_brush; static bool pen_and_brush_initialized; @@ -61,6 +60,7 @@ class Conducer : public QGraphicsPathItem { static bool valideXml(QDomElement &); bool fromXml(QDomElement &); QDomElement toXml(QDomDocument &, QHash &) const; + const QList segmentsList() const; protected: void mousePressEvent(QGraphicsSceneMouseEvent *); @@ -70,16 +70,19 @@ class Conducer : public QGraphicsPathItem { private: void segmentsToPath(); - void updatePoints(); + void saveProfile(); void priv_calculeConducer(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation); void priv_modifieConducer(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation); - int nbSegments() const; + uint nbSegments(QET::ConducerSegmentType = QET::Both) const; QList segmentsToPoints() const; void pointsToSegments(QList); bool hasClickedOn(QPointF, QPointF) const; void calculateTextItemPosition(); + static int getCoeff(const qreal &, const qreal &); + static int getSign(const qreal &); + QHash shareOffsetBetweenSegments(const qreal &offset, const QList &, const qreal & = 0.01) const; static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 12.0); - static qreal conducer_bound(qreal tobound, qreal bound1, qreal bound2); - static qreal conducer_bound(qreal tobound, qreal bound, bool positive); + static qreal conducer_bound(qreal, qreal, qreal, qreal = 0.0); + static qreal conducer_bound(qreal, qreal, bool); }; #endif diff --git a/conducerprofile.cpp b/conducerprofile.cpp new file mode 100644 index 000000000..5cdae1d3b --- /dev/null +++ b/conducerprofile.cpp @@ -0,0 +1,92 @@ +#include "conducerprofile.h" +#include "conducer.h" +#include "conducersegmentprofile.h" + +/// Constructeur +ConducerProfile::ConducerProfile() { +} + +/** + Constructeur + @param Conducer conducteur dont il faut extraire le profil +*/ +ConducerProfile::ConducerProfile(Conducer *conducer) { + foreach(ConducerSegment *conducer_segment, conducer -> segmentsList()) { + segments << new ConducerSegmentProfile(conducer_segment); + } + beginOrientation = conducer -> terminal1 -> orientation(); + endOrientation = conducer -> terminal2 -> orientation(); +} + +/// destructeur +ConducerProfile::~ConducerProfile() { +} + +/// @return true si le profil est nul +bool ConducerProfile::isNull() const { + return(segments.isEmpty()); +} + +/// @return la largeur occupee par le conducteur +qreal ConducerProfile::width() const { + qreal width = 0.0; + foreach(ConducerSegmentProfile *csp, segments) { + if (csp -> isHorizontal) width += csp -> length; + } + return(width); +} + +/// @return la hauteur occupee par le conducteur +qreal ConducerProfile::height() const{ + qreal height = 0.0; + foreach(ConducerSegmentProfile *csp, segments) { + if (!csp -> isHorizontal) height += csp -> length; + } + return(height); +} + +/** + @param type Type de Segments + @return Le nombre de segments composant le conducteur. +*/ +uint ConducerProfile::nbSegments(QET::ConducerSegmentType type) const { + if (type == QET::Both) return(segments.count()); + uint nb_seg = 0; + foreach(ConducerSegmentProfile *csp, segments) { + if (type == QET::Horizontal && csp -> isHorizontal) ++ nb_seg; + else if (type == QET::Vertical && !csp -> isHorizontal) ++ nb_seg; + } + return(nb_seg); +} + +/// @return les segments horizontaux de ce profil +QList ConducerProfile::horizontalSegments() { + QList segments_list; + foreach(ConducerSegmentProfile *csp, segments) { + if (csp -> isHorizontal) segments_list << csp; + } + return(segments_list); +} + +/// @return les segments verticaux de ce profil +QList ConducerProfile::verticalSegments() { + QList segments_list; + foreach(ConducerSegmentProfile *csp, segments) { + if (!csp -> isHorizontal) segments_list << csp; + } + return(segments_list); +} + +/** + Permet de debugger un profil de conducteur + @param d Object QDebug a utiliser pour l'affichage des informations de debug + @param t Profil de conducteur a debugger +*/ +QDebug &operator<<(QDebug d, ConducerProfile &t) { + d << "ConducerProfile {"; + foreach(ConducerSegmentProfile *csp, t.segments) { + d << "CSP" << (csp -> isHorizontal ? "horizontal" : "vertical") << ":" << csp -> length << ","; + } + d << "}"; + return(d.space()); +} diff --git a/conducerprofile.h b/conducerprofile.h new file mode 100644 index 000000000..20364547e --- /dev/null +++ b/conducerprofile.h @@ -0,0 +1,34 @@ +#ifndef CONDUCER_PROFILE_H +#define CONDUCER_PROFILE_H +#include +#include "qet.h" +class Conducer; +class ConducerSegmentProfile; +/** + Cette classe contient le profil (= les caracteristiques essentielles) d'un + conducteur. +*/ +class ConducerProfile { + public: + // constructeurs, destructeur + ConducerProfile(); + ConducerProfile(Conducer *conducer); + virtual ~ConducerProfile(); + + // attributs + public: + QList segments; + QET::Orientation beginOrientation; + QET::Orientation endOrientation; + + // methodes + public: + bool isNull() const; + qreal width() const; + qreal height() const; + uint nbSegments(QET::ConducerSegmentType) const; + QList horizontalSegments(); + QList verticalSegments(); +}; +QDebug &operator<<(QDebug d, ConducerProfile &); +#endif diff --git a/conducersegment.cpp b/conducersegment.cpp index a40e50caa..a4a561085 100644 --- a/conducersegment.cpp +++ b/conducersegment.cpp @@ -25,7 +25,6 @@ ConducerSegment::ConducerSegment( Destructeur - Relie le segment precedent au suivant */ ConducerSegment::~ConducerSegment() { - //qDebug() << "~ConducerSegment()" << (void *)this; if (hasPreviousSegment()) previousSegment() -> setNextSegment(nextSegment()); if (hasNextSegment()) nextSegment() -> setPreviousSegment(previousSegment()); } @@ -494,3 +493,7 @@ qreal ConducerSegment::length() const { return(secondPoint().y() - firstPoint().y()); } } + +QET::ConducerSegmentType ConducerSegment::type() const { + return(isHorizontal() ? QET::Horizontal : QET::Vertical); +} diff --git a/conducersegment.h b/conducersegment.h index 07e6bd2db..6008966d8 100644 --- a/conducersegment.h +++ b/conducersegment.h @@ -1,6 +1,7 @@ #ifndef CONDUCER_SEGMENT_H #define CONDUCER_SEGMENT_H #include +#include "qet.h" /** Cette classe represente un segment de conducteur. */ @@ -41,6 +42,7 @@ class ConducerSegment { QPointF middle() const; bool isHorizontal() const; bool isVertical() const; + QET::ConducerSegmentType type() const; qreal length() const; bool canMove1stPointX(const qreal &, qreal &) const; bool canMove2ndPointX(const qreal &, qreal &) const; diff --git a/conducersegmentprofile.h b/conducersegmentprofile.h new file mode 100644 index 000000000..98dfd9da7 --- /dev/null +++ b/conducersegmentprofile.h @@ -0,0 +1,42 @@ +#ifndef CONDUCER_SEGMENT_PROFILE_H +#define CONDUCER_SEGMENT_PROFILE_H +#include +#include "conducersegment.h" +/** + Cette classe contient le profil (= les caracteristiques essentielles) d'un + segment de conducteur. +*/ +class ConducerSegmentProfile { + // constructeurs, destructeur + public: + /** + Constructeur + @param l longueur du segment + @param ori true si le segment est horizontal, false s'il est vertical + */ + ConducerSegmentProfile(qreal l, bool ori = true) : + length(l), + isHorizontal(ori) + { + } + + /** + Constructeur + @param segment ConducerSegment dont il faut extraire le profil + */ + ConducerSegmentProfile(ConducerSegment *segment) : + length(segment -> length()), + isHorizontal(segment -> isHorizontal()) + { + } + + /// Destructeur + virtual ~ConducerSegmentProfile() { + } + + // attributs + public: + qreal length; /// longueur du segment + bool isHorizontal; /// orientation du segment +}; +#endif diff --git a/qelectrotech.pro b/qelectrotech.pro index 69eb34db1..1706316aa 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -60,7 +60,9 @@ HEADERS += aboutqet.h \ editor/texteditor.h \ editor/textfieldeditor.h \ elementscategorydeleter.h \ - elementdeleter.h + elementdeleter.h \ + conducersegmentprofile.h \ + conducerprofile.h SOURCES += aboutqet.cpp \ borderinset.cpp \ conducer.cpp \ @@ -114,7 +116,8 @@ SOURCES += aboutqet.cpp \ editor/texteditor.cpp \ editor/textfieldeditor.cpp \ elementscategorydeleter.cpp \ - elementdeleter.cpp + elementdeleter.cpp \ + conducerprofile.cpp RESOURCES += qelectrotech.qrc TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts QT += xml diff --git a/qet.h b/qet.h index 1341c994f..29fe8980f 100644 --- a/qet.h +++ b/qet.h @@ -8,6 +8,7 @@ */ namespace QET { enum Orientation {North, East, South, West}; + enum ConducerSegmentType { Horizontal = 1, Vertical = 2, Both = 3 }; QET::Orientation nextOrientation(QET::Orientation); QET::Orientation previousOrientation(QET::Orientation); QET::Orientation orientationFromString(const QString &);