diff --git a/borne.cpp b/borne.cpp index 1741b5c7f..50dac75ce 100644 --- a/borne.cpp +++ b/borne.cpp @@ -92,17 +92,16 @@ Borne::~Borne() { Borne::Orientation Borne::orientation() const { //true pour une orientation verticale, false pour une orientation horizontale if (Element *elt = qgraphicsitem_cast(parentItem())) { - if (elt -> orientation()) return(sens); + // orientations actuelle et par defaut de l'element + Borne::Orientation ori_cur = elt -> orientation(); + Borne::Orientation ori_def = elt -> defaultOrientation(); + if (ori_cur == ori_def) return(sens); else { - Borne::Orientation retour; - switch(sens) { - case Borne::Nord : retour = Borne::Ouest; break; - case Borne::Est : retour = Borne::Nord; break; - case Borne::Ouest : retour = Borne::Sud; break; - case Borne::Sud : - default : retour = Borne::Est; - } - return(retour); + /* calcul l'angle de rotation implique par l'orientation de l'element parent */ + // angle de rotation de la borne sur la scene, divise par 90 + int angle = ori_cur - ori_def + sens; + while (angle >= 4) angle -= 4; + return((Borne::Orientation)angle); } } else return(sens); } diff --git a/borne.h b/borne.h index a7f58782d..693c3a431 100644 --- a/borne.h +++ b/borne.h @@ -13,7 +13,7 @@ class Borne : public QGraphicsItem { public: // enum definissant l'orientation de la borne - enum Orientation {Nord, Sud, Est, Ouest}; + enum Orientation {Nord, Est, Sud, Ouest}; // permet de caster un QGraphicsItem en Borne avec qgraphicsitem_cast enum { Type = UserType + 1002 }; diff --git a/element.cpp b/element.cpp index 9e3fe17d2..0223c8d9d 100644 --- a/element.cpp +++ b/element.cpp @@ -8,7 +8,6 @@ Constructeur pour un element sans scene ni parent */ Element::Element(QGraphicsItem *parent, Schema *scene) : QGraphicsItem(parent, scene) { - sens = true; peut_relier_ses_propres_bornes = false; } @@ -110,29 +109,19 @@ QVariant Element::itemChange(GraphicsItemChange change, const QVariant &value) { return(QGraphicsItem::itemChange(change, value)); } -/** - @return L'orientation en cours de l'element : true pour une orientation verticale, false pour une orientation horizontale -*/ -bool Element::orientation() const { - return(sens); -} - -/** - Inverse l'orientation de l'element - @return La nouvelle orientation : true pour une orientation verticale, false pour une orientation horizontale -*/ -bool Element::invertOrientation() { - // inversion du sens - sens = !sens; +bool Element::setOrientation(Borne::Orientation o) { + // verifie que l'orientation demandee est acceptee + if (!acceptOrientation(o)) return(false); // on cache temporairement l'element pour eviter un bug graphique hide(); // rotation en consequence et rafraichissement de l'element graphique - rotate(sens ? 90.0 : -90.0); + rotate(90.0 * (o - ori)); + ori = o; // on raffiche l'element, on le reselectionne et on le rafraichit show(); select(); update(); - return(sens); + return(true); } /*** Methodes protegees ***/ diff --git a/element.h b/element.h index 3a781fe78..b15819a91 100644 --- a/element.h +++ b/element.h @@ -33,16 +33,62 @@ inline void setConnexionsInternesAcceptees(bool cia) { peut_relier_ses_propres_bornes = cia; } static bool valideXml(QDomElement &); virtual bool fromXml(QDomElement &, QHash&) = 0; + // methodes d'acces aux possibilites d'orientation + inline Borne::Orientation orientation() { return(ori); } + inline bool acceptOrientation(Borne::Orientation o) { + switch(o) { + case Borne::Nord: return(ori_n); + case Borne::Est: return(ori_e); + case Borne::Sud: return(ori_s); + case Borne::Ouest: return(ori_w); + default: return(false); + } + } + inline Borne::Orientation defaultOrientation() { return(ori_d); } + inline Borne::Orientation nextAcceptableOrientation() { + Borne::Orientation retour = nextOrientation(ori); + for (int i = 0 ; i < 4 ; ++ i) { + if (acceptOrientation(retour)) return(retour); + retour = nextOrientation(retour); + } + // on ne devrait pas arriver la : renvoi d'une valeur par defaut = nord + return(Borne::Nord); + } + inline Borne::Orientation previousAcceptableOrientation() { + Borne::Orientation retour = previousOrientation(ori); + for (int i = 0 ; i < 4 ; ++ i) { + if (acceptOrientation(retour)) return(retour); + retour = previousOrientation(retour); + } + // on ne devrait pas arriver la : renvoi d'une valeur par defaut = nord + return(Borne::Nord); + } + bool setOrientation(Borne::Orientation o); protected: void drawAxes(QPainter *, const QStyleOptionGraphicsItem *); void mouseMoveEvent(QGraphicsSceneMouseEvent *); + bool ori_n; + bool ori_s; + bool ori_e; + bool ori_w; + Borne::Orientation ori_d; + Borne::Orientation ori; private: bool peut_relier_ses_propres_bornes; void drawSelection(QPainter *, const QStyleOptionGraphicsItem *); void updatePixmap(); - bool sens; + inline Borne::Orientation nextOrientation(Borne::Orientation o) { + if (o < 0 || o > 2) return(Borne::Nord); + return((Borne::Orientation)(o + 1)); + } + inline Borne::Orientation previousOrientation(Borne::Orientation o) { + if (o < 0 || o > 3) return(Borne::Nord); + if (o == Borne::Nord) return(Borne::Ouest); + return((Borne::Orientation)(o - 1)); + } + QSize dimensions; QPoint hotspot_coord; QPixmap apercu; diff --git a/elementperso.cpp b/elementperso.cpp index be28983ff..ad8759fac 100644 --- a/elementperso.cpp +++ b/elementperso.cpp @@ -44,7 +44,8 @@ ElementPerso::ElementPerso(QString &nom_fichier, QGraphicsItem *qgi, Schema *s, !attributeIsAnInteger(racine, QString("width"), &w) ||\ !attributeIsAnInteger(racine, QString("height"), &h) ||\ !attributeIsAnInteger(racine, QString("hotspot_x"), &hot_x) ||\ - !attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) + !attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) ||\ + !validOrientationAttribute(racine) ) { if (etat != NULL) *etat = 5; elmt_etat = 5; @@ -209,3 +210,30 @@ bool ElementPerso::attributeIsAReal(QDomElement &e, QString nom_attribut, double if (reel != NULL) *reel = tmp; return(true); } + +bool ElementPerso::validOrientationAttribute(QDomElement &e) { + // verifie la presence de l'attribut orientation + if (!e.hasAttribute("orientation")) return(false); + QString t = e.attribute("orientation"); + // verification syntaxique : 4 lettres, un d, que des y ou des n pour le reste + if (t.length() != 4) return(false); + int d_pos = -1; + for (int i = 0 ; i < 4 ; ++ i) { + QChar c = t.at(i); + if (c != 'd' && c != 'y' && c != 'n') return(false); + if (c == 'd') { + if (d_pos == -1) d_pos = i; + else return(false); + } + } + if (d_pos == -1) return(false); + + // orientation : 4 lettres = nord/est/sud/ouest avec d = default, y = yes et n = no + ori_n = (t.at(0) == 'd' || t.at(0) == 'y'); + ori_e = (t.at(1) == 'd' || t.at(1) == 'y'); + ori_s = (t.at(2) == 'd' || t.at(2) == 'y'); + ori_w = (t.at(3) == 'd' || t.at(3) == 'y'); + ori_d = (Borne::Orientation)d_pos; + ori = ori_d; + return(true); +} diff --git a/elementperso.h b/elementperso.h index 1c629306b..240bec908 100644 --- a/elementperso.h +++ b/elementperso.h @@ -26,6 +26,7 @@ void setQPainterAntiAliasing(QPainter *, bool); bool attributeIsAnInteger(QDomElement &, QString, int * = NULL); bool attributeIsAReal(QDomElement &, QString, double * = NULL); + bool validOrientationAttribute(QDomElement &); int nb_bornes; }; #endif diff --git a/elements/entree.elmt b/elements/entree.elmt index 8e99e47bb..48d5a2ae7 100644 --- a/elements/entree.elmt +++ b/elements/entree.elmt @@ -1,5 +1,5 @@ - + diff --git a/schema.cpp b/schema.cpp index 5c2f9aa9a..1bc4010e4 100644 --- a/schema.cpp +++ b/schema.cpp @@ -149,7 +149,7 @@ QDomDocument Schema::toXml(bool schema) { element.setAttribute("x", elmt -> pos().x()); element.setAttribute("y", elmt -> pos().y()); if (elmt -> isSelected()) element.setAttribute("selected", "selected"); - element.setAttribute("sens", elmt -> orientation() ? "true" : "false"); + element.setAttribute("sens", QString("%1").arg(elmt -> orientation())); // enregistrements des bornes de chaque appareil QDomElement bornes = document.createElement("bornes"); @@ -303,6 +303,8 @@ Element *Schema::elementFromXml(QDomElement &e, QHash &table_id_ad int etat; Element *nvel_elmt = new ElementPerso(chemin_fichier, 0, 0, &etat); if (etat != 0) return(false); + + // charge les caracteristiques de l'element bool retour = nvel_elmt -> fromXml(e, table_id_adr); if (!retour) { delete nvel_elmt; @@ -311,7 +313,10 @@ Element *Schema::elementFromXml(QDomElement &e, QHash &table_id_ad addItem(nvel_elmt); nvel_elmt -> setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble()); nvel_elmt -> setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable); - if (e.attribute("sens") == "false") nvel_elmt -> invertOrientation(); + bool conv_ok; + int read_ori = e.attribute("sens").toInt(&conv_ok); + if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = nvel_elmt -> defaultOrientation(); + nvel_elmt -> setOrientation((Borne::Orientation)read_ori); nvel_elmt -> setSelected(e.attribute("selected") == "selected"); } return(retour ? nvel_elmt : NULL); diff --git a/schemavue.cpp b/schemavue.cpp index 5b2be2316..ef1467e9e 100644 --- a/schemavue.cpp +++ b/schemavue.cpp @@ -151,7 +151,7 @@ void SchemaVue::pivoter() { if (scene -> selectedItems().isEmpty()) return; foreach (QGraphicsItem *item, scene -> selectedItems()) { if (Element *elt = qgraphicsitem_cast(item)) { - elt -> invertOrientation(); + elt -> setOrientation(elt -> nextAcceptableOrientation()); elt -> update(); } }