diff --git a/conductor.cpp b/conductor.cpp index 2778f56e3..170208e19 100644 --- a/conductor.cpp +++ b/conductor.cpp @@ -47,6 +47,12 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene pen_and_brush_initialized = true; } + // par defaut, les 4 profils sont des profils nuls = il faut utiliser priv_calculeConductor + conductor_profiles.insert(Qt::TopLeftCorner, ConductorProfile()); + conductor_profiles.insert(Qt::TopRightCorner, ConductorProfile()); + conductor_profiles.insert(Qt::BottomLeftCorner, ConductorProfile()); + conductor_profiles.insert(Qt::BottomRightCorner, ConductorProfile()); + // calcul du rendu du conducteur priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); setFlags(QGraphicsItem::ItemIsSelectable); @@ -79,22 +85,27 @@ Conductor::~Conductor() { @param rect Rectangle a mettre a jour */ void Conductor::update(const QRectF &rect) { - // utilise soit la fonction priv_modifieConducteur soit la fonction priv_calculeConducteur - void (Conductor::* fonction_update) (const QPointF &, QET::Orientation, const QPointF &, QET::Orientation); - fonction_update = (nbSegments() && modified_path) ? &Conductor::priv_modifieConductor : &Conductor::priv_calculeConductor; - // appelle la bonne fonction pour calculer l'aspect du conducteur - (this ->* fonction_update)( - terminal1 -> amarrageConductor(), terminal1 -> orientation(), - terminal2 -> amarrageConductor(), terminal2 -> orientation() - ); + if (nbSegments() && !conductor_profiles[currentPathType()].isNull()) { + priv_modifieConductor( + terminal1 -> amarrageConductor(), terminal1 -> orientation(), + terminal2 -> amarrageConductor(), terminal2 -> orientation() + ); + } else { + priv_calculeConductor( + terminal1 -> amarrageConductor(), terminal1 -> orientation(), + terminal2 -> amarrageConductor(), terminal2 -> orientation() + ); + } + calculateTextItemPosition(); QGraphicsPathItem::update(rect); } /** - Met a jour la representation graphique du conducteur en considerant que la borne b - a pour position pos + Met a jour la representation graphique du conducteur en considerant que la + borne b a pour position pos. Cette fonction est appelee lorsqu'une seule + des bornes du conducteur a change de position. @param rect Rectangle a mettre a jour @param b Borne @param newpos position de la borne b @@ -111,7 +122,7 @@ void Conductor::updateWithNewPos(const QRectF &rect, const Terminal *b, const QP p1 = terminal1 -> amarrageConductor(); p2 = terminal2 -> amarrageConductor(); } - if (nbSegments() && modified_path) + if (nbSegments() && !conductor_profiles[currentPathType()].isNull()) priv_modifieConductor(p1, terminal1 -> orientation(), p2, terminal2 -> orientation()); else priv_calculeConductor(p1, terminal1 -> orientation(), p2, terminal2 -> orientation()); @@ -154,6 +165,9 @@ void Conductor::segmentsToPath() { @param o2 Orientation de la borne 2 */ void Conductor::priv_modifieConductor(const QPointF &p1, QET::Orientation, const QPointF &p2, QET::Orientation) { + + ConductorProfile &conductor_profile = conductor_profiles[currentPathType()]; + Q_ASSERT_X(conductor_profile.nbSegments(QET::Both) > 1, "Conductor::priv_modifieConductor", "pas de points a modifier"); Q_ASSERT_X(!conductor_profile.isNull(), "Conductor::priv_modifieConductor", "pas de profil utilisable"); @@ -957,6 +971,7 @@ ConductorSegment *Conductor::middleSegment() { @see middleSegment() */ void Conductor::calculateTextItemPosition() { + if (properties_.type != ConductorProperties::Multi) return; text_item -> setPos(middleSegment() -> middle()); } @@ -965,11 +980,12 @@ void Conductor::calculateTextItemPosition() { dans priv_modifieConductor. */ void Conductor::saveProfile(bool undo) { - ConductorProfile old_profile = conductor_profile; - conductor_profile.fromConductor(this); + Qt::Corner current_path_type = currentPathType(); + ConductorProfile old_profile(conductor_profiles[current_path_type]); + conductor_profiles[current_path_type].fromConductor(this); Diagram *dia = diagram(); if (undo && dia) { - dia -> undoStack().push(new ChangeConductorCommand(this, old_profile, conductor_profile)); + dia -> undoStack().push(new ChangeConductorCommand(this, old_profile, conductor_profiles[current_path_type], current_path_type)); } } @@ -993,22 +1009,28 @@ int Conductor::getSign(const qreal &value) { /** Applique un nouveau profil a ce conducteur @param cp Profil a appliquer a ce conducteur + @param path_type Type de trajet pour lequel ce profil convient */ -void Conductor::setProfile(const ConductorProfile &cp) { - conductor_profile = cp; - if (conductor_profile.isNull()) { - priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); - modified_path = false; - } else { - priv_modifieConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); - modified_path = true; +void Conductor::setProfile(const ConductorProfile &cp, Qt::Corner path_type) { + conductor_profiles[path_type] = cp; + // si le type de trajet correspond a l'actuel + if (currentPathType() == path_type) { + if (conductor_profiles[path_type].isNull()) { + priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); + modified_path = false; + } else { + priv_modifieConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); + modified_path = true; + } + if (type() == ConductorProperties::Multi) { + calculateTextItemPosition(); + } } - calculateTextItemPosition(); } /// @return le profil de ce conducteur -ConductorProfile Conductor::profile() const { - return(conductor_profile); +ConductorProfile Conductor::profile(Qt::Corner path_type) const { + return(conductor_profiles[path_type]); } /// @return le texte du conducteur @@ -1177,3 +1199,45 @@ bool Conductor::containsPoint(const QPointF &p) const { } return(false); } + +/** + @param start Point de depart + @param end Point d'arrivee + @return le coin vers lequel se dirige le trajet de start vers end +*/ +Qt::Corner Conductor::movementType(const QPointF &start, const QPointF &end) { + Qt::Corner result = Qt::BottomRightCorner; + if (start.x() <= end.x()) { + result = start.y() <= end.y() ? Qt::BottomRightCorner : Qt::TopRightCorner; + } else { + result = start.y() <= end.y() ? Qt::BottomLeftCorner : Qt::TopLeftCorner; + } + return(result); +} + +/// @return le type de trajet actuel de ce conducteur +Qt::Corner Conductor::currentPathType() const { + return(movementType(terminal1 -> amarrageConductor(), terminal2 -> amarrageConductor())); +} + +/// @return les profils de ce conducteur +ConductorProfilesGroup Conductor::profiles() const { + return(conductor_profiles); +} + +/** + @param cpg Les nouveaux profils de ce conducteur +*/ +void Conductor::setProfiles(const ConductorProfilesGroup &cpg) { + conductor_profiles = cpg; + if (conductor_profiles[currentPathType()].isNull()) { + priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); + modified_path = false; + } else { + priv_modifieConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); + modified_path = true; + } + if (type() == ConductorProperties::Multi) { + calculateTextItemPosition(); + } +} diff --git a/conductor.h b/conductor.h index 74b0dacad..c6d4f3bd8 100644 --- a/conductor.h +++ b/conductor.h @@ -8,7 +8,7 @@ class ConductorSegment; class Element; typedef QPair ConductorBend; - +typedef QHash ConductorProfilesGroup; /** Cette classe represente un conducteur. Un conducteur relie deux bornes d'element. */ @@ -54,8 +54,10 @@ class Conductor : public QGraphicsPathItem { const QList segmentsList() const; void setProperties(const ConductorProperties &); ConductorProperties properties() const; - void setProfile(const ConductorProfile &); - ConductorProfile profile() const; + void setProfile(const ConductorProfile &, Qt::Corner); + ConductorProfile profile(Qt::Corner) const; + void setProfiles(const ConductorProfilesGroup &); + ConductorProfilesGroup profiles() const; void readProperties(); protected: @@ -84,8 +86,8 @@ class Conductor : public QGraphicsPathItem { bool modified_path; /// booleen indiquant s'il faut sauver le profil courant au plus tot bool has_to_save_profile; - /// profil du conducteur : "photo" de ce a quoi le conducteur doit ressembler - ConductorProfile conductor_profile; + /// profil du conducteur : "photo" de ce a quoi le conducteur doit ressembler - il y a un profil par type de trajet + ConductorProfilesGroup conductor_profiles; /// QPen et QBrush utilises pour dessiner les conducteurs static QPen conductor_pen; static QBrush conductor_brush; @@ -105,11 +107,13 @@ class Conductor : public QGraphicsPathItem { void pointsToSegments(QList); bool hasClickedOn(QPointF, QPointF) const; void calculateTextItemPosition(); + Qt::Corner currentPathType() const; 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 conductor_bound(qreal, qreal, qreal, qreal = 0.0); static qreal conductor_bound(qreal, qreal, bool); + static Qt::Corner movementType(const QPointF &, const QPointF &); }; #endif diff --git a/diagramcommands.cpp b/diagramcommands.cpp index 25d96f05d..bbe3b9ab1 100644 --- a/diagramcommands.cpp +++ b/diagramcommands.cpp @@ -363,12 +363,14 @@ ChangeConductorCommand::ChangeConductorCommand( Conductor *c, const ConductorProfile &old_p, const ConductorProfile &new_p, + Qt::Corner path_t, QUndoCommand *parent ) : QUndoCommand(QObject::tr("modifier un conducteur"), parent), conductor(c), old_profile(old_p), new_profile(new_p), + path_type(path_t), first_redo(true) { } @@ -379,13 +381,13 @@ ChangeConductorCommand::~ChangeConductorCommand() { /// Annule la modification du conducteur void ChangeConductorCommand::undo() { - conductor -> setProfile(old_profile); + conductor -> setProfile(old_profile, path_type); } /// Refait la modification du conducteur void ChangeConductorCommand::redo() { if (first_redo) first_redo = false; - else conductor -> setProfile(new_profile); + else conductor -> setProfile(new_profile, path_type); } /** @@ -394,7 +396,7 @@ void ChangeConductorCommand::redo() { @param parent QUndoCommand parent */ ResetConductorCommand::ResetConductorCommand( - const QHash &cp, + const QHash &cp, QUndoCommand *parent ) : QUndoCommand(QObject::tr("R\351initialiser ") + QET::ElementsAndConductorsSentence(0, cp.count()), parent), @@ -409,15 +411,14 @@ ResetConductorCommand::~ResetConductorCommand() { /// Annule la reinitialisation des conducteurs void ResetConductorCommand::undo() { foreach(Conductor *c, conductors_profiles.keys()) { - c -> setProfile(conductors_profiles[c]); + c -> setProfiles(conductors_profiles[c]); } } /// Refait la reinitialisation des conducteurs void ResetConductorCommand::redo() { foreach(Conductor *c, conductors_profiles.keys()) { - ConductorProfile t(conductors_profiles[c]); - c -> setProfile(ConductorProfile()); + c -> setProfiles(ConductorProfilesGroup()); } } diff --git a/diagramcommands.h b/diagramcommands.h index 3445c4859..e4a2665b3 100644 --- a/diagramcommands.h +++ b/diagramcommands.h @@ -214,7 +214,7 @@ class RotateElementsCommand : public QUndoCommand { class ChangeConductorCommand : public QUndoCommand { // constructeurs, destructeur public: - ChangeConductorCommand(Conductor *, const ConductorProfile &, const ConductorProfile &, QUndoCommand * = 0); + ChangeConductorCommand(Conductor *, const ConductorProfile &, const ConductorProfile &, Qt::Corner, QUndoCommand * = 0); virtual ~ChangeConductorCommand(); private: ChangeConductorCommand(const ChangeConductorCommand &); @@ -232,6 +232,8 @@ class ChangeConductorCommand : public QUndoCommand { ConductorProfile old_profile; /// profil apres changement ConductorProfile new_profile; + /// Type de trajet + Qt::Corner path_type; /// booleen pour ne pas executer le premier redo() bool first_redo; }; @@ -242,7 +244,7 @@ class ChangeConductorCommand : public QUndoCommand { class ResetConductorCommand : public QUndoCommand { // constructeurs, destructeur public: - ResetConductorCommand(const QHash &, QUndoCommand * = 0); + ResetConductorCommand(const QHash &, QUndoCommand * = 0); virtual ~ResetConductorCommand(); private: ResetConductorCommand(const ResetConductorCommand &); @@ -255,7 +257,7 @@ class ResetConductorCommand : public QUndoCommand { // attributs private: /// conducteurs reinitialises associes a leur ancien profil - QHash conductors_profiles; + QHash conductors_profiles; }; /** diff --git a/diagramview.cpp b/diagramview.cpp index 709cab2d9..f5e743d0b 100644 --- a/diagramview.cpp +++ b/diagramview.cpp @@ -738,10 +738,17 @@ void DiagramView::resetConductors() { QSet selected_conductors = scene -> selectedConductors(); // repere les conducteurs modifies (= profil non nul) - QHash conductors_and_profiles; + QHash conductors_and_profiles; foreach(Conductor *conductor, selected_conductors) { - ConductorProfile profile = conductor -> profile(); - if (!profile.isNull()) conductors_and_profiles.insert(conductor, profile); + ConductorProfilesGroup profile = conductor -> profiles(); + if ( + !profile[Qt::TopLeftCorner].isNull() ||\ + !profile[Qt::TopRightCorner].isNull() ||\ + !profile[Qt::BottomLeftCorner].isNull() ||\ + !profile[Qt::BottomRightCorner].isNull() + ) { + conductors_and_profiles.insert(conductor, profile); + } } if (conductors_and_profiles.isEmpty()) return;