Changement dans l'algorithme de modification des conducteurs : un conducteur a desormais 4 profils au lieu d'un

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@192 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet
2007-10-22 20:27:39 +00:00
parent 8d774aa4d6
commit 20a9a5158c
5 changed files with 120 additions and 42 deletions

View File

@@ -47,6 +47,12 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene
pen_and_brush_initialized = true; 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 // calcul du rendu du conducteur
priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation());
setFlags(QGraphicsItem::ItemIsSelectable); setFlags(QGraphicsItem::ItemIsSelectable);
@@ -79,22 +85,27 @@ Conductor::~Conductor() {
@param rect Rectangle a mettre a jour @param rect Rectangle a mettre a jour
*/ */
void Conductor::update(const QRectF &rect) { 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 // appelle la bonne fonction pour calculer l'aspect du conducteur
(this ->* fonction_update)( if (nbSegments() && !conductor_profiles[currentPathType()].isNull()) {
terminal1 -> amarrageConductor(), terminal1 -> orientation(), priv_modifieConductor(
terminal2 -> amarrageConductor(), terminal2 -> orientation() terminal1 -> amarrageConductor(), terminal1 -> orientation(),
); terminal2 -> amarrageConductor(), terminal2 -> orientation()
);
} else {
priv_calculeConductor(
terminal1 -> amarrageConductor(), terminal1 -> orientation(),
terminal2 -> amarrageConductor(), terminal2 -> orientation()
);
}
calculateTextItemPosition(); calculateTextItemPosition();
QGraphicsPathItem::update(rect); QGraphicsPathItem::update(rect);
} }
/** /**
Met a jour la representation graphique du conducteur en considerant que la borne b Met a jour la representation graphique du conducteur en considerant que la
a pour position pos 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 rect Rectangle a mettre a jour
@param b Borne @param b Borne
@param newpos position de la borne b @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(); p1 = terminal1 -> amarrageConductor();
p2 = terminal2 -> amarrageConductor(); p2 = terminal2 -> amarrageConductor();
} }
if (nbSegments() && modified_path) if (nbSegments() && !conductor_profiles[currentPathType()].isNull())
priv_modifieConductor(p1, terminal1 -> orientation(), p2, terminal2 -> orientation()); priv_modifieConductor(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
else else
priv_calculeConductor(p1, terminal1 -> orientation(), p2, terminal2 -> orientation()); priv_calculeConductor(p1, terminal1 -> orientation(), p2, terminal2 -> orientation());
@@ -154,6 +165,9 @@ void Conductor::segmentsToPath() {
@param o2 Orientation de la borne 2 @param o2 Orientation de la borne 2
*/ */
void Conductor::priv_modifieConductor(const QPointF &p1, QET::Orientation, const QPointF &p2, QET::Orientation) { 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.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"); Q_ASSERT_X(!conductor_profile.isNull(), "Conductor::priv_modifieConductor", "pas de profil utilisable");
@@ -957,6 +971,7 @@ ConductorSegment *Conductor::middleSegment() {
@see middleSegment() @see middleSegment()
*/ */
void Conductor::calculateTextItemPosition() { void Conductor::calculateTextItemPosition() {
if (properties_.type != ConductorProperties::Multi) return;
text_item -> setPos(middleSegment() -> middle()); text_item -> setPos(middleSegment() -> middle());
} }
@@ -965,11 +980,12 @@ void Conductor::calculateTextItemPosition() {
dans priv_modifieConductor. dans priv_modifieConductor.
*/ */
void Conductor::saveProfile(bool undo) { void Conductor::saveProfile(bool undo) {
ConductorProfile old_profile = conductor_profile; Qt::Corner current_path_type = currentPathType();
conductor_profile.fromConductor(this); ConductorProfile old_profile(conductor_profiles[current_path_type]);
conductor_profiles[current_path_type].fromConductor(this);
Diagram *dia = diagram(); Diagram *dia = diagram();
if (undo && dia) { 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 Applique un nouveau profil a ce conducteur
@param cp Profil a appliquer 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) { void Conductor::setProfile(const ConductorProfile &cp, Qt::Corner path_type) {
conductor_profile = cp; conductor_profiles[path_type] = cp;
if (conductor_profile.isNull()) { // si le type de trajet correspond a l'actuel
priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); if (currentPathType() == path_type) {
modified_path = false; if (conductor_profiles[path_type].isNull()) {
} else { priv_calculeConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation());
priv_modifieConductor(terminal1 -> amarrageConductor(), terminal1 -> orientation(), terminal2 -> amarrageConductor(), terminal2 -> orientation()); modified_path = false;
modified_path = true; } 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 /// @return le profil de ce conducteur
ConductorProfile Conductor::profile() const { ConductorProfile Conductor::profile(Qt::Corner path_type) const {
return(conductor_profile); return(conductor_profiles[path_type]);
} }
/// @return le texte du conducteur /// @return le texte du conducteur
@@ -1177,3 +1199,45 @@ bool Conductor::containsPoint(const QPointF &p) const {
} }
return(false); 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();
}
}

View File

@@ -8,7 +8,7 @@
class ConductorSegment; class ConductorSegment;
class Element; class Element;
typedef QPair<QPointF, Qt::Corner> ConductorBend; typedef QPair<QPointF, Qt::Corner> ConductorBend;
typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
/** /**
Cette classe represente un conducteur. Un conducteur relie deux bornes d'element. Cette classe represente un conducteur. Un conducteur relie deux bornes d'element.
*/ */
@@ -54,8 +54,10 @@ class Conductor : public QGraphicsPathItem {
const QList<ConductorSegment *> segmentsList() const; const QList<ConductorSegment *> segmentsList() const;
void setProperties(const ConductorProperties &); void setProperties(const ConductorProperties &);
ConductorProperties properties() const; ConductorProperties properties() const;
void setProfile(const ConductorProfile &); void setProfile(const ConductorProfile &, Qt::Corner);
ConductorProfile profile() const; ConductorProfile profile(Qt::Corner) const;
void setProfiles(const ConductorProfilesGroup &);
ConductorProfilesGroup profiles() const;
void readProperties(); void readProperties();
protected: protected:
@@ -84,8 +86,8 @@ class Conductor : public QGraphicsPathItem {
bool modified_path; bool modified_path;
/// booleen indiquant s'il faut sauver le profil courant au plus tot /// booleen indiquant s'il faut sauver le profil courant au plus tot
bool has_to_save_profile; bool has_to_save_profile;
/// profil du conducteur : "photo" de ce a quoi le conducteur doit ressembler /// profil du conducteur : "photo" de ce a quoi le conducteur doit ressembler - il y a un profil par type de trajet
ConductorProfile conductor_profile; ConductorProfilesGroup conductor_profiles;
/// QPen et QBrush utilises pour dessiner les conducteurs /// QPen et QBrush utilises pour dessiner les conducteurs
static QPen conductor_pen; static QPen conductor_pen;
static QBrush conductor_brush; static QBrush conductor_brush;
@@ -105,11 +107,13 @@ class Conductor : public QGraphicsPathItem {
void pointsToSegments(QList<QPointF>); void pointsToSegments(QList<QPointF>);
bool hasClickedOn(QPointF, QPointF) const; bool hasClickedOn(QPointF, QPointF) const;
void calculateTextItemPosition(); void calculateTextItemPosition();
Qt::Corner currentPathType() const;
static int getCoeff(const qreal &, const qreal &); static int getCoeff(const qreal &, const qreal &);
static int getSign(const qreal &); static int getSign(const qreal &);
QHash<ConductorSegmentProfile *, qreal> shareOffsetBetweenSegments(const qreal &offset, const QList<ConductorSegmentProfile *> &, const qreal & = 0.01) const; QHash<ConductorSegmentProfile *, qreal> shareOffsetBetweenSegments(const qreal &offset, const QList<ConductorSegmentProfile *> &, const qreal & = 0.01) const;
static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 12.0); 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, qreal, qreal = 0.0);
static qreal conductor_bound(qreal, qreal, bool); static qreal conductor_bound(qreal, qreal, bool);
static Qt::Corner movementType(const QPointF &, const QPointF &);
}; };
#endif #endif

View File

@@ -363,12 +363,14 @@ ChangeConductorCommand::ChangeConductorCommand(
Conductor *c, Conductor *c,
const ConductorProfile &old_p, const ConductorProfile &old_p,
const ConductorProfile &new_p, const ConductorProfile &new_p,
Qt::Corner path_t,
QUndoCommand *parent QUndoCommand *parent
) : ) :
QUndoCommand(QObject::tr("modifier un conducteur"), parent), QUndoCommand(QObject::tr("modifier un conducteur"), parent),
conductor(c), conductor(c),
old_profile(old_p), old_profile(old_p),
new_profile(new_p), new_profile(new_p),
path_type(path_t),
first_redo(true) first_redo(true)
{ {
} }
@@ -379,13 +381,13 @@ ChangeConductorCommand::~ChangeConductorCommand() {
/// Annule la modification du conducteur /// Annule la modification du conducteur
void ChangeConductorCommand::undo() { void ChangeConductorCommand::undo() {
conductor -> setProfile(old_profile); conductor -> setProfile(old_profile, path_type);
} }
/// Refait la modification du conducteur /// Refait la modification du conducteur
void ChangeConductorCommand::redo() { void ChangeConductorCommand::redo() {
if (first_redo) first_redo = false; 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 @param parent QUndoCommand parent
*/ */
ResetConductorCommand::ResetConductorCommand( ResetConductorCommand::ResetConductorCommand(
const QHash<Conductor *, ConductorProfile> &cp, const QHash<Conductor *, ConductorProfilesGroup> &cp,
QUndoCommand *parent QUndoCommand *parent
) : ) :
QUndoCommand(QObject::tr("R\351initialiser ") + QET::ElementsAndConductorsSentence(0, cp.count()), parent), QUndoCommand(QObject::tr("R\351initialiser ") + QET::ElementsAndConductorsSentence(0, cp.count()), parent),
@@ -409,15 +411,14 @@ ResetConductorCommand::~ResetConductorCommand() {
/// Annule la reinitialisation des conducteurs /// Annule la reinitialisation des conducteurs
void ResetConductorCommand::undo() { void ResetConductorCommand::undo() {
foreach(Conductor *c, conductors_profiles.keys()) { foreach(Conductor *c, conductors_profiles.keys()) {
c -> setProfile(conductors_profiles[c]); c -> setProfiles(conductors_profiles[c]);
} }
} }
/// Refait la reinitialisation des conducteurs /// Refait la reinitialisation des conducteurs
void ResetConductorCommand::redo() { void ResetConductorCommand::redo() {
foreach(Conductor *c, conductors_profiles.keys()) { foreach(Conductor *c, conductors_profiles.keys()) {
ConductorProfile t(conductors_profiles[c]); c -> setProfiles(ConductorProfilesGroup());
c -> setProfile(ConductorProfile());
} }
} }

View File

@@ -214,7 +214,7 @@ class RotateElementsCommand : public QUndoCommand {
class ChangeConductorCommand : public QUndoCommand { class ChangeConductorCommand : public QUndoCommand {
// constructeurs, destructeur // constructeurs, destructeur
public: public:
ChangeConductorCommand(Conductor *, const ConductorProfile &, const ConductorProfile &, QUndoCommand * = 0); ChangeConductorCommand(Conductor *, const ConductorProfile &, const ConductorProfile &, Qt::Corner, QUndoCommand * = 0);
virtual ~ChangeConductorCommand(); virtual ~ChangeConductorCommand();
private: private:
ChangeConductorCommand(const ChangeConductorCommand &); ChangeConductorCommand(const ChangeConductorCommand &);
@@ -232,6 +232,8 @@ class ChangeConductorCommand : public QUndoCommand {
ConductorProfile old_profile; ConductorProfile old_profile;
/// profil apres changement /// profil apres changement
ConductorProfile new_profile; ConductorProfile new_profile;
/// Type de trajet
Qt::Corner path_type;
/// booleen pour ne pas executer le premier redo() /// booleen pour ne pas executer le premier redo()
bool first_redo; bool first_redo;
}; };
@@ -242,7 +244,7 @@ class ChangeConductorCommand : public QUndoCommand {
class ResetConductorCommand : public QUndoCommand { class ResetConductorCommand : public QUndoCommand {
// constructeurs, destructeur // constructeurs, destructeur
public: public:
ResetConductorCommand(const QHash<Conductor *, ConductorProfile> &, QUndoCommand * = 0); ResetConductorCommand(const QHash<Conductor *, ConductorProfilesGroup> &, QUndoCommand * = 0);
virtual ~ResetConductorCommand(); virtual ~ResetConductorCommand();
private: private:
ResetConductorCommand(const ResetConductorCommand &); ResetConductorCommand(const ResetConductorCommand &);
@@ -255,7 +257,7 @@ class ResetConductorCommand : public QUndoCommand {
// attributs // attributs
private: private:
/// conducteurs reinitialises associes a leur ancien profil /// conducteurs reinitialises associes a leur ancien profil
QHash<Conductor *, ConductorProfile> conductors_profiles; QHash<Conductor *, ConductorProfilesGroup> conductors_profiles;
}; };
/** /**

View File

@@ -738,10 +738,17 @@ void DiagramView::resetConductors() {
QSet<Conductor *> selected_conductors = scene -> selectedConductors(); QSet<Conductor *> selected_conductors = scene -> selectedConductors();
// repere les conducteurs modifies (= profil non nul) // repere les conducteurs modifies (= profil non nul)
QHash<Conductor *, ConductorProfile> conductors_and_profiles; QHash<Conductor *, ConductorProfilesGroup> conductors_and_profiles;
foreach(Conductor *conductor, selected_conductors) { foreach(Conductor *conductor, selected_conductors) {
ConductorProfile profile = conductor -> profile(); ConductorProfilesGroup profile = conductor -> profiles();
if (!profile.isNull()) conductors_and_profiles.insert(conductor, profile); 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; if (conductors_and_profiles.isEmpty()) return;