Ajout de l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@94 bfdf4180-ca20-0410-9c96-a3a8aa849046
60
conducer.cpp
@ -74,7 +74,7 @@ Conducer::~Conducer() {
|
|||||||
*/
|
*/
|
||||||
void Conducer::update(const QRectF &rect) {
|
void Conducer::update(const QRectF &rect) {
|
||||||
// utilise soit la fonction priv_modifieConducteur soit la fonction priv_calculeConducteur
|
// utilise soit la fonction priv_modifieConducteur soit la fonction priv_calculeConducteur
|
||||||
void (Conducer::* fonction_update) (const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
void (Conducer::* fonction_update) (const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
|
||||||
fonction_update = (nbSegments() && modified_path) ? &Conducer::priv_modifieConducer : &Conducer::priv_calculeConducer;
|
fonction_update = (nbSegments() && modified_path) ? &Conducer::priv_modifieConducer : &Conducer::priv_calculeConducer;
|
||||||
|
|
||||||
// appelle la bonne fonction pour calculer l'aspect du conducteur
|
// appelle la bonne fonction pour calculer l'aspect du conducteur
|
||||||
@ -147,7 +147,7 @@ void Conducer::segmentsToPath() {
|
|||||||
@param p2 Coordonnees du point d'amarrage de la borne 2
|
@param p2 Coordonnees du point d'amarrage de la borne 2
|
||||||
@param o2 Orientation de la borne 2
|
@param o2 Orientation de la borne 2
|
||||||
*/
|
*/
|
||||||
void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, const QPointF &p2, Terminal::Orientation) {
|
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");
|
Q_ASSERT_X(nbSegments() > 1, "priv_modifieConducer", "pas de points a modifier");
|
||||||
|
|
||||||
// recupere les dernieres coordonnees connues des bornes
|
// recupere les dernieres coordonnees connues des bornes
|
||||||
@ -194,9 +194,9 @@ void Conducer::priv_modifieConducer(const QPointF &p1, Terminal::Orientation, co
|
|||||||
@param p2 Coordonnees du point d'amarrage de la borne 2
|
@param p2 Coordonnees du point d'amarrage de la borne 2
|
||||||
@param o2 Orientation de la borne 2
|
@param o2 Orientation de la borne 2
|
||||||
*/
|
*/
|
||||||
void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1, const QPointF &p2, Terminal::Orientation o2) {
|
void Conducer::priv_calculeConducer(const QPointF &p1, QET::Orientation o1, const QPointF &p2, QET::Orientation o2) {
|
||||||
QPointF sp1, sp2, depart, newp1, newp2, arrivee, depart0, arrivee0;
|
QPointF sp1, sp2, depart, newp1, newp2, arrivee, depart0, arrivee0;
|
||||||
Terminal::Orientation ori_depart, ori_arrivee;
|
QET::Orientation ori_depart, ori_arrivee;
|
||||||
|
|
||||||
// s'assure qu'il n'y a ni points
|
// s'assure qu'il n'y a ni points
|
||||||
QList<QPointF> points;
|
QList<QPointF> points;
|
||||||
@ -236,34 +236,34 @@ void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1,
|
|||||||
// commence le vrai trajet
|
// commence le vrai trajet
|
||||||
if (depart.y() < arrivee.y()) {
|
if (depart.y() < arrivee.y()) {
|
||||||
// trajet descendant
|
// trajet descendant
|
||||||
if ((ori_depart == Terminal::Nord && (ori_arrivee == Terminal::Sud || ori_arrivee == Terminal::Ouest)) || (ori_depart == Terminal::Est && ori_arrivee == Terminal::Ouest)) {
|
if ((ori_depart == QET::North && (ori_arrivee == QET::South || ori_arrivee == QET::West)) || (ori_depart == QET::East && ori_arrivee == QET::West)) {
|
||||||
// cas « 3 »
|
// cas « 3 »
|
||||||
qreal ligne_inter_x = (depart.x() + arrivee.x()) / 2.0;
|
qreal ligne_inter_x = (depart.x() + arrivee.x()) / 2.0;
|
||||||
points << QPointF(ligne_inter_x, depart.y());
|
points << QPointF(ligne_inter_x, depart.y());
|
||||||
points << QPointF(ligne_inter_x, arrivee.y());
|
points << QPointF(ligne_inter_x, arrivee.y());
|
||||||
} else if ((ori_depart == Terminal::Sud && (ori_arrivee == Terminal::Nord || ori_arrivee == Terminal::Est)) || (ori_depart == Terminal::Ouest && ori_arrivee == Terminal::Est)) {
|
} else if ((ori_depart == QET::South && (ori_arrivee == QET::North || ori_arrivee == QET::East)) || (ori_depart == QET::West && ori_arrivee == QET::East)) {
|
||||||
// cas « 4 »
|
// cas « 4 »
|
||||||
qreal ligne_inter_y = (depart.y() + arrivee.y()) / 2.0;
|
qreal ligne_inter_y = (depart.y() + arrivee.y()) / 2.0;
|
||||||
points << QPointF(depart.x(), ligne_inter_y);
|
points << QPointF(depart.x(), ligne_inter_y);
|
||||||
points << QPointF(arrivee.x(), ligne_inter_y);
|
points << QPointF(arrivee.x(), ligne_inter_y);
|
||||||
} else if ((ori_depart == Terminal::Nord || ori_depart == Terminal::Est) && (ori_arrivee == Terminal::Nord || ori_arrivee == Terminal::Est)) {
|
} else if ((ori_depart == QET::North || ori_depart == QET::East) && (ori_arrivee == QET::North || ori_arrivee == QET::East)) {
|
||||||
points << QPointF(arrivee.x(), depart.y()); // cas « 2 »
|
points << QPointF(arrivee.x(), depart.y()); // cas « 2 »
|
||||||
} else {
|
} else {
|
||||||
points << QPointF(depart.x(), arrivee.y()); // cas « 1 »
|
points << QPointF(depart.x(), arrivee.y()); // cas « 1 »
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// trajet montant
|
// trajet montant
|
||||||
if ((ori_depart == Terminal::Ouest && (ori_arrivee == Terminal::Est || ori_arrivee == Terminal::Sud)) || (ori_depart == Terminal::Nord && ori_arrivee == Terminal::Sud)) {
|
if ((ori_depart == QET::West && (ori_arrivee == QET::East || ori_arrivee == QET::South)) || (ori_depart == QET::North && ori_arrivee == QET::South)) {
|
||||||
// cas « 3 »
|
// cas « 3 »
|
||||||
qreal ligne_inter_y = (depart.y() + arrivee.y()) / 2.0;
|
qreal ligne_inter_y = (depart.y() + arrivee.y()) / 2.0;
|
||||||
points << QPointF(depart.x(), ligne_inter_y);
|
points << QPointF(depart.x(), ligne_inter_y);
|
||||||
points << QPointF(arrivee.x(), ligne_inter_y);
|
points << QPointF(arrivee.x(), ligne_inter_y);
|
||||||
} else if ((ori_depart == Terminal::Est && (ori_arrivee == Terminal::Ouest || ori_arrivee == Terminal::Nord)) || (ori_depart == Terminal::Sud && ori_arrivee == Terminal::Nord)) {
|
} else if ((ori_depart == QET::East && (ori_arrivee == QET::West || ori_arrivee == QET::North)) || (ori_depart == QET::South && ori_arrivee == QET::North)) {
|
||||||
// cas « 4 »
|
// cas « 4 »
|
||||||
qreal ligne_inter_x = (depart.x() + arrivee.x()) / 2.0;
|
qreal ligne_inter_x = (depart.x() + arrivee.x()) / 2.0;
|
||||||
points << QPointF(ligne_inter_x, depart.y());
|
points << QPointF(ligne_inter_x, depart.y());
|
||||||
points << QPointF(ligne_inter_x, arrivee.y());
|
points << QPointF(ligne_inter_x, arrivee.y());
|
||||||
} else if ((ori_depart == Terminal::Ouest || ori_depart == Terminal::Nord) && (ori_arrivee == Terminal::Ouest || ori_arrivee == Terminal::Nord)) {
|
} else if ((ori_depart == QET::West || ori_depart == QET::North) && (ori_arrivee == QET::West || ori_arrivee == QET::North)) {
|
||||||
points << QPointF(depart.x(), arrivee.y()); // cas « 2 »
|
points << QPointF(depart.x(), arrivee.y()); // cas « 2 »
|
||||||
} else {
|
} else {
|
||||||
points << QPointF(arrivee.x(), depart.y()); // cas « 1 »
|
points << QPointF(arrivee.x(), depart.y()); // cas « 1 »
|
||||||
@ -287,19 +287,19 @@ void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1,
|
|||||||
@param ext_size la taille de la prolongation
|
@param ext_size la taille de la prolongation
|
||||||
@return le point correspondant a la borne apres prolongation
|
@return le point correspondant a la borne apres prolongation
|
||||||
*/
|
*/
|
||||||
QPointF Conducer::extendTerminal(const QPointF &terminal, Terminal::Orientation terminal_orientation, qreal ext_size) {
|
QPointF Conducer::extendTerminal(const QPointF &terminal, QET::Orientation terminal_orientation, qreal ext_size) {
|
||||||
QPointF extended_terminal;
|
QPointF extended_terminal;
|
||||||
switch(terminal_orientation) {
|
switch(terminal_orientation) {
|
||||||
case Terminal::Nord:
|
case QET::North:
|
||||||
extended_terminal = QPointF(terminal.x(), terminal.y() - ext_size);
|
extended_terminal = QPointF(terminal.x(), terminal.y() - ext_size);
|
||||||
break;
|
break;
|
||||||
case Terminal::Est:
|
case QET::East:
|
||||||
extended_terminal = QPointF(terminal.x() + ext_size, terminal.y());
|
extended_terminal = QPointF(terminal.x() + ext_size, terminal.y());
|
||||||
break;
|
break;
|
||||||
case Terminal::Sud:
|
case QET::South:
|
||||||
extended_terminal = QPointF(terminal.x(), terminal.y() + ext_size);
|
extended_terminal = QPointF(terminal.x(), terminal.y() + ext_size);
|
||||||
break;
|
break;
|
||||||
case Terminal::Ouest:
|
case QET::West:
|
||||||
extended_terminal = QPointF(terminal.x() - ext_size, terminal.y());
|
extended_terminal = QPointF(terminal.x() - ext_size, terminal.y());
|
||||||
break;
|
break;
|
||||||
default: extended_terminal = terminal;
|
default: extended_terminal = terminal;
|
||||||
@ -356,36 +356,6 @@ void Conducer::paint(QPainter *qp, const QStyleOptionGraphicsItem */*qsogi*/, QW
|
|||||||
qp -> restore();
|
qp -> restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Indique si deux orientations de Borne sont sur le meme axe (Vertical / Horizontal).
|
|
||||||
@param a La premiere orientation de Borne
|
|
||||||
@param b La seconde orientation de Borne
|
|
||||||
@return Un booleen a true si les deux orientations de bornes sont sur le meme axe
|
|
||||||
*/
|
|
||||||
bool Conducer::surLeMemeAxe(Terminal::Orientation a, Terminal::Orientation b) {
|
|
||||||
if ((a == Terminal::Nord || a == Terminal::Sud) && (b == Terminal::Nord || b == Terminal::Sud)) return(true);
|
|
||||||
else if ((a == Terminal::Est || a == Terminal::Ouest) && (b == Terminal::Est || b == Terminal::Ouest)) return(true);
|
|
||||||
else return(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Indique si une orientation de borne est horizontale (Est / Ouest).
|
|
||||||
@param a L'orientation de borne
|
|
||||||
@return True si l'orientation de borne est horizontale, false sinon
|
|
||||||
*/
|
|
||||||
bool Conducer::estHorizontale(Terminal::Orientation a) {
|
|
||||||
return(a == Terminal::Est || a == Terminal::Ouest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Indique si une orientation de borne est verticale (Nord / Sud).
|
|
||||||
@param a L'orientation de borne
|
|
||||||
@return True si l'orientation de borne est verticale, false sinon
|
|
||||||
*/
|
|
||||||
bool Conducer::estVerticale(Terminal::Orientation a) {
|
|
||||||
return(a == Terminal::Nord || a == Terminal::Sud);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Methode de preparation a la destruction du conducteur ; le conducteur se detache de ses deux bornes
|
Methode de preparation a la destruction du conducteur ; le conducteur se detache de ses deux bornes
|
||||||
*/
|
*/
|
||||||
|
@ -71,17 +71,14 @@ class Conducer : public QGraphicsPathItem {
|
|||||||
private:
|
private:
|
||||||
void segmentsToPath();
|
void segmentsToPath();
|
||||||
void updatePoints();
|
void updatePoints();
|
||||||
void priv_calculeConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
void priv_calculeConducer(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
|
||||||
void priv_modifieConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
void priv_modifieConducer(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
|
||||||
int nbSegments() const;
|
int nbSegments() const;
|
||||||
QList<QPointF> segmentsToPoints() const;
|
QList<QPointF> segmentsToPoints() const;
|
||||||
void pointsToSegments(QList<QPointF>);
|
void pointsToSegments(QList<QPointF>);
|
||||||
bool hasClickedOn(QPointF, QPointF) const;
|
bool hasClickedOn(QPointF, QPointF) const;
|
||||||
void calculateTextItemPosition();
|
void calculateTextItemPosition();
|
||||||
static QPointF extendTerminal(const QPointF &, Terminal::Orientation, qreal = 12.0);
|
static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 12.0);
|
||||||
static bool surLeMemeAxe(Terminal::Orientation, Terminal::Orientation);
|
|
||||||
static bool estHorizontale(Terminal::Orientation a);
|
|
||||||
static bool estVerticale(Terminal::Orientation a);
|
|
||||||
static qreal conducer_bound(qreal tobound, qreal bound1, qreal bound2);
|
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 tobound, qreal bound, bool positive);
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "customelement.h"
|
#include "customelement.h"
|
||||||
#include "elementtextitem.h"
|
#include "elementtextitem.h"
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructeur de la classe ElementPerso. Permet d'instancier un element
|
Constructeur de la classe ElementPerso. Permet d'instancier un element
|
||||||
utilisable comme un element fixe a la difference que l'element perso lit
|
utilisable comme un element fixe a la difference que l'element perso lit
|
||||||
@ -63,10 +62,10 @@ CustomElement::CustomElement(QString &nom_fichier, QGraphicsItem *qgi, Diagram *
|
|||||||
// ces attributs doivent etre presents et valides
|
// ces attributs doivent etre presents et valides
|
||||||
int w, h, hot_x, hot_y;
|
int w, h, hot_x, hot_y;
|
||||||
if (
|
if (
|
||||||
!attributeIsAnInteger(racine, QString("width"), &w) ||\
|
!QET::attributeIsAnInteger(racine, QString("width"), &w) ||\
|
||||||
!attributeIsAnInteger(racine, QString("height"), &h) ||\
|
!QET::attributeIsAnInteger(racine, QString("height"), &h) ||\
|
||||||
!attributeIsAnInteger(racine, QString("hotspot_x"), &hot_x) ||\
|
!QET::attributeIsAnInteger(racine, QString("hotspot_x"), &hot_x) ||\
|
||||||
!attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) ||\
|
!QET::attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) ||\
|
||||||
!validOrientationAttribute(racine)
|
!validOrientationAttribute(racine)
|
||||||
) {
|
) {
|
||||||
if (etat != NULL) *etat = 5;
|
if (etat != NULL) *etat = 5;
|
||||||
@ -78,6 +77,7 @@ CustomElement::CustomElement(QString &nom_fichier, QGraphicsItem *qgi, Diagram *
|
|||||||
setSize(w, h);
|
setSize(w, h);
|
||||||
setHotspot(QPoint(hot_x, hot_y));
|
setHotspot(QPoint(hot_x, hot_y));
|
||||||
setConnexionsInternesAcceptees(racine.attribute("ci") == "true");
|
setConnexionsInternesAcceptees(racine.attribute("ci") == "true");
|
||||||
|
|
||||||
// la definition est supposee avoir des enfants
|
// la definition est supposee avoir des enfants
|
||||||
if (racine.firstChild().isNull()) {
|
if (racine.firstChild().isNull()) {
|
||||||
if (etat != NULL) *etat = 6;
|
if (etat != NULL) *etat = 6;
|
||||||
@ -194,12 +194,20 @@ bool CustomElement::parseElement(QDomElement &e, QPainter &qp, Diagram *s) {
|
|||||||
@return true si l'analyse reussit, false sinon
|
@return true si l'analyse reussit, false sinon
|
||||||
*/
|
*/
|
||||||
bool CustomElement::parseLine(QDomElement &e, QPainter &qp) {
|
bool CustomElement::parseLine(QDomElement &e, QPainter &qp) {
|
||||||
|
//qDebug() << "parseLine sur " << (void *)(&dessin);
|
||||||
|
// qDebug() << names.name() << (void *)(&dessin);
|
||||||
|
// qp.end();
|
||||||
|
// PartLine t;
|
||||||
|
// t.fromXml(e);
|
||||||
|
// t.renderToCustomElement(*this);
|
||||||
|
// qp.begin(&dessin);
|
||||||
|
//return(true);
|
||||||
// verifie la presence et la validite des attributs obligatoires
|
// verifie la presence et la validite des attributs obligatoires
|
||||||
double x1, y1, x2, y2;
|
double x1, y1, x2, y2;
|
||||||
if (!attributeIsAReal(e, QString("x1"), &x1)) return(false);
|
if (!QET::attributeIsAReal(e, QString("x1"), &x1)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("y1"), &y1)) return(false);
|
if (!QET::attributeIsAReal(e, QString("y1"), &y1)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("x2"), &x2)) return(false);
|
if (!QET::attributeIsAReal(e, QString("x2"), &x2)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("y2"), &y2)) return(false);
|
if (!QET::attributeIsAReal(e, QString("y2"), &y2)) return(false);
|
||||||
qp.save();
|
qp.save();
|
||||||
setPainterStyle(e, qp);
|
setPainterStyle(e, qp);
|
||||||
qp.drawLine(QLineF(x1, y1, x2, y2));
|
qp.drawLine(QLineF(x1, y1, x2, y2));
|
||||||
@ -223,9 +231,9 @@ bool CustomElement::parseLine(QDomElement &e, QPainter &qp) {
|
|||||||
bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
|
bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
|
||||||
// verifie la presence des attributs obligatoires
|
// verifie la presence des attributs obligatoires
|
||||||
double cercle_x, cercle_y, cercle_r;
|
double cercle_x, cercle_y, cercle_r;
|
||||||
if (!attributeIsAReal(e, QString("x"), &cercle_x)) return(false);
|
if (!QET::attributeIsAReal(e, QString("x"), &cercle_x)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("y"), &cercle_y)) return(false);
|
if (!QET::attributeIsAReal(e, QString("y"), &cercle_y)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
|
if (!QET::attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
|
||||||
qp.save();
|
qp.save();
|
||||||
setPainterStyle(e, qp);
|
setPainterStyle(e, qp);
|
||||||
qp.drawEllipse(QRectF(cercle_x, cercle_y, cercle_r, cercle_r));
|
qp.drawEllipse(QRectF(cercle_x, cercle_y, cercle_r, cercle_r));
|
||||||
@ -250,10 +258,10 @@ bool CustomElement::parseCircle(QDomElement &e, QPainter &qp) {
|
|||||||
bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
|
bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
|
||||||
// verifie la presence des attributs obligatoires
|
// verifie la presence des attributs obligatoires
|
||||||
double ellipse_x, ellipse_y, ellipse_l, ellipse_h;
|
double ellipse_x, ellipse_y, ellipse_l, ellipse_h;
|
||||||
if (!attributeIsAReal(e, QString("x"), &ellipse_x)) return(false);
|
if (!QET::attributeIsAReal(e, QString("x"), &ellipse_x)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("y"), &ellipse_y)) return(false);
|
if (!QET::attributeIsAReal(e, QString("y"), &ellipse_y)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("width"), &ellipse_l)) return(false);
|
if (!QET::attributeIsAReal(e, QString("width"), &ellipse_l)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("height"), &ellipse_h)) return(false);
|
if (!QET::attributeIsAReal(e, QString("height"), &ellipse_h)) return(false);
|
||||||
qp.save();
|
qp.save();
|
||||||
setPainterStyle(e, qp);
|
setPainterStyle(e, qp);
|
||||||
qp.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
|
qp.drawEllipse(QRectF(ellipse_x, ellipse_y, ellipse_l, ellipse_h));
|
||||||
@ -278,12 +286,12 @@ bool CustomElement::parseEllipse(QDomElement &e, QPainter &qp) {
|
|||||||
bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
|
bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
|
||||||
// verifie la presence des attributs obligatoires
|
// verifie la presence des attributs obligatoires
|
||||||
double arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
|
double arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
|
||||||
if (!attributeIsAReal(e, QString("x"), &arc_x)) return(false);
|
if (!QET::attributeIsAReal(e, QString("x"), &arc_x)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("y"), &arc_y)) return(false);
|
if (!QET::attributeIsAReal(e, QString("y"), &arc_y)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("width"), &arc_l)) return(false);
|
if (!QET::attributeIsAReal(e, QString("width"), &arc_l)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("height"), &arc_h)) return(false);
|
if (!QET::attributeIsAReal(e, QString("height"), &arc_h)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("start"), &arc_s)) return(false);
|
if (!QET::attributeIsAReal(e, QString("start"), &arc_s)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("angle"), &arc_a)) return(false);
|
if (!QET::attributeIsAReal(e, QString("angle"), &arc_a)) return(false);
|
||||||
|
|
||||||
qp.save();
|
qp.save();
|
||||||
setPainterStyle(e, qp);
|
setPainterStyle(e, qp);
|
||||||
@ -306,7 +314,7 @@ bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
|
|||||||
bool CustomElement::parsePolygon(QDomElement &e, QPainter &qp) {
|
bool CustomElement::parsePolygon(QDomElement &e, QPainter &qp) {
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while(true) {
|
while(true) {
|
||||||
if (attributeIsAReal(e, QString("x%1").arg(i)) && attributeIsAReal(e, QString("y%1").arg(i))) ++ i;
|
if (QET::attributeIsAReal(e, QString("x%1").arg(i)) && QET::attributeIsAReal(e, QString("y%1").arg(i))) ++ i;
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
if (i < 3) return(false);
|
if (i < 3) return(false);
|
||||||
@ -338,9 +346,9 @@ bool CustomElement::parseText(QDomElement &e, QPainter &qp) {
|
|||||||
qreal pos_x, pos_y;
|
qreal pos_x, pos_y;
|
||||||
int size;
|
int size;
|
||||||
if (
|
if (
|
||||||
!attributeIsAReal(e, "x", &pos_x) ||\
|
!QET::attributeIsAReal(e, "x", &pos_x) ||\
|
||||||
!attributeIsAReal(e, "y", &pos_y) ||\
|
!QET::attributeIsAReal(e, "y", &pos_y) ||\
|
||||||
!attributeIsAnInteger(e, "size", &size) ||\
|
!QET::attributeIsAnInteger(e, "size", &size) ||\
|
||||||
!e.hasAttribute("text")
|
!e.hasAttribute("text")
|
||||||
) return(false);
|
) return(false);
|
||||||
|
|
||||||
@ -368,9 +376,9 @@ bool CustomElement::parseInput(QDomElement &e, Diagram *s) {
|
|||||||
qreal pos_x, pos_y;
|
qreal pos_x, pos_y;
|
||||||
int size;
|
int size;
|
||||||
if (
|
if (
|
||||||
!attributeIsAReal(e, "x", &pos_x) ||\
|
!QET::attributeIsAReal(e, "x", &pos_x) ||\
|
||||||
!attributeIsAReal(e, "y", &pos_y) ||\
|
!QET::attributeIsAReal(e, "y", &pos_y) ||\
|
||||||
!attributeIsAnInteger(e, "size", &size)
|
!QET::attributeIsAnInteger(e, "size", &size)
|
||||||
) return(false);
|
) return(false);
|
||||||
|
|
||||||
ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this, s);
|
ElementTextItem *eti = new ElementTextItem(e.attribute("text"), this, s);
|
||||||
@ -394,14 +402,14 @@ bool CustomElement::parseInput(QDomElement &e, Diagram *s) {
|
|||||||
bool CustomElement::parseTerminal(QDomElement &e, Diagram *s) {
|
bool CustomElement::parseTerminal(QDomElement &e, Diagram *s) {
|
||||||
// verifie la presence et la validite des attributs obligatoires
|
// verifie la presence et la validite des attributs obligatoires
|
||||||
double terminalx, terminaly;
|
double terminalx, terminaly;
|
||||||
Terminal::Orientation terminalo;
|
QET::Orientation terminalo;
|
||||||
if (!attributeIsAReal(e, QString("x"), &terminalx)) return(false);
|
if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(false);
|
||||||
if (!attributeIsAReal(e, QString("y"), &terminaly)) return(false);
|
if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(false);
|
||||||
if (!e.hasAttribute("orientation")) return(false);
|
if (!e.hasAttribute("orientation")) return(false);
|
||||||
if (e.attribute("orientation") == "n") terminalo = Terminal::Nord;
|
if (e.attribute("orientation") == "n") terminalo = QET::North;
|
||||||
else if (e.attribute("orientation") == "s") terminalo = Terminal::Sud;
|
else if (e.attribute("orientation") == "s") terminalo = QET::South;
|
||||||
else if (e.attribute("orientation") == "e") terminalo = Terminal::Est;
|
else if (e.attribute("orientation") == "e") terminalo = QET::East;
|
||||||
else if (e.attribute("orientation") == "w") terminalo = Terminal::Ouest;
|
else if (e.attribute("orientation") == "w") terminalo = QET::West;
|
||||||
else return(false);
|
else return(false);
|
||||||
new Terminal(terminalx, terminaly, terminalo, this, s);
|
new Terminal(terminalx, terminaly, terminalo, this, s);
|
||||||
++ nb_terminals;
|
++ nb_terminals;
|
||||||
@ -419,44 +427,6 @@ void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool aa) {
|
|||||||
qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
|
qp.setRenderHint(QPainter::SmoothPixmapTransform, aa);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de savoir si l'attribut nom_attribut d'un element XML e est bien un
|
|
||||||
entier. Si oui, sa valeur est copiee dans entier.
|
|
||||||
@param e Element XML
|
|
||||||
@param nom_attribut Nom de l'attribut a analyser
|
|
||||||
@param entier Pointeur facultatif vers un entier
|
|
||||||
@return true si l'attribut est bien un entier, false sinon
|
|
||||||
*/
|
|
||||||
bool CustomElement::attributeIsAnInteger(QDomElement &e, QString nom_attribut, int *entier) {
|
|
||||||
// verifie la presence de l'attribut
|
|
||||||
if (!e.hasAttribute(nom_attribut)) return(false);
|
|
||||||
// verifie la validite de l'attribut
|
|
||||||
bool ok;
|
|
||||||
int tmp = e.attribute(nom_attribut).toInt(&ok);
|
|
||||||
if (!ok) return(false);
|
|
||||||
if (entier != NULL) *entier = tmp;
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de savoir si l'attribut nom_attribut d'un element XML e est bien un
|
|
||||||
reel. Si oui, sa valeur est copiee dans reel.
|
|
||||||
@param e Element XML
|
|
||||||
@param nom_attribut Nom de l'attribut a analyser
|
|
||||||
@param reel Pointeur facultatif vers un double
|
|
||||||
@return true si l'attribut est bien un reel, false sinon
|
|
||||||
*/
|
|
||||||
bool CustomElement::attributeIsAReal(QDomElement &e, QString nom_attribut, double *reel) {
|
|
||||||
// verifie la presence de l'attribut
|
|
||||||
if (!e.hasAttribute(nom_attribut)) return(false);
|
|
||||||
// verifie la validite de l'attribut
|
|
||||||
bool ok;
|
|
||||||
qreal tmp = e.attribute(nom_attribut).toDouble(&ok);
|
|
||||||
if (!ok) return(false);
|
|
||||||
if (reel != NULL) *reel = tmp;
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Verifie si l'attribut "orientation" de l'element XML e correspond bien a la
|
Verifie si l'attribut "orientation" de l'element XML e correspond bien a la
|
||||||
syntaxe decrivant les orientations possibles pour un element.
|
syntaxe decrivant les orientations possibles pour un element.
|
||||||
@ -477,30 +447,7 @@ bool CustomElement::attributeIsAReal(QDomElement &e, QString nom_attribut, doubl
|
|||||||
@return true si l'attribut "orientation" est valide, false sinon
|
@return true si l'attribut "orientation" est valide, false sinon
|
||||||
*/
|
*/
|
||||||
bool CustomElement::validOrientationAttribute(QDomElement &e) {
|
bool CustomElement::validOrientationAttribute(QDomElement &e) {
|
||||||
// verifie la presence de l'attribut orientation
|
return(ori.fromString(e.attribute("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 = (Terminal::Orientation)d_pos;
|
|
||||||
ori = ori_d;
|
|
||||||
return(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
#include "fixedelement.h"
|
#include "fixedelement.h"
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include "nameslist.h"
|
#include "nameslist.h"
|
||||||
|
class CustomElementPart;
|
||||||
|
// #include "customelementpart.h"
|
||||||
|
// #include "cep_line.h"
|
||||||
/**
|
/**
|
||||||
Cette classe represente un element electrique. Elle est utilisable
|
Cette classe represente un element electrique. Elle est utilisable
|
||||||
comme un element fixe. La difference est que l'element perso lit
|
comme un element fixe. La difference est que l'element perso lit
|
||||||
@ -15,6 +18,8 @@ class CustomElement : public FixedElement {
|
|||||||
CustomElement(QString &, QGraphicsItem * = 0, Diagram * = 0, int * = NULL);
|
CustomElement(QString &, QGraphicsItem * = 0, Diagram * = 0, int * = NULL);
|
||||||
virtual ~CustomElement();
|
virtual ~CustomElement();
|
||||||
|
|
||||||
|
friend class CustomElementPart;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CustomElement(const CustomElement &);
|
CustomElement(const CustomElement &);
|
||||||
|
|
||||||
@ -47,8 +52,6 @@ class CustomElement : public FixedElement {
|
|||||||
bool parseInput(QDomElement &, Diagram *);
|
bool parseInput(QDomElement &, Diagram *);
|
||||||
bool parseTerminal(QDomElement &, Diagram *);
|
bool parseTerminal(QDomElement &, Diagram *);
|
||||||
void setQPainterAntiAliasing(QPainter &, bool);
|
void setQPainterAntiAliasing(QPainter &, bool);
|
||||||
bool attributeIsAnInteger(QDomElement &, QString, int * = NULL);
|
|
||||||
bool attributeIsAReal(QDomElement &, QString, double * = NULL);
|
|
||||||
bool validOrientationAttribute(QDomElement &);
|
bool validOrientationAttribute(QDomElement &);
|
||||||
void setPainterStyle(QDomElement &, QPainter &);
|
void setPainterStyle(QDomElement &, QPainter &);
|
||||||
};
|
};
|
||||||
|
@ -153,7 +153,7 @@ void DiagramView::pivoter() {
|
|||||||
if (scene -> selectedItems().isEmpty()) return;
|
if (scene -> selectedItems().isEmpty()) return;
|
||||||
foreach (QGraphicsItem *item, scene -> selectedItems()) {
|
foreach (QGraphicsItem *item, scene -> selectedItems()) {
|
||||||
if (Element *elt = qgraphicsitem_cast<Element *>(item)) {
|
if (Element *elt = qgraphicsitem_cast<Element *>(item)) {
|
||||||
elt -> setOrientation(elt -> nextAcceptableOrientation());
|
elt -> setOrientation(elt -> orientation().next());
|
||||||
elt -> update();
|
elt -> update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
56
editor/circleeditor.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#include "circleeditor.h"
|
||||||
|
#include "partcircle.h"
|
||||||
|
|
||||||
|
CircleEditor::CircleEditor(PartCircle *circle, QWidget *parent) : QWidget(parent) {
|
||||||
|
|
||||||
|
part = circle;
|
||||||
|
|
||||||
|
x = new QLineEdit();
|
||||||
|
y = new QLineEdit();
|
||||||
|
r = new QLineEdit();
|
||||||
|
|
||||||
|
// QDoubleValidator *format = new QDoubleValidator(-1000.0, -1000.0, 4, this);
|
||||||
|
// x -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
|
||||||
|
// y -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
|
||||||
|
// h -> setValidator(new QDoubleValidator(0.0, 1000.0, 4, this));
|
||||||
|
|
||||||
|
|
||||||
|
QGridLayout *grid = new QGridLayout(this);
|
||||||
|
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
|
||||||
|
grid -> addWidget(new QLabel("x"), 1, 0);
|
||||||
|
grid -> addWidget(x, 1, 1);
|
||||||
|
grid -> addWidget(new QLabel("y"), 1, 2);
|
||||||
|
grid -> addWidget(y, 1, 3);
|
||||||
|
grid -> addWidget(new QLabel(tr("Diam\350tre : ")), 2, 0);
|
||||||
|
grid -> addWidget(r, 2, 1);
|
||||||
|
|
||||||
|
updateForm();
|
||||||
|
|
||||||
|
connect(x, SIGNAL(editingFinished()), this, SLOT(updateCircle()));
|
||||||
|
connect(y, SIGNAL(editingFinished()), this, SLOT(updateCircle()));
|
||||||
|
connect(r, SIGNAL(editingFinished()), this, SLOT(updateCircle()));
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleEditor::~CircleEditor() {
|
||||||
|
qDebug() << "~CircleEditor()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircleEditor::updateCircle() {
|
||||||
|
qreal _x = x -> text().toDouble();
|
||||||
|
qreal _y = y -> text().toDouble();
|
||||||
|
qreal _d = r -> text().toDouble();
|
||||||
|
part -> setRect(
|
||||||
|
QRectF(
|
||||||
|
part -> mapFromScene(QPointF(_x - _d / 2.0, _y - _d / 2.0)),
|
||||||
|
QSizeF(_d, _d)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CircleEditor::updateForm() {
|
||||||
|
qreal _d = part -> rect().width();
|
||||||
|
QPointF top_left(part -> sceneTopLeft());
|
||||||
|
x -> setText(QString("%1").arg(top_left.x() + _d / 2.0));
|
||||||
|
y -> setText(QString("%1").arg(top_left.y() + _d / 2.0));
|
||||||
|
r -> setText(QString("%1").arg(_d));
|
||||||
|
}
|
29
editor/circleeditor.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef CIRCLE_EDITOR_H
|
||||||
|
#define CIRCLE_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class PartCircle;
|
||||||
|
/**
|
||||||
|
Cette classe represente un editeur de cercle.
|
||||||
|
Elle permet d'editer a travers une interface graphique les
|
||||||
|
proprietes d'une cercle composant le dessin d'un element.
|
||||||
|
*/
|
||||||
|
class CircleEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
// Constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
CircleEditor(PartCircle *, QWidget * = 0);
|
||||||
|
virtual ~CircleEditor();
|
||||||
|
private:
|
||||||
|
CircleEditor(const CircleEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
PartCircle *part;
|
||||||
|
QLineEdit *x, *y, *r;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public slots:
|
||||||
|
void updateCircle();
|
||||||
|
void updateForm();
|
||||||
|
};
|
||||||
|
#endif
|
447
editor/customelementeditor.cpp
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
#include "customelementeditor.h"
|
||||||
|
#include "editorscene.h"
|
||||||
|
#include "customelementpart.h"
|
||||||
|
#include "newelementwizard.h"
|
||||||
|
#include "qetapp.h"
|
||||||
|
|
||||||
|
CustomElementEditor::CustomElementEditor(QWidget *parent) :
|
||||||
|
QMainWindow(parent),
|
||||||
|
read_only(false),
|
||||||
|
min_title(tr("QElectroTech - \311diteur d'\351l\351ment")),
|
||||||
|
_filename(QString())
|
||||||
|
{
|
||||||
|
setMinimumWidth(700);
|
||||||
|
setMinimumHeight(450);
|
||||||
|
setWindowTitle(min_title);
|
||||||
|
setWindowIcon(QIcon(":/ico/qet.png"));
|
||||||
|
|
||||||
|
setupInterface();
|
||||||
|
setupActions();
|
||||||
|
setupMenus();
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomElementEditor::~CustomElementEditor() {
|
||||||
|
qDebug() << "~CustomElementEditor()";
|
||||||
|
// recupere le layout
|
||||||
|
// QLayout *layout = tools_dock -> widget() -> layout();
|
||||||
|
//
|
||||||
|
// // enleve les widgets deja presents
|
||||||
|
// QLayoutItem *qli;
|
||||||
|
// while ((qli = layout -> takeAt(0)) != 0) {
|
||||||
|
// if (qli -> widget()) {
|
||||||
|
// layout -> removeWidget(qli -> widget());
|
||||||
|
// qli -> widget() -> setParent(0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::setupActions() {
|
||||||
|
new_element = new QAction(QIcon(":/ico/new.png"), tr("&Nouveau"), this);
|
||||||
|
open = new QAction(QIcon(":/ico/open.png"), tr("&Ouvrir"), this);
|
||||||
|
save = new QAction(QIcon(":/ico/save.png"), tr("&Enregistrer"), this);
|
||||||
|
save_as = new QAction(QIcon(":/ico/saveas.png"), tr("Enregistrer sous"), this);
|
||||||
|
quit = new QAction(QIcon(":/ico/exit.png"), tr("&Quitter"), this);
|
||||||
|
selectall = new QAction( tr("Tout s\351lectionner"), this);
|
||||||
|
deselectall = new QAction( tr("D\351s\351lectionner tout"), this);
|
||||||
|
inv_select = new QAction( tr("Inverser la s\351lection"), this);
|
||||||
|
edit_delete = new QAction(QIcon(":/ico/delete.png"), tr("&Supprimer"), this);
|
||||||
|
edit_size = new QAction( tr("Modifier la taille"), this);
|
||||||
|
edit_hotspot = new QAction( tr("Modifier le point de saisie"), this);
|
||||||
|
edit_names = new QAction( tr("\311diter les noms"), this);
|
||||||
|
edit_ori = new QAction(QIcon(":/ico/orientations.png"), tr("\311diter les orientations"), this);
|
||||||
|
move = new QAction(QIcon(":/ico/select.png"), tr("D\351placer un objet"), this);
|
||||||
|
add_line = new QAction(QIcon(":/ico/line.png"), tr("Ajouter une ligne"), this);
|
||||||
|
add_ellipse = new QAction(QIcon(":/ico/ellipse.png"), tr("Ajouter une ellipse"), this);
|
||||||
|
add_circle = new QAction(QIcon(":/ico/circle.png"), tr("Ajouter un cercle"), this);
|
||||||
|
add_polygon = new QAction(QIcon(":/ico/polygon.png"), tr("Ajouter un polygone"), this);
|
||||||
|
add_text = new QAction(QIcon(":/ico/text.png"), tr("Ajouter du texte"), this);
|
||||||
|
add_arc = new QAction(QIcon(":/ico/arc.png"), tr("Ajouter un arc de cercle"), this);
|
||||||
|
add_terminal = new QAction(QIcon(":/ico/terminal.png"), tr("Ajouter une borne"), this);
|
||||||
|
add_textfield = new QAction(QIcon(":/ico/textfield.png"), tr("Ajouter un champ de texte"), this);
|
||||||
|
|
||||||
|
edit_delete -> setEnabled(false);
|
||||||
|
edit_size -> setEnabled(false);
|
||||||
|
edit_hotspot -> setEnabled(false);
|
||||||
|
|
||||||
|
selectall -> setShortcut(QKeySequence::SelectAll);
|
||||||
|
deselectall -> setShortcut(QKeySequence(tr("Ctrl+Shift+A")));
|
||||||
|
inv_select -> setShortcut(QKeySequence(tr("Ctrl+I")));
|
||||||
|
edit_delete -> setShortcut(QKeySequence(tr("Ctrl+Suppr")));
|
||||||
|
|
||||||
|
connect(new_element, SIGNAL(triggered()), this, SLOT(slot_new()));
|
||||||
|
connect(open, SIGNAL(triggered()), this, SLOT(slot_open()));
|
||||||
|
connect(save, SIGNAL(triggered()), this, SLOT(slot_save()));
|
||||||
|
connect(save_as, SIGNAL(triggered()), this, SLOT(slot_saveAs()));
|
||||||
|
connect(quit, SIGNAL(triggered()), this, SLOT(slot_quit()));
|
||||||
|
connect(selectall, SIGNAL(triggered()), ce_scene, SLOT(slot_selectAll()));
|
||||||
|
connect(deselectall, SIGNAL(triggered()), ce_scene, SLOT(slot_deselectAll()));
|
||||||
|
connect(inv_select, SIGNAL(triggered()), ce_scene, SLOT(slot_invertSelection()));
|
||||||
|
connect(edit_delete, SIGNAL(triggered()), ce_scene, SLOT(slot_delete()));
|
||||||
|
connect(edit_size, SIGNAL(triggered()), ce_scene, SLOT(slot_editSize()));
|
||||||
|
connect(edit_hotspot, SIGNAL(triggered()), ce_scene, SLOT(slot_editHotSpot()));
|
||||||
|
connect(edit_names, SIGNAL(triggered()), ce_scene, SLOT(slot_editNames()));
|
||||||
|
connect(edit_ori, SIGNAL(triggered()), ce_scene, SLOT(slot_editOrientations()));
|
||||||
|
connect(move, SIGNAL(triggered()), ce_scene, SLOT(slot_move()));
|
||||||
|
connect(add_line, SIGNAL(triggered()), ce_scene, SLOT(slot_addLine()));
|
||||||
|
connect(add_ellipse, SIGNAL(triggered()), ce_scene, SLOT(slot_addEllipse()));
|
||||||
|
connect(add_circle, SIGNAL(triggered()), ce_scene, SLOT(slot_addCircle()));
|
||||||
|
connect(add_polygon, SIGNAL(triggered()), ce_scene, SLOT(slot_addPolygon()));
|
||||||
|
connect(add_text, SIGNAL(triggered()), ce_scene, SLOT(slot_addText()));
|
||||||
|
connect(add_arc, SIGNAL(triggered()), ce_scene, SLOT(slot_addArc()));
|
||||||
|
connect(add_terminal, SIGNAL(triggered()), ce_scene, SLOT(slot_addTerminal()));
|
||||||
|
connect(add_textfield, SIGNAL(triggered()), ce_scene, SLOT(slot_addTextField()));
|
||||||
|
|
||||||
|
connect(move, SIGNAL(triggered()), this, SLOT(slot_setRubberBandToView()));
|
||||||
|
connect(add_line, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_ellipse, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_circle, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_polygon, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_text, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_arc, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_terminal, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
connect(add_textfield, SIGNAL(triggered()), this, SLOT(slot_setNoDragToView()));
|
||||||
|
|
||||||
|
connect(ce_scene, SIGNAL(needNormalMode()), this, SLOT(slot_setNormalMode()));
|
||||||
|
|
||||||
|
move -> setCheckable(true);
|
||||||
|
add_line -> setCheckable(true);
|
||||||
|
add_ellipse -> setCheckable(true);
|
||||||
|
add_circle -> setCheckable(true);
|
||||||
|
add_polygon -> setCheckable(true);
|
||||||
|
add_text -> setCheckable(true);
|
||||||
|
add_arc -> setCheckable(true);
|
||||||
|
add_terminal -> setCheckable(true);
|
||||||
|
add_textfield -> setCheckable(true);
|
||||||
|
|
||||||
|
parts = new QActionGroup(this);
|
||||||
|
parts -> addAction(move);
|
||||||
|
parts -> addAction(add_line);
|
||||||
|
parts -> addAction(add_ellipse);
|
||||||
|
parts -> addAction(add_circle);
|
||||||
|
parts -> addAction(add_polygon);
|
||||||
|
parts -> addAction(add_text);
|
||||||
|
parts -> addAction(add_arc);
|
||||||
|
parts -> addAction(add_textfield);
|
||||||
|
parts -> addAction(add_terminal);
|
||||||
|
parts -> setExclusive(true);
|
||||||
|
|
||||||
|
parts_toolbar = new QToolBar(tr("Parties"), this);
|
||||||
|
foreach (QAction *action, parts -> actions()) parts_toolbar -> addAction(action);
|
||||||
|
move -> setChecked(true);
|
||||||
|
parts_toolbar -> setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
|
||||||
|
|
||||||
|
QAction *xml_preview = new QAction(QIcon(":/ico/info.png"), tr("XML"), this);
|
||||||
|
connect(xml_preview, SIGNAL(triggered()), this, SLOT(xmlPreview()));
|
||||||
|
parts_toolbar -> addAction(xml_preview);
|
||||||
|
|
||||||
|
addToolBar(Qt::LeftToolBarArea, parts_toolbar);
|
||||||
|
|
||||||
|
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateInformations()));
|
||||||
|
connect(ce_scene, SIGNAL(selectionChanged()), this, SLOT(slot_updateMenus()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::setupMenus() {
|
||||||
|
file_menu = new QMenu(tr("Fichier"));
|
||||||
|
edit_menu = new QMenu(tr("\311dition"));
|
||||||
|
display_menu = new QMenu(tr("Affichage"));
|
||||||
|
tools_menu = new QMenu(tr("Outils"));
|
||||||
|
help_menu = new QMenu(tr("Aide"));
|
||||||
|
|
||||||
|
file_menu -> setTearOffEnabled(true);
|
||||||
|
edit_menu -> setTearOffEnabled(true);
|
||||||
|
display_menu -> setTearOffEnabled(true);
|
||||||
|
tools_menu -> setTearOffEnabled(true);
|
||||||
|
help_menu -> setTearOffEnabled(true);
|
||||||
|
|
||||||
|
file_menu -> addAction(new_element);
|
||||||
|
file_menu -> addAction(open);
|
||||||
|
file_menu -> addAction(save);
|
||||||
|
file_menu -> addAction(save_as);
|
||||||
|
file_menu -> addSeparator();
|
||||||
|
file_menu -> addAction(quit);
|
||||||
|
|
||||||
|
edit_menu -> addAction(selectall);
|
||||||
|
edit_menu -> addAction(deselectall);
|
||||||
|
edit_menu -> addAction(inv_select);
|
||||||
|
edit_menu -> addSeparator();
|
||||||
|
edit_menu -> addAction(edit_delete);
|
||||||
|
edit_menu -> addSeparator();
|
||||||
|
edit_menu -> addAction(edit_names);
|
||||||
|
edit_menu -> addAction(edit_size);
|
||||||
|
edit_menu -> addAction(edit_hotspot);
|
||||||
|
edit_menu -> addAction(edit_ori);
|
||||||
|
|
||||||
|
menuBar() -> addMenu(file_menu);
|
||||||
|
menuBar() -> addMenu(edit_menu);
|
||||||
|
menuBar() -> addMenu(display_menu);
|
||||||
|
menuBar() -> addMenu(tools_menu);
|
||||||
|
menuBar() -> addMenu(help_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_updateMenus() {
|
||||||
|
edit_delete -> setEnabled(!ce_scene -> selectedItems().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::setupInterface() {
|
||||||
|
// editeur
|
||||||
|
ce_scene = new EditorScene(this);
|
||||||
|
ce_scene -> slot_move();
|
||||||
|
ce_view = new QGraphicsView(ce_scene, this);
|
||||||
|
ce_view -> setInteractive(true);
|
||||||
|
ce_view -> setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||||
|
//ce_view -> setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
|
||||||
|
ce_view -> setResizeAnchor(QGraphicsView::AnchorUnderMouse);
|
||||||
|
//ce_view -> setSceneRect(QRectF(0.0, 0.0, 50.0, 200.0));
|
||||||
|
ce_view -> scale(4.0, 4.0);
|
||||||
|
slot_setRubberBandToView();
|
||||||
|
setCentralWidget(ce_view);
|
||||||
|
|
||||||
|
// widget par defaut dans le QDockWidget
|
||||||
|
default_informations = new QLabel();
|
||||||
|
|
||||||
|
// panel sur le cote
|
||||||
|
tools_dock = new QDockWidget(tr("Informations"), this);
|
||||||
|
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||||
|
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||||
|
tools_dock -> setMinimumWidth(285);
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, tools_dock);
|
||||||
|
QWidget *info_widget = new QWidget();
|
||||||
|
info_widget -> setLayout(new QVBoxLayout(info_widget));
|
||||||
|
tools_dock -> setWidget(info_widget);
|
||||||
|
slot_updateInformations();
|
||||||
|
|
||||||
|
// barre d'etat
|
||||||
|
statusBar() -> showMessage(tr("\311diteur d'\351l\351ments"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_setRubberBandToView() {
|
||||||
|
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_setNoDragToView() {
|
||||||
|
ce_view -> setDragMode(QGraphicsView::NoDrag);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_setNormalMode() {
|
||||||
|
if (!move -> isChecked()) move -> setChecked(true);
|
||||||
|
ce_view -> setDragMode(QGraphicsView::RubberBandDrag);
|
||||||
|
ce_scene -> slot_move();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_updateInformations() {
|
||||||
|
QList<QGraphicsItem *> selected_qgis = ce_scene -> selectedItems();
|
||||||
|
QList<CustomElementPart *> selected_parts;
|
||||||
|
foreach(QGraphicsItem *qgi, selected_qgis) {
|
||||||
|
if (CustomElementPart *cep = dynamic_cast<CustomElementPart *>(qgi)) {
|
||||||
|
selected_parts.append(cep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recupere le layout
|
||||||
|
QLayout *layout = tools_dock -> widget() -> layout();
|
||||||
|
|
||||||
|
// enleve les widgets deja presents
|
||||||
|
QLayoutItem *qli;
|
||||||
|
while ((qli = layout -> takeAt(0)) != 0) {
|
||||||
|
if (qli -> widget()) {
|
||||||
|
layout -> removeWidget(qli -> widget());
|
||||||
|
qli -> widget() -> setParent(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (selected_parts.size() == 1) {
|
||||||
|
// recupere le premier CustomElementPart et en ajoute le widget d'edition
|
||||||
|
layout -> addWidget(selected_parts.first() -> elementInformations());
|
||||||
|
} else {
|
||||||
|
default_informations -> setText(
|
||||||
|
selected_parts.size() ?
|
||||||
|
QString("%1").arg(selected_parts.size()) + tr(" parties s\351lectionn\351es.") :
|
||||||
|
tr("Aucune partie s\351lectionn\351e.")
|
||||||
|
);
|
||||||
|
layout -> addWidget(default_informations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::xmlPreview() {
|
||||||
|
QMessageBox::information(
|
||||||
|
this,
|
||||||
|
"Export XML",
|
||||||
|
ce_scene -> toXml().toString(4)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::fromFile(const QString &filepath) {
|
||||||
|
bool state = true;
|
||||||
|
QString error_message;
|
||||||
|
|
||||||
|
// le fichier doit exister
|
||||||
|
QFileInfo infos_file(filepath);
|
||||||
|
if (!infos_file.exists() || !infos_file.isFile()) {
|
||||||
|
state = false;
|
||||||
|
error_message = tr("Le fichier ") + filepath + tr(" n'existe pas.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// le fichier doit etre lisible
|
||||||
|
QFile file(filepath);
|
||||||
|
if (state) {
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
state = false;
|
||||||
|
error_message = tr("Impossible d'ouvrir le fichier ") + filepath + ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// le fichier doit etre un document XML
|
||||||
|
QDomDocument document_xml;
|
||||||
|
if (state) {
|
||||||
|
if (!document_xml.setContent(&file)) {
|
||||||
|
state = false;
|
||||||
|
error_message = tr("Ce fichier n'est pas un document XML valide");
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state) {
|
||||||
|
QMessageBox::critical(this, tr("Erreur"), error_message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// chargement de l'element
|
||||||
|
ce_scene -> fromXml(document_xml);
|
||||||
|
|
||||||
|
// gestion de la lecture seule
|
||||||
|
if (!infos_file.isWritable()) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this,
|
||||||
|
tr("\311dition en lecture seule"),
|
||||||
|
tr("Vous n'avez pas les privil\350ges n\351cessaires pour modifier cet \351lement. Il sera donc ouvert en lecture seule.")
|
||||||
|
);
|
||||||
|
setReadOnly(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// memorise le fichier
|
||||||
|
_filename = filepath;
|
||||||
|
|
||||||
|
// modifie le titre de la fenetre
|
||||||
|
QString new_title = min_title + " - " + ce_scene -> names().name();
|
||||||
|
if (isReadOnly()) new_title += tr(" [lecture seule]");
|
||||||
|
setWindowTitle(new_title);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomElementEditor::toFile(const QString &fn) {
|
||||||
|
QFile file(fn);
|
||||||
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
|
QMessageBox::warning(this, tr("Erreur"), tr("Impossible d'ecrire dans ce fichier"));
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
QTextStream out(&file);
|
||||||
|
out.setCodec("UTF-8");
|
||||||
|
out << ce_scene -> toXml().toString(4);
|
||||||
|
file.close();
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
specifie si l'editeur d'element doit etre en mode lecture seule
|
||||||
|
@param ro true pour activer le mode lecture seule, false pour le desactiver
|
||||||
|
*/
|
||||||
|
void CustomElementEditor::setReadOnly(bool ro) {
|
||||||
|
read_only = ro;
|
||||||
|
// active / desactive les actions
|
||||||
|
foreach (QAction *action, parts -> actions()) action -> setEnabled(!ro);
|
||||||
|
|
||||||
|
// active / desactive les interactions avec la scene
|
||||||
|
ce_view -> setInteractive(!ro);
|
||||||
|
|
||||||
|
// active / desactive l'edition de la taille, du hotspot, des noms et des orientations
|
||||||
|
edit_size -> setEnabled(!ro);
|
||||||
|
edit_hotspot -> setEnabled(!ro);
|
||||||
|
edit_names -> setEnabled(!ro);
|
||||||
|
edit_ori -> setEnabled(!ro);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return true si l'editeur d'element est en mode lecture seule
|
||||||
|
*/
|
||||||
|
bool CustomElementEditor::isReadOnly() const {
|
||||||
|
return(read_only);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_new() {
|
||||||
|
NewElementWizard new_element_wizard;
|
||||||
|
new_element_wizard.exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_open() {
|
||||||
|
// demande un nom de fichier a ouvrir a l'utilisateur
|
||||||
|
QString user_filename = QFileDialog::getOpenFileName(
|
||||||
|
this,
|
||||||
|
tr("Ouvrir un fichier"),
|
||||||
|
QETApp::customElementsDir(),
|
||||||
|
tr("\311l\351ments QElectroTech (*.elmt);;Fichiers XML (*.xml);;Tous les fichiers (*)")
|
||||||
|
);
|
||||||
|
if (user_filename == "") return;
|
||||||
|
CustomElementEditor *cee = new CustomElementEditor();
|
||||||
|
cee -> fromFile(user_filename);
|
||||||
|
cee -> show();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomElementEditor::slot_save() {
|
||||||
|
// si on ne connait pas le nom du fichier en cours, enregistrer revient a enregistrer sous
|
||||||
|
if (_filename == QString()) return(slot_saveAs());
|
||||||
|
// sinon on enregistre dans le nom de fichier connu
|
||||||
|
return(toFile(_filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomElementEditor::slot_saveAs() {
|
||||||
|
// demande un nom de fichier a l'utilisateur pour enregistrer l'element
|
||||||
|
QString fn = QFileDialog::getSaveFileName(
|
||||||
|
this,
|
||||||
|
tr("Enregistrer sous"),
|
||||||
|
QETApp::customElementsDir(),
|
||||||
|
tr("\311l\351ments QElectroTech (*.elmt)")
|
||||||
|
);
|
||||||
|
// si aucun nom n'est entre, renvoie faux.
|
||||||
|
if (fn == "") return(false);
|
||||||
|
// si le nom ne se termine pas par l'extension .elmt, celle-ci est ajoutee
|
||||||
|
if (!fn.endsWith(".elmt", Qt::CaseInsensitive)) fn += ".elmt";
|
||||||
|
// tente d'enregistrer le fichier
|
||||||
|
bool result_save = toFile(fn);
|
||||||
|
// si l'enregistrement reussit, le nom du fichier est conserve
|
||||||
|
if (result_save) setFileName(fn);
|
||||||
|
// retourne un booleen representatif de la reussite de l'enregistrement
|
||||||
|
return(result_save);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomElementEditor::slot_quit(QCloseEvent *event) {
|
||||||
|
if (close()) {
|
||||||
|
if (event != NULL) event -> accept();
|
||||||
|
delete(this);
|
||||||
|
} else if (event != NULL) event -> ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomElementEditor::close() {
|
||||||
|
// demande d'abord a l'utilisateur s'il veut enregistrer l'element en cours
|
||||||
|
QMessageBox::StandardButton answer = QMessageBox::question(
|
||||||
|
this,
|
||||||
|
tr("Enregistrer l'\351l\351ment en cours ?"),
|
||||||
|
tr("Voulez-vous enregistrer l'\351l\351ment ") + ce_scene -> names().name() + tr(" ?"),
|
||||||
|
QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel,
|
||||||
|
QMessageBox::Cancel
|
||||||
|
);
|
||||||
|
bool result;
|
||||||
|
switch(answer) {
|
||||||
|
case QMessageBox::Cancel: result = false; break; // l'utilisateur annule : echec de la fermeture
|
||||||
|
case QMessageBox::Yes: result = slot_save(); break; // l'utilisateur dit oui : la reussite depend de l'enregistrement
|
||||||
|
default: result = true; // l'utilisateur dit non ou ferme le dialogue: c'est reussi
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de quitter l'editeur lors de la fermeture de la fenetre principale
|
||||||
|
@param qce Le QCloseEvent correspondant a l'evenement de fermeture
|
||||||
|
*/
|
||||||
|
void CustomElementEditor::closeEvent(QCloseEvent *qce) {
|
||||||
|
slot_quit(qce);
|
||||||
|
}
|
128
editor/customelementeditor.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#ifndef CUSTOM_ELEMENT_EDITOR_H
|
||||||
|
#define CUSTOM_ELEMENT_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include "editorscene.h"
|
||||||
|
#include "orientationset.h"
|
||||||
|
class CustomElementEditor : public QMainWindow {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
// constructeur, destructeur
|
||||||
|
public:
|
||||||
|
CustomElementEditor(QWidget * = 0);
|
||||||
|
virtual ~CustomElementEditor();
|
||||||
|
private:
|
||||||
|
CustomElementEditor(const CustomElementEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
/// booleen indiquant si l'editeur est en mode "lecture seule" ou non
|
||||||
|
bool read_only;
|
||||||
|
/// menus
|
||||||
|
QMenu *file_menu, *edit_menu, *display_menu, *tools_menu, *help_menu;
|
||||||
|
/// vue sur la scene d'edition
|
||||||
|
QGraphicsView *ce_view;
|
||||||
|
/// scene d'edition
|
||||||
|
EditorScene *ce_scene;
|
||||||
|
/// container pour les widgets d'edition des parties
|
||||||
|
QDockWidget *tools_dock;
|
||||||
|
/// actions du menu fichier
|
||||||
|
QAction *new_element, *open, *save, *save_as, *quit;
|
||||||
|
/// actions du menu edition
|
||||||
|
QAction *selectall, *deselectall, *inv_select;
|
||||||
|
QAction *edit_delete, *edit_size, *edit_hotspot, *edit_names, *edit_ori;
|
||||||
|
/// barre d'outils
|
||||||
|
QToolBar *parts_toolbar;
|
||||||
|
/// actions de la barre d'outils
|
||||||
|
QActionGroup *parts;
|
||||||
|
QAction *move, *add_line, *add_circle, *add_ellipse, *add_polygon, *add_text;
|
||||||
|
QAction *add_arc, *add_terminal, *add_textfield;
|
||||||
|
/// label affiche lors de la selection de plusieurs elements
|
||||||
|
QLabel *default_informations;
|
||||||
|
/// titre minimal
|
||||||
|
QString min_title;
|
||||||
|
/// Nom de fichier
|
||||||
|
QString _filename;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
void setSize(const QSize &);
|
||||||
|
QSize size() const;
|
||||||
|
void setHotspot(const QPoint &);
|
||||||
|
QPoint hotspot() const;
|
||||||
|
void setNames(const NamesList &);
|
||||||
|
void setOrientations(const OrientationSet &orientation_set);
|
||||||
|
OrientationSet orientations() const;
|
||||||
|
void setFileName(const QString &);
|
||||||
|
QString fileName() const;
|
||||||
|
void setReadOnly(bool);
|
||||||
|
bool isReadOnly() const;
|
||||||
|
void fromFile(const QString &);
|
||||||
|
bool toFile(const QString &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void closeEvent(QCloseEvent *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupActions();
|
||||||
|
void setupMenus();
|
||||||
|
void setupInterface();
|
||||||
|
bool close();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void slot_new();
|
||||||
|
void slot_open();
|
||||||
|
bool slot_save();
|
||||||
|
bool slot_saveAs();
|
||||||
|
void slot_quit(QCloseEvent * = NULL);
|
||||||
|
void slot_setRubberBandToView();
|
||||||
|
void slot_setNoDragToView();
|
||||||
|
void slot_setNormalMode();
|
||||||
|
void slot_updateInformations();
|
||||||
|
void slot_updateMenus();
|
||||||
|
void xmlPreview();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void CustomElementEditor::setSize(const QSize &siz) {
|
||||||
|
ce_scene -> setWidth(siz.width());
|
||||||
|
ce_scene -> setHeight(siz.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QSize CustomElementEditor::size() const {
|
||||||
|
return(
|
||||||
|
QSize(
|
||||||
|
ce_scene -> width(),
|
||||||
|
ce_scene -> height()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomElementEditor::setHotspot(const QPoint &hs) {
|
||||||
|
ce_scene -> setHotspot(hs);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QPoint CustomElementEditor::hotspot() const {
|
||||||
|
return(ce_scene -> hotspot());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomElementEditor::setNames(const NamesList &nameslist) {
|
||||||
|
ce_scene -> setNames(nameslist);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomElementEditor::setOrientations(const OrientationSet &orientation_set) {
|
||||||
|
ce_scene -> setOrientations(orientation_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline OrientationSet CustomElementEditor::orientations() const {
|
||||||
|
return(ce_scene -> orientations());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CustomElementEditor::setFileName(const QString &fn) {
|
||||||
|
setWindowTitle(min_title + " - " + fn);
|
||||||
|
_filename = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QString CustomElementEditor::fileName() const {
|
||||||
|
return(_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
133
editor/customelementgraphicpart.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Ecrit les attributs de style dans un element XML
|
||||||
|
@param qde L'element XML a modifier
|
||||||
|
|
||||||
|
*/
|
||||||
|
void CustomElementGraphicPart::stylesToXml(QDomElement &qde) const {
|
||||||
|
QString css_like_styles;
|
||||||
|
|
||||||
|
css_like_styles += "line-style:";
|
||||||
|
if (_linestyle == DashedStyle) css_like_styles += "dashed";
|
||||||
|
else if (_linestyle == NormalStyle) css_like_styles += "normal";
|
||||||
|
|
||||||
|
css_like_styles += ";line-weight:";
|
||||||
|
if (_lineweight == NoneWeight) css_like_styles += "none";
|
||||||
|
else if (_lineweight == ThinWeight) css_like_styles += "thin";
|
||||||
|
else if (_lineweight == NormalWeight) css_like_styles += "normal";
|
||||||
|
|
||||||
|
css_like_styles += ";filling:";
|
||||||
|
if (_filling == NoneFilling) css_like_styles += "none";
|
||||||
|
else if (_filling == BlackFilling) css_like_styles += "black";
|
||||||
|
else if (_filling == WhiteFilling) css_like_styles += "white";
|
||||||
|
|
||||||
|
css_like_styles += ";color:";
|
||||||
|
if (_color == WhiteColor) css_like_styles += "white";
|
||||||
|
else if (_color == BlackColor) css_like_styles += "black";
|
||||||
|
|
||||||
|
qde.setAttribute("style", css_like_styles);
|
||||||
|
qde.setAttribute("antialias", _antialiased ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Lit les attributs de style depuis un element XML
|
||||||
|
@param qde L'element XML a analyser
|
||||||
|
*/
|
||||||
|
void CustomElementGraphicPart::stylesFromXml(const QDomElement &qde) {
|
||||||
|
resetStyles();
|
||||||
|
|
||||||
|
// recupere la liste des couples style / valeur
|
||||||
|
QStringList styles = qde.attribute("style").split(";", QString::SkipEmptyParts);
|
||||||
|
|
||||||
|
// analyse chaque couple
|
||||||
|
QRegExp rx("^\\s*([a-z-]+)\\s*:\\s*([a-z-]+)\\s*$");
|
||||||
|
foreach (QString style, styles) {
|
||||||
|
if (!rx.exactMatch(style)) continue;
|
||||||
|
QString style_name = rx.cap(1);
|
||||||
|
QString style_value = rx.cap(2);
|
||||||
|
if (style_name == "line-style") {
|
||||||
|
if (style_value == "dashed") _linestyle = DashedStyle;
|
||||||
|
else if (style_value == "normal") _linestyle = NormalStyle;
|
||||||
|
// il n'y a pas de else car les valeurs non conformes sont ignorees (idem par la suite)
|
||||||
|
} else if (style_name == "line-weight") {
|
||||||
|
if (style_value == "thin") _lineweight = ThinWeight;
|
||||||
|
else if (style_value == "normal") _lineweight = NormalWeight;
|
||||||
|
else if (style_value == "none") _lineweight = NoneWeight;
|
||||||
|
} else if (style_name == "filling") {
|
||||||
|
if (style_value == "white") _filling = WhiteFilling;
|
||||||
|
else if (style_value == "black") _filling = BlackFilling;
|
||||||
|
else if (style_value == "none") _filling = NoneFilling;
|
||||||
|
} else if (style_name == "color") {
|
||||||
|
if (style_value == "black") _color = BlackColor;
|
||||||
|
else if (style_value == "white") _color = WhiteColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// recupere l'antialiasing
|
||||||
|
_antialiased = qde.attribute("antialias") == "true";
|
||||||
|
|
||||||
|
// met a jour l'editeur de style
|
||||||
|
style_editor -> updateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Remet les styles par defaut
|
||||||
|
*/
|
||||||
|
void CustomElementGraphicPart::resetStyles() {
|
||||||
|
_linestyle = NormalStyle;
|
||||||
|
_lineweight = NormalWeight;
|
||||||
|
_filling = NoneFilling;
|
||||||
|
_color = BlackColor;
|
||||||
|
_antialiased = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Applique les styles a un Qpainter
|
||||||
|
@param painter QPainter a modifier
|
||||||
|
*/
|
||||||
|
void CustomElementGraphicPart::applyStylesToQPainter(QPainter &painter) const {
|
||||||
|
// recupere le QPen et la QBrush du QPainter
|
||||||
|
QPen pen = painter.pen();
|
||||||
|
QBrush brush = painter.brush();
|
||||||
|
|
||||||
|
// applique le style de trait
|
||||||
|
if (_linestyle == DashedStyle) pen.setStyle(Qt::DashLine);
|
||||||
|
else if (_linestyle == NormalStyle) pen.setStyle(Qt::SolidLine);
|
||||||
|
|
||||||
|
// applique l'epaisseur de trait
|
||||||
|
if (_lineweight == NoneWeight) pen.setColor(QColor(0, 0, 0, 0));
|
||||||
|
else if (_lineweight == ThinWeight) pen.setWidth(0);
|
||||||
|
else if (_lineweight == NormalWeight) pen.setWidthF(1.0);
|
||||||
|
|
||||||
|
// applique le remplissage
|
||||||
|
if (_filling == NoneFilling) {
|
||||||
|
brush.setStyle(Qt::NoBrush);
|
||||||
|
} else if (_filling == BlackFilling) {
|
||||||
|
brush.setStyle(Qt::SolidPattern);
|
||||||
|
brush.setColor(Qt::black);
|
||||||
|
} else if (_filling == WhiteFilling) {
|
||||||
|
brush.setStyle(Qt::SolidPattern);
|
||||||
|
brush.setColor(Qt::white);
|
||||||
|
}
|
||||||
|
|
||||||
|
// applique la couleur de trait
|
||||||
|
if (_color == WhiteColor) pen.setColor(QColor(255, 255, 255, pen.color().alpha()));
|
||||||
|
else if (_color == BlackColor) pen.setColor(QColor( 0, 0, 0, pen.color().alpha()));
|
||||||
|
|
||||||
|
|
||||||
|
// applique l'antialiasing
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing, _antialiased);
|
||||||
|
painter.setRenderHint(QPainter::TextAntialiasing, _antialiased);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform, _antialiased);
|
||||||
|
|
||||||
|
painter.setPen(pen);
|
||||||
|
painter.setBrush(brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return Le widget permettant d'editer les styles
|
||||||
|
*/
|
||||||
|
QWidget *CustomElementGraphicPart::elementInformations() {
|
||||||
|
return(style_editor);
|
||||||
|
}
|
145
editor/customelementgraphicpart.h
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
#ifndef CUSTOM_ELEMENT_GRAPHIC_PART_H
|
||||||
|
#define CUSTOM_ELEMENT_GRAPHIC_PART_H
|
||||||
|
#include <QPainter>
|
||||||
|
#include "customelementpart.h"
|
||||||
|
#include "styleeditor.h"
|
||||||
|
/**
|
||||||
|
Cette classe represente une partie graphique d'element
|
||||||
|
Elle encapsule des methodes afin de gerer les attributs de style communs
|
||||||
|
a la plupart des parties d'elements
|
||||||
|
*/
|
||||||
|
typedef CustomElementGraphicPart CEGP;
|
||||||
|
class CustomElementGraphicPart : public CustomElementPart {
|
||||||
|
public:
|
||||||
|
enum LineStyle { NormalStyle, DashedStyle };
|
||||||
|
enum LineWeight { NormalWeight, ThinWeight, NoneWeight };
|
||||||
|
enum Filling { NoneFilling, BlackFilling, WhiteFilling };
|
||||||
|
enum Color { BlackColor, WhiteColor };
|
||||||
|
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
CustomElementGraphicPart() :
|
||||||
|
_linestyle(NormalStyle),
|
||||||
|
_lineweight(NormalWeight),
|
||||||
|
_filling(NoneFilling),
|
||||||
|
_color(BlackColor),
|
||||||
|
_antialiased(false)
|
||||||
|
{
|
||||||
|
style_editor = new StyleEditor(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~CustomElementGraphicPart() {
|
||||||
|
qDebug() << "~CustomElementGraphicPart()";
|
||||||
|
delete style_editor;
|
||||||
|
};
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
LineStyle _linestyle;
|
||||||
|
LineWeight _lineweight;
|
||||||
|
Filling _filling ;
|
||||||
|
Color _color;
|
||||||
|
bool _antialiased;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
StyleEditor *style_editor;
|
||||||
|
|
||||||
|
//methodes
|
||||||
|
public:
|
||||||
|
void setLineStyle(LineStyle);
|
||||||
|
void setLineWeight(LineWeight);
|
||||||
|
void setFilling(Filling);
|
||||||
|
void setColor(Color);
|
||||||
|
void setAntialiased(bool);
|
||||||
|
|
||||||
|
LineStyle lineStyle() const;
|
||||||
|
LineWeight lineWeight() const;
|
||||||
|
Filling filling() const;
|
||||||
|
Color color() const;
|
||||||
|
bool antialiased() const;
|
||||||
|
|
||||||
|
QWidget *elementInformations();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void stylesToXml(QDomElement &) const;
|
||||||
|
void stylesFromXml(const QDomElement &);
|
||||||
|
void resetStyles();
|
||||||
|
void applyStylesToQPainter(QPainter &) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Change le style de trait
|
||||||
|
@param ls Le nouveau style de trait
|
||||||
|
*/
|
||||||
|
inline void CustomElementGraphicPart::setLineStyle(LineStyle ls) {
|
||||||
|
_linestyle = ls;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Change l'epaisseur de trait
|
||||||
|
@param lw La nouvelle epaisseur de trait
|
||||||
|
*/
|
||||||
|
inline void CustomElementGraphicPart::setLineWeight(LineWeight lw) {
|
||||||
|
_lineweight = lw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Change la couleur de remplissage
|
||||||
|
@param f La nouvelle couleur de remplissage
|
||||||
|
*/
|
||||||
|
inline void CustomElementGraphicPart::setFilling(Filling f) {
|
||||||
|
_filling = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Change la couleur de trait
|
||||||
|
@param c La nouvelle couleur de trait
|
||||||
|
*/
|
||||||
|
inline void CustomElementGraphicPart::setColor(Color c) {
|
||||||
|
_color = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return Le style de trait
|
||||||
|
*/
|
||||||
|
inline CustomElementGraphicPart::LineStyle CustomElementGraphicPart::lineStyle() const {
|
||||||
|
return(_linestyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return L'epaisseur de trait
|
||||||
|
*/
|
||||||
|
inline CustomElementGraphicPart::LineWeight CustomElementGraphicPart::lineWeight() const {
|
||||||
|
return(_lineweight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return La couleur de remplissage
|
||||||
|
*/
|
||||||
|
inline CustomElementGraphicPart::Filling CustomElementGraphicPart::filling() const {
|
||||||
|
return(_filling);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return La couleur de trait
|
||||||
|
*/
|
||||||
|
inline CustomElementGraphicPart::Color CustomElementGraphicPart::color() const {
|
||||||
|
return(_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Definit si la partie doit etre antialiasee ou non
|
||||||
|
@param aa True pour activer l'antialiasing, false pour le desactiver
|
||||||
|
*/
|
||||||
|
inline void CustomElementGraphicPart::setAntialiased(bool aa) {
|
||||||
|
_antialiased = aa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return true si la partie est antialiasee, false sinon
|
||||||
|
*/
|
||||||
|
inline bool CustomElementGraphicPart::antialiased() const {
|
||||||
|
return(_antialiased);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
6
editor/customelementpart.cpp
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#include "customelementpart.h"
|
||||||
|
#include "customelement.h"
|
||||||
|
|
||||||
|
QPicture *CustomElementPart::getCustomElementQPicture(CustomElement &ce) const {
|
||||||
|
return(&(ce.dessin));
|
||||||
|
}
|
39
editor/customelementpart.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef CUSTOM_ELEMENT_PART_H
|
||||||
|
#define CUSTOM_ELEMENT_PART_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include <QtXml>
|
||||||
|
#include <QImage>
|
||||||
|
class CustomElement;
|
||||||
|
/**
|
||||||
|
Cette classe abstraite represente une partie de la representation graphique
|
||||||
|
d'un element de schema electrique. Les attributs et methodes qu'elle
|
||||||
|
encapsule ne sont pas integres directement dans la classe CustomElement
|
||||||
|
afin de ne pas alourdir celle-ci. Il est en effet inutile pour cette classe
|
||||||
|
de retenir sa conception graphique autrement que sous la forme d'une
|
||||||
|
QImage.
|
||||||
|
*/
|
||||||
|
class CustomElementPart {
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
CustomElementPart() {};
|
||||||
|
virtual ~CustomElementPart() {
|
||||||
|
qDebug() << "~CustomElementPart()";
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
CustomElementPart(const CustomElementPart &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
virtual void fromXml(const QDomElement &) = 0;
|
||||||
|
virtual const QDomElement toXml(QDomDocument &) const = 0;
|
||||||
|
virtual QWidget *elementInformations() = 0;
|
||||||
|
//virtual void renderToCustomElement(CustomElement &) const = 0;
|
||||||
|
//virtual void toEditorPart(const EditorPart &);
|
||||||
|
//virtual void fromEditorPart(const EditorPart &) = 0;
|
||||||
|
protected:
|
||||||
|
QPicture *getCustomElementQPicture(CustomElement &ce) const;
|
||||||
|
};
|
||||||
|
#endif
|
447
editor/editorscene.cpp
Normal file
@ -0,0 +1,447 @@
|
|||||||
|
#include "editorscene.h"
|
||||||
|
#include <cmath>
|
||||||
|
#include "partline.h"
|
||||||
|
#include "partellipse.h"
|
||||||
|
#include "partcircle.h"
|
||||||
|
#include "partpolygon.h"
|
||||||
|
#include "partterminal.h"
|
||||||
|
#include "parttext.h"
|
||||||
|
#define GRILLE_X 10
|
||||||
|
#define GRILLE_Y 10
|
||||||
|
|
||||||
|
EditorScene::EditorScene(QObject *parent) :
|
||||||
|
QGraphicsScene(parent),
|
||||||
|
_width(3),
|
||||||
|
_height(7),
|
||||||
|
_hotspot(15, 35)
|
||||||
|
{
|
||||||
|
current_polygon = NULL;
|
||||||
|
connect(this, SIGNAL(changed(const QList<QRectF> &)), this, SLOT(slot_checkSelectionChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorScene::~EditorScene() {
|
||||||
|
qDebug() << "~EditorScene()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_move() {
|
||||||
|
behavior = Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addLine() {
|
||||||
|
behavior = Line;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addCircle() {
|
||||||
|
behavior = Circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addEllipse() {
|
||||||
|
behavior = Ellipse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addPolygon() {
|
||||||
|
behavior = Polygon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addText() {
|
||||||
|
behavior = Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addTerminal() {
|
||||||
|
behavior = Terminal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addArc() {
|
||||||
|
behavior = Arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_addTextField() {
|
||||||
|
behavior = TextField;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
|
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||||
|
QRectF temp_rect;
|
||||||
|
qreal radius;
|
||||||
|
QPointF temp_point;
|
||||||
|
QPolygonF temp_polygon;
|
||||||
|
if (e -> buttons() & Qt::LeftButton) {
|
||||||
|
switch(behavior) {
|
||||||
|
case Normal:
|
||||||
|
QGraphicsScene::mouseMoveEvent(e);
|
||||||
|
break;
|
||||||
|
case Line:
|
||||||
|
current_line -> setLine(QLineF(current_line -> line().p1(), e -> scenePos()));
|
||||||
|
break;
|
||||||
|
case Ellipse:
|
||||||
|
temp_rect = current_ellipse -> rect();
|
||||||
|
temp_rect.setBottomRight(e -> scenePos());
|
||||||
|
current_ellipse -> setRect(temp_rect);
|
||||||
|
break;
|
||||||
|
case Circle:
|
||||||
|
temp_rect = current_circle -> rect();
|
||||||
|
temp_point = e -> scenePos() - current_circle -> mapToScene(temp_rect.center());
|
||||||
|
radius = sqrt(pow(temp_point.x(), 2) + pow(temp_point.y(), 2));
|
||||||
|
temp_rect = QRectF(
|
||||||
|
temp_rect.center() - QPointF(radius, radius),
|
||||||
|
QSizeF(2.0 * radius, 2.0 * radius)
|
||||||
|
);
|
||||||
|
current_circle -> setRect(temp_rect);
|
||||||
|
break;
|
||||||
|
case Polygon:
|
||||||
|
if (current_polygon == NULL) break;
|
||||||
|
temp_polygon = current_polygon -> polygon();
|
||||||
|
temp_polygon.pop_back();
|
||||||
|
temp_polygon << e -> scenePos();
|
||||||
|
current_polygon -> setPolygon(temp_polygon);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QGraphicsScene::mouseMoveEvent(e);
|
||||||
|
}
|
||||||
|
} else if (behavior == Polygon && current_polygon != NULL) {
|
||||||
|
temp_polygon = current_polygon -> polygon();
|
||||||
|
temp_polygon.pop_back();
|
||||||
|
temp_polygon << e -> scenePos();
|
||||||
|
current_polygon -> setPolygon(temp_polygon);
|
||||||
|
} else QGraphicsScene::mouseMoveEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
|
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||||
|
QPolygonF temp_polygon;
|
||||||
|
if (e -> button() & Qt::LeftButton) {
|
||||||
|
switch(behavior) {
|
||||||
|
case Normal:
|
||||||
|
QGraphicsScene::mousePressEvent(e);
|
||||||
|
break;
|
||||||
|
case Line:
|
||||||
|
current_line = new PartLine(0, this);
|
||||||
|
current_line -> setLine(QLineF(e -> scenePos(), e -> scenePos()));
|
||||||
|
break;
|
||||||
|
case Ellipse:
|
||||||
|
current_ellipse = new PartEllipse(0, this);
|
||||||
|
current_ellipse -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
||||||
|
break;
|
||||||
|
case Circle:
|
||||||
|
current_circle = new PartCircle(0, this);
|
||||||
|
current_circle -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
||||||
|
break;
|
||||||
|
case Polygon:
|
||||||
|
if (current_polygon == NULL) {
|
||||||
|
current_polygon = new PartPolygon(0, this);
|
||||||
|
temp_polygon = QPolygonF(0);
|
||||||
|
} else temp_polygon = current_polygon -> polygon();
|
||||||
|
// au debut, on insere deux points
|
||||||
|
if (!temp_polygon.count()) temp_polygon << e -> scenePos();
|
||||||
|
temp_polygon << e -> scenePos();
|
||||||
|
current_polygon -> setPolygon(temp_polygon);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QGraphicsScene::mousePressEvent(e);
|
||||||
|
}
|
||||||
|
} else QGraphicsScene::mousePressEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
|
PartTerminal *terminal;
|
||||||
|
PartText *text;
|
||||||
|
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||||
|
if (e -> button() & Qt::LeftButton) {
|
||||||
|
switch(behavior) {
|
||||||
|
case Normal:
|
||||||
|
QGraphicsScene::mouseReleaseEvent(e);
|
||||||
|
break;
|
||||||
|
case Line:
|
||||||
|
break;
|
||||||
|
case Ellipse:
|
||||||
|
current_ellipse -> setRect(current_ellipse -> rect().normalized());
|
||||||
|
break;
|
||||||
|
case Circle:
|
||||||
|
current_circle -> setRect(current_circle -> rect().normalized());
|
||||||
|
break;
|
||||||
|
case Terminal:
|
||||||
|
terminal = new PartTerminal(0, this);
|
||||||
|
terminal -> setPos(e -> scenePos());
|
||||||
|
break;
|
||||||
|
case Text:
|
||||||
|
text = new PartText(0, this);
|
||||||
|
text -> setPos(e -> scenePos());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
QGraphicsScene::mouseReleaseEvent(e);
|
||||||
|
}
|
||||||
|
} else if (e -> button() & Qt::RightButton) {
|
||||||
|
if (behavior == Polygon) {
|
||||||
|
behavior = Normal;
|
||||||
|
current_polygon = NULL;
|
||||||
|
emit(needNormalMode());
|
||||||
|
} else QGraphicsScene::mouseReleaseEvent(e);
|
||||||
|
} else QGraphicsScene::mouseReleaseEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Dessine l'arriere-plan de l'editeur, cad la grille.
|
||||||
|
@param p Le QPainter a utiliser pour dessiner
|
||||||
|
@param r Le rectangle de la zone a dessiner
|
||||||
|
*/
|
||||||
|
void EditorScene::drawBackground(QPainter *p, const QRectF &r) {
|
||||||
|
p -> save();
|
||||||
|
|
||||||
|
// desactive tout antialiasing, sauf pour le texte
|
||||||
|
p -> setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
p -> setRenderHint(QPainter::TextAntialiasing, true);
|
||||||
|
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||||
|
|
||||||
|
// dessine un fond blanc
|
||||||
|
p -> setPen(Qt::NoPen);
|
||||||
|
p -> setBrush(Qt::white);
|
||||||
|
p -> drawRect(r);
|
||||||
|
|
||||||
|
// encadre la zone dessinable de l'element
|
||||||
|
QRectF drawable_area(-_hotspot.x(), -_hotspot.y(), width(), height());
|
||||||
|
p -> setPen(Qt::black);
|
||||||
|
p -> setBrush(Qt::NoBrush);
|
||||||
|
p -> drawRect(drawable_area);
|
||||||
|
|
||||||
|
if (r.width() < 2500 && r.height() < 2500) {
|
||||||
|
// dessine les points de la grille
|
||||||
|
p -> setPen(Qt::black);
|
||||||
|
p -> setBrush(Qt::NoBrush);
|
||||||
|
qreal limite_x = r.x() + r.width();
|
||||||
|
qreal limite_y = r.y() + r.height();
|
||||||
|
|
||||||
|
int g_x = (int)ceil(r.x());
|
||||||
|
while (g_x % GRILLE_X) ++ g_x;
|
||||||
|
int g_y = (int)ceil(r.y());
|
||||||
|
while (g_y % GRILLE_Y) ++ g_y;
|
||||||
|
|
||||||
|
for (int gx = g_x ; gx < limite_x ; gx += GRILLE_X) {
|
||||||
|
for (int gy = g_y ; gy < limite_y ; gy += GRILLE_Y) {
|
||||||
|
p -> drawPoint(gx, gy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p -> restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Dessine l'arriere-plan de l'editeur, cad l'indicateur de hotspotó.
|
||||||
|
@param p Le QPainter a utiliser pour dessiner
|
||||||
|
@param r Le rectangle de la zone a dessiner
|
||||||
|
*/
|
||||||
|
void EditorScene::drawForeground(QPainter *p, const QRectF &) {
|
||||||
|
p -> save();
|
||||||
|
|
||||||
|
// desactive tout antialiasing, sauf pour le texte
|
||||||
|
p -> setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
p -> setRenderHint(QPainter::TextAntialiasing, true);
|
||||||
|
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||||
|
|
||||||
|
p -> setPen(Qt::red);
|
||||||
|
p -> setBrush(Qt::NoBrush);
|
||||||
|
p -> drawLine(QLineF(0.0, -_hotspot.y(), 0.0, height() - _hotspot.y()));
|
||||||
|
p -> drawLine(QLineF(-_hotspot.x(), 0.0, width() - _hotspot.x(), 0.0));
|
||||||
|
p -> restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomDocument EditorScene::toXml() const {
|
||||||
|
// document XML
|
||||||
|
QDomDocument xml_document;
|
||||||
|
|
||||||
|
// racine du document XML
|
||||||
|
QDomElement root = xml_document.createElement("definition");
|
||||||
|
root.setAttribute("type", "element");
|
||||||
|
root.setAttribute("width", QString("%1").arg(_width * 10));
|
||||||
|
root.setAttribute("height", QString("%1").arg(_height * 10));
|
||||||
|
root.setAttribute("hotspot_x", QString("%1").arg(_hotspot.x()));
|
||||||
|
root.setAttribute("hotspot_y", QString("%1").arg(_hotspot.y()));
|
||||||
|
root.setAttribute("orientation", ori.toString());
|
||||||
|
|
||||||
|
// noms de l'element
|
||||||
|
root.appendChild(_names.toXml(xml_document));
|
||||||
|
|
||||||
|
QDomElement description = xml_document.createElement("description");
|
||||||
|
// description de l'element
|
||||||
|
foreach(QGraphicsItem *qgi, items()) {
|
||||||
|
if (CustomElementPart *ce = dynamic_cast<CustomElementPart *>(qgi)) {
|
||||||
|
description.appendChild(ce -> toXml(xml_document));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
root.appendChild(description);
|
||||||
|
|
||||||
|
xml_document.appendChild(root);
|
||||||
|
return(xml_document);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::fromXml(const QDomDocument &xml_document) {
|
||||||
|
|
||||||
|
QString error_message;
|
||||||
|
bool state = true;
|
||||||
|
|
||||||
|
// la racine est supposee etre une definition d'element
|
||||||
|
QDomElement root = xml_document.documentElement();
|
||||||
|
if (root.tagName() != "definition" || root.attribute("type") != "element") {
|
||||||
|
state = false;
|
||||||
|
error_message = tr("Ce document XML n'est pas une definition d'\351l\351ment.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// dimensions et hotspot
|
||||||
|
if (state) {
|
||||||
|
// ces attributs doivent etre presents et valides
|
||||||
|
int w, h, hot_x, hot_y;
|
||||||
|
if (
|
||||||
|
!QET::attributeIsAnInteger(root, QString("width"), &w) ||\
|
||||||
|
!QET::attributeIsAnInteger(root, QString("height"), &h) ||\
|
||||||
|
!QET::attributeIsAnInteger(root, QString("hotspot_x"), &hot_x) ||\
|
||||||
|
!QET::attributeIsAnInteger(root, QString("hotspot_y"), &hot_y)
|
||||||
|
) {
|
||||||
|
state = false;
|
||||||
|
error_message = tr("Les dimensions ou le point de saisie ne sont pas valides.");
|
||||||
|
} else {
|
||||||
|
setWidth(w);
|
||||||
|
setHeight(h);
|
||||||
|
setHotspot(QPoint(hot_x, hot_y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// orientations
|
||||||
|
if (state) {
|
||||||
|
if (!ori.fromString(root.attribute("orientation"))) {
|
||||||
|
state = false;
|
||||||
|
error_message = tr("Les orientations ne sont pas valides.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extrait les noms de la definition XML
|
||||||
|
if (state) {
|
||||||
|
_names.fromXml(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parcours des enfants de la definition : parties de l'element
|
||||||
|
if (state) {
|
||||||
|
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
|
||||||
|
QDomElement elmts = node.toElement();
|
||||||
|
if (elmts.isNull()) continue;
|
||||||
|
if (elmts.tagName() == "description") {
|
||||||
|
// gestion de la description graphique de l'element
|
||||||
|
// = parcours des differentes parties du dessin
|
||||||
|
int z = 1;
|
||||||
|
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
|
||||||
|
QDomElement qde = n.toElement();
|
||||||
|
if (qde.isNull()) continue;
|
||||||
|
CustomElementPart *cep;
|
||||||
|
if (qde.tagName() == "line") cep = new PartLine (0, this);
|
||||||
|
else if (qde.tagName() == "ellipse") cep = new PartEllipse (0, this);
|
||||||
|
else if (qde.tagName() == "circle") cep = new PartCircle (0, this);
|
||||||
|
else if (qde.tagName() == "polygon") cep = new PartPolygon (0, this);
|
||||||
|
else if (qde.tagName() == "terminal") cep = new PartTerminal(0, this);
|
||||||
|
else if (qde.tagName() == "text") cep = new PartText (0, this);
|
||||||
|
else continue;
|
||||||
|
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) qgi -> setZValue(z++);
|
||||||
|
cep -> fromXml(qde);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_checkSelectionChanged() {
|
||||||
|
static QList<QGraphicsItem *> cache_selecteditems = QList<QGraphicsItem *>();
|
||||||
|
QList<QGraphicsItem *> selecteditems = selectedItems();
|
||||||
|
if (cache_selecteditems != selecteditems) emit(selectionChanged());
|
||||||
|
cache_selecteditems = selecteditems;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_selectAll() {
|
||||||
|
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_deselectAll() {
|
||||||
|
clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_invertSelection() {
|
||||||
|
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(!qgi -> isSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_delete() {
|
||||||
|
// verifie qu'il y a qqc de selectionne
|
||||||
|
QList<QGraphicsItem *> selected_items = selectedItems();
|
||||||
|
if (selected_items.isEmpty()) return;
|
||||||
|
|
||||||
|
// efface tout ce qui est selectionne
|
||||||
|
foreach(QGraphicsItem *qgi, selected_items) {
|
||||||
|
removeItem(qgi);
|
||||||
|
delete qgi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_editSize() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_editHotSpot() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_editOrientations() {
|
||||||
|
|
||||||
|
// cree un dialogue
|
||||||
|
QDialog dialog_ori;
|
||||||
|
dialog_ori.setModal(true);
|
||||||
|
dialog_ori.setFixedSize(400, 230);
|
||||||
|
dialog_ori.setWindowTitle(tr("\311diter les orientations"));
|
||||||
|
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_ori);
|
||||||
|
|
||||||
|
// ajoute un champ explicatif au dialogue
|
||||||
|
QLabel *information_label = new QLabel(tr("L'orientation par d\351faut est l'orientation dans laquelle s'effectue la cr\351ation de l'\351l\351ment."));
|
||||||
|
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||||||
|
information_label -> setWordWrap(true);
|
||||||
|
dialog_layout -> addWidget(information_label);
|
||||||
|
|
||||||
|
// ajoute un OrientationSetWidget au dialogue
|
||||||
|
OrientationSetWidget *ori_widget = new OrientationSetWidget();
|
||||||
|
ori_widget -> setOrientationSet(ori);
|
||||||
|
dialog_layout -> addWidget(ori_widget);
|
||||||
|
|
||||||
|
// ajoute deux boutons au dialogue
|
||||||
|
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
dialog_layout -> addWidget(dialog_buttons);
|
||||||
|
connect(dialog_buttons, SIGNAL(accepted()), &dialog_ori, SLOT(accept()));
|
||||||
|
connect(dialog_buttons, SIGNAL(rejected()), &dialog_ori, SLOT(reject()));
|
||||||
|
|
||||||
|
// lance le dialogue
|
||||||
|
if (dialog_ori.exec() == QDialog::Accepted) ori = ori_widget -> orientationSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EditorScene::slot_editNames() {
|
||||||
|
|
||||||
|
// cree un dialogue
|
||||||
|
QDialog dialog;
|
||||||
|
dialog.setModal(true);
|
||||||
|
dialog.setFixedSize(400, 330);
|
||||||
|
dialog.setWindowTitle(tr("\311diter les noms"));
|
||||||
|
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog);
|
||||||
|
|
||||||
|
// ajoute un champ explicatif au dialogue
|
||||||
|
QLabel *information_label = new QLabel(tr("Vous pouvez sp\351cifier le nom de l'\351l\351ment dans plusieurs langues."));
|
||||||
|
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||||||
|
information_label -> setWordWrap(true);
|
||||||
|
dialog_layout -> addWidget(information_label);
|
||||||
|
|
||||||
|
// ajoute un NamesListWidget au dialogue
|
||||||
|
NamesListWidget *names_widget = new NamesListWidget();
|
||||||
|
names_widget -> setNames(_names);
|
||||||
|
dialog_layout -> addWidget(names_widget);
|
||||||
|
|
||||||
|
// ajoute deux boutons au dialogue
|
||||||
|
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||||
|
dialog_layout -> addWidget(dialog_buttons);
|
||||||
|
connect(dialog_buttons, SIGNAL(accepted()), names_widget, SLOT(check()));
|
||||||
|
connect(names_widget, SIGNAL(inputChecked()), &dialog, SLOT(accept()));
|
||||||
|
connect(dialog_buttons, SIGNAL(rejected()), &dialog, SLOT(reject()));
|
||||||
|
|
||||||
|
// lance le dialogue
|
||||||
|
if (dialog.exec() == QDialog::Accepted) _names = names_widget -> names();
|
||||||
|
}
|
||||||
|
|
136
editor/editorscene.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#ifndef EDITOR_SCNE_H
|
||||||
|
#define EDITOR_SCNE_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include <QtXml>
|
||||||
|
#include "nameslistwidget.h"
|
||||||
|
#include "orientationsetwidget.h"
|
||||||
|
class PartLine;
|
||||||
|
class PartEllipse;
|
||||||
|
class PartCircle;
|
||||||
|
class PartPolygon;
|
||||||
|
class EditorScene : public QGraphicsScene {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
// enum
|
||||||
|
enum Behavior { Normal, Line, Circle, Ellipse, Polygon, Text, Terminal, Arc, TextField };
|
||||||
|
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
EditorScene(QObject * = 0);
|
||||||
|
virtual ~EditorScene();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EditorScene(const EditorScene &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
/// longueur de l'element en dizaines de pixels
|
||||||
|
uint _width;
|
||||||
|
/// hauteur de l'element en dizaines de pixels
|
||||||
|
uint _height;
|
||||||
|
/// position du point de saisie
|
||||||
|
QPoint _hotspot;
|
||||||
|
/// Liste des noms de l'element
|
||||||
|
NamesList _names;
|
||||||
|
/// Liste des orientations de l'element
|
||||||
|
OrientationSet ori;
|
||||||
|
|
||||||
|
/// Variables relatives a la gestion du dessin des parties sur la scene
|
||||||
|
Behavior behavior;
|
||||||
|
PartLine *current_line;
|
||||||
|
PartEllipse *current_ellipse;
|
||||||
|
PartCircle *current_circle;
|
||||||
|
PartPolygon *current_polygon;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
void setWidth(const uint& theValue);
|
||||||
|
uint width() const;
|
||||||
|
void setHeight(const uint& theValue);
|
||||||
|
uint height() const;
|
||||||
|
void setHotspot(const QPoint &);
|
||||||
|
QPoint hotspot() const;
|
||||||
|
void setNames(const NamesList);
|
||||||
|
NamesList names() const;
|
||||||
|
OrientationSet orientations();
|
||||||
|
void setOrientations(const OrientationSet &);
|
||||||
|
virtual const QDomDocument toXml() const;
|
||||||
|
virtual void fromXml(const QDomDocument &);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
|
||||||
|
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
|
||||||
|
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
|
||||||
|
virtual void drawBackground(QPainter *, const QRectF &);
|
||||||
|
virtual void drawForeground(QPainter *, const QRectF &);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void slot_move();
|
||||||
|
void slot_addLine();
|
||||||
|
void slot_addCircle();
|
||||||
|
void slot_addEllipse();
|
||||||
|
void slot_addPolygon();
|
||||||
|
void slot_addText();
|
||||||
|
void slot_addArc();
|
||||||
|
void slot_addTerminal();
|
||||||
|
void slot_addTextField();
|
||||||
|
void slot_checkSelectionChanged();
|
||||||
|
void slot_selectAll();
|
||||||
|
void slot_deselectAll();
|
||||||
|
void slot_invertSelection();
|
||||||
|
void slot_delete();
|
||||||
|
void slot_editSize();
|
||||||
|
void slot_editHotSpot();
|
||||||
|
void slot_editNames();
|
||||||
|
void slot_editOrientations();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void selectionChanged();
|
||||||
|
void needNormalMode();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void EditorScene::setWidth(const uint &wid) {
|
||||||
|
_width = wid;
|
||||||
|
while (_width % 10) ++ _width;
|
||||||
|
_width /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint EditorScene::width() const {
|
||||||
|
return(_width * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EditorScene::setHeight(const uint &hei) {
|
||||||
|
_height = hei;
|
||||||
|
while (_height % 10) ++ _height;
|
||||||
|
_height /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint EditorScene::height() const {
|
||||||
|
return(_height * 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EditorScene::setHotspot(const QPoint &hs) {
|
||||||
|
_hotspot = hs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QPoint EditorScene::hotspot() const {
|
||||||
|
return(_hotspot);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EditorScene::setNames(const NamesList nameslist) {
|
||||||
|
_names = nameslist;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline NamesList EditorScene::names() const {
|
||||||
|
return(_names);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline OrientationSet EditorScene::orientations() {
|
||||||
|
return(ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void EditorScene::setOrientations(const OrientationSet &orientation_set) {
|
||||||
|
ori = orientation_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
66
editor/ellipseeditor.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "ellipseeditor.h"
|
||||||
|
#include "partellipse.h"
|
||||||
|
|
||||||
|
EllipseEditor::EllipseEditor(PartEllipse *ellipse, QWidget *parent) : QWidget(parent) {
|
||||||
|
|
||||||
|
part = ellipse;
|
||||||
|
|
||||||
|
x = new QLineEdit();
|
||||||
|
y = new QLineEdit();
|
||||||
|
h = new QLineEdit();
|
||||||
|
v = new QLineEdit();
|
||||||
|
|
||||||
|
// QDoubleValidator *format = new QDoubleValidator(-1000.0, -1000.0, 4, this);
|
||||||
|
// x -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
|
||||||
|
// y -> setValidator(new QDoubleValidator(-1000.0, 1000.0, 4, this));
|
||||||
|
// h -> setValidator(new QDoubleValidator(0.0, 1000.0, 4, this));
|
||||||
|
// v -> setValidator(new QDoubleValidator(0.0, 1000.0, 4, this));
|
||||||
|
|
||||||
|
|
||||||
|
QGridLayout *grid = new QGridLayout(this);
|
||||||
|
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
|
||||||
|
grid -> addWidget(new QLabel("x"), 1, 0);
|
||||||
|
grid -> addWidget(x, 1, 1);
|
||||||
|
grid -> addWidget(new QLabel("y"), 1, 2);
|
||||||
|
grid -> addWidget(y, 1, 3);
|
||||||
|
grid -> addWidget(new QLabel(tr("Diam\350tres : ")), 2, 0);
|
||||||
|
grid -> addWidget(new QLabel(tr("horizontal :")), 3, 0);
|
||||||
|
grid -> addWidget(h, 3, 1);
|
||||||
|
grid -> addWidget(new QLabel(tr("vertical :")), 4, 0);
|
||||||
|
grid -> addWidget(v, 4, 1);
|
||||||
|
|
||||||
|
updateForm();
|
||||||
|
|
||||||
|
connect(x, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
|
||||||
|
connect(y, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
|
||||||
|
connect(h, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
|
||||||
|
connect(v, SIGNAL(editingFinished()), this, SLOT(updateEllipse()));
|
||||||
|
}
|
||||||
|
|
||||||
|
EllipseEditor::~EllipseEditor() {
|
||||||
|
qDebug() << "~EllipseEditor()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void EllipseEditor::updateEllipse() {
|
||||||
|
qreal _x = x -> text().toDouble();
|
||||||
|
qreal _y = y -> text().toDouble();
|
||||||
|
qreal _h = h -> text().toDouble();
|
||||||
|
qreal _v = v -> text().toDouble();
|
||||||
|
_v = _v < 0 ? -_v : _v;
|
||||||
|
part -> setRect(
|
||||||
|
QRectF(
|
||||||
|
part -> mapFromScene(QPointF(_x - (_h / 2.0), _y - (_v / 2.0))),
|
||||||
|
QSizeF(_h, _v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EllipseEditor::updateForm() {
|
||||||
|
qreal _h = part -> rect().width();
|
||||||
|
qreal _v = part -> rect().height();
|
||||||
|
QPointF top_left(part -> sceneTopLeft());
|
||||||
|
x -> setText(QString("%1").arg(top_left.x() + (_h / 2.0)));
|
||||||
|
y -> setText(QString("%1").arg(top_left.y() + (_v / 2.0)));
|
||||||
|
h -> setText(QString("%1").arg(_h));
|
||||||
|
v -> setText(QString("%1").arg(_v));
|
||||||
|
}
|
24
editor/ellipseeditor.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef ELLIPSE_EDITOR_H
|
||||||
|
#define ELLIPSE_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class PartEllipse;
|
||||||
|
class EllipseEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
//constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
EllipseEditor(PartEllipse *, QWidget * = 0);
|
||||||
|
~EllipseEditor();
|
||||||
|
private:
|
||||||
|
EllipseEditor(const EllipseEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
PartEllipse *part;
|
||||||
|
QLineEdit *x, *y, *h, *v;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public slots:
|
||||||
|
void updateEllipse();
|
||||||
|
void updateForm();
|
||||||
|
};
|
||||||
|
#endif
|
57
editor/lineeditor.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "lineeditor.h"
|
||||||
|
#include "partline.h"
|
||||||
|
|
||||||
|
LineEditor::LineEditor(PartLine *line, QWidget *parent) : QWidget(parent) {
|
||||||
|
|
||||||
|
part = line;
|
||||||
|
|
||||||
|
x1 = new QLineEdit();
|
||||||
|
y1 = new QLineEdit();
|
||||||
|
x2 = new QLineEdit();
|
||||||
|
y2 = new QLineEdit();
|
||||||
|
|
||||||
|
QGridLayout *grid = new QGridLayout(this);
|
||||||
|
grid -> addWidget(new QLabel("x1"), 0, 0);
|
||||||
|
grid -> addWidget(x1, 0, 1);
|
||||||
|
grid -> addWidget(new QLabel("y1"), 0, 2);
|
||||||
|
grid -> addWidget(y1, 0, 3);
|
||||||
|
grid -> addWidget(new QLabel("x2"), 1, 0);
|
||||||
|
grid -> addWidget(x2, 1, 1);
|
||||||
|
grid -> addWidget(new QLabel("y2"), 1, 2);
|
||||||
|
grid -> addWidget(y2, 1, 3);
|
||||||
|
|
||||||
|
updateForm();
|
||||||
|
|
||||||
|
connect(x1, SIGNAL(editingFinished()), this, SLOT(updateLine()));
|
||||||
|
connect(y1, SIGNAL(editingFinished()), this, SLOT(updateLine()));
|
||||||
|
connect(x2, SIGNAL(editingFinished()), this, SLOT(updateLine()));
|
||||||
|
connect(y2, SIGNAL(editingFinished()), this, SLOT(updateLine()));
|
||||||
|
}
|
||||||
|
|
||||||
|
LineEditor::~LineEditor() {
|
||||||
|
qDebug() << "~LineEditor()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditor::updateLine() {
|
||||||
|
part -> setLine(
|
||||||
|
QLineF(
|
||||||
|
part -> mapFromScene(
|
||||||
|
x1 -> text().toDouble(),
|
||||||
|
y1 -> text().toDouble()
|
||||||
|
),
|
||||||
|
part -> mapFromScene(
|
||||||
|
x2 -> text().toDouble(),
|
||||||
|
y2 -> text().toDouble()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LineEditor::updateForm() {
|
||||||
|
QPointF p1(part -> sceneP1());
|
||||||
|
QPointF p2(part -> sceneP2());
|
||||||
|
x1 -> setText(QString("%1").arg(p1.x()));
|
||||||
|
y1 -> setText(QString("%1").arg(p1.y()));
|
||||||
|
x2 -> setText(QString("%1").arg(p2.x()));
|
||||||
|
y2 -> setText(QString("%1").arg(p2.y()));
|
||||||
|
}
|
24
editor/lineeditor.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef LINE_EDITOR_H
|
||||||
|
#define LINE_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class PartLine;
|
||||||
|
class LineEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
//constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
LineEditor(PartLine *, QWidget * = 0);
|
||||||
|
~LineEditor();
|
||||||
|
private:
|
||||||
|
LineEditor(const LineEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
PartLine *part;
|
||||||
|
QLineEdit *x1, *y1, *x2, *y2;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public slots:
|
||||||
|
void updateLine();
|
||||||
|
void updateForm();
|
||||||
|
};
|
||||||
|
#endif
|
77
editor/partcircle.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#include "partcircle.h"
|
||||||
|
#include "circleeditor.h"
|
||||||
|
|
||||||
|
PartCircle::PartCircle(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart() {
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
setAcceptedMouseButtons(Qt::LeftButton);
|
||||||
|
informations = new CircleEditor(this);
|
||||||
|
style_editor -> appendWidget(informations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartCircle::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
|
||||||
|
applyStylesToQPainter(*painter);
|
||||||
|
QPen t = painter -> pen();
|
||||||
|
if (isSelected()) {
|
||||||
|
t.setColor(Qt::red);
|
||||||
|
painter -> setPen(t);
|
||||||
|
}
|
||||||
|
painter -> drawEllipse(rect());
|
||||||
|
if (isSelected()) {
|
||||||
|
painter -> setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
|
||||||
|
QPointF center = rect().center();
|
||||||
|
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
|
||||||
|
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomElement PartCircle::toXml(QDomDocument &xml_document) const {
|
||||||
|
QDomElement xml_element = xml_document.createElement("circle");
|
||||||
|
QPointF top_left(sceneTopLeft());
|
||||||
|
xml_element.setAttribute("x", top_left.x());
|
||||||
|
xml_element.setAttribute("y", top_left.y());
|
||||||
|
xml_element.setAttribute("diameter", rect().width());
|
||||||
|
stylesToXml(xml_element);
|
||||||
|
return(xml_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartCircle::fromXml(const QDomElement &qde) {
|
||||||
|
stylesFromXml(qde);
|
||||||
|
qreal diameter = qde.attribute("diameter", "0").toDouble();
|
||||||
|
setRect(
|
||||||
|
QRectF(
|
||||||
|
mapFromScene(
|
||||||
|
qde.attribute("x", "0").toDouble(),
|
||||||
|
qde.attribute("y", "0").toDouble()
|
||||||
|
),
|
||||||
|
QSizeF(
|
||||||
|
diameter,
|
||||||
|
diameter
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PartCircle::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (scene()) {
|
||||||
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||||
|
informations -> updateForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(QGraphicsEllipseItem::itemChange(change, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PartCircle::sceneTopLeft() const {
|
||||||
|
return(mapToScene(rect().topLeft()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PartCircle::sceneCenter() const {
|
||||||
|
return(mapToScene(rect().center()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF PartCircle::boundingRect() const {
|
||||||
|
qreal adjust = 1.5;
|
||||||
|
QRectF r(QGraphicsEllipseItem::boundingRect());
|
||||||
|
r.adjust(-adjust, -adjust, adjust, adjust);
|
||||||
|
return(r);
|
||||||
|
}
|
33
editor/partcircle.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef PART_CIRCLE_H
|
||||||
|
#define PART_CIRCLE_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
class CircleEditor;
|
||||||
|
class PartCircle : public QGraphicsEllipseItem, public CustomElementGraphicPart {
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
PartCircle(QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||||
|
virtual ~PartCircle() {
|
||||||
|
qDebug() << "~PartCircle()";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PartCircle(const PartCircle &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
CircleEditor *informations;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||||
|
virtual const QDomElement toXml(QDomDocument &) const;
|
||||||
|
virtual void fromXml(const QDomElement &);
|
||||||
|
virtual QPointF sceneTopLeft() const;
|
||||||
|
virtual QRectF boundingRect() const;
|
||||||
|
QPointF sceneCenter() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||||
|
};
|
||||||
|
#endif
|
66
editor/partellipse.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "partellipse.h"
|
||||||
|
#include "ellipseeditor.h"
|
||||||
|
|
||||||
|
PartEllipse::PartEllipse(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsEllipseItem(parent, scene), CustomElementGraphicPart() {
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
setAcceptedMouseButtons(Qt::LeftButton);
|
||||||
|
informations = new EllipseEditor(this);
|
||||||
|
style_editor -> appendWidget(informations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartEllipse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
|
||||||
|
applyStylesToQPainter(*painter);
|
||||||
|
QPen t = painter -> pen();
|
||||||
|
if (isSelected()) {
|
||||||
|
t.setColor(Qt::red);
|
||||||
|
painter -> setPen(t);
|
||||||
|
}
|
||||||
|
painter -> drawEllipse(rect());
|
||||||
|
if (isSelected()) {
|
||||||
|
painter -> setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
painter -> setPen((painter -> brush().color() == QColor(Qt::black) && painter -> brush().isOpaque()) ? Qt::yellow : Qt::blue);
|
||||||
|
QPointF center = rect().center();
|
||||||
|
painter -> drawLine(QLineF(center.x() - 2.0, center.y(), center.x() + 2.0, center.y()));
|
||||||
|
painter -> drawLine(QLineF(center.x(), center.y() - 2.0, center.x(), center.y() + 2.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomElement PartEllipse::toXml(QDomDocument &xml_document) const {
|
||||||
|
QDomElement xml_element = xml_document.createElement("ellipse");
|
||||||
|
QPointF top_left(sceneTopLeft());
|
||||||
|
xml_element.setAttribute("x", top_left.x());
|
||||||
|
xml_element.setAttribute("y", top_left.y());
|
||||||
|
xml_element.setAttribute("width", rect().width());
|
||||||
|
xml_element.setAttribute("height", rect().height());
|
||||||
|
stylesToXml(xml_element);
|
||||||
|
return(xml_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartEllipse::fromXml(const QDomElement &qde) {
|
||||||
|
stylesFromXml(qde);
|
||||||
|
setRect(
|
||||||
|
QRectF(
|
||||||
|
mapFromScene(
|
||||||
|
qde.attribute("x", "0").toDouble(),
|
||||||
|
qde.attribute("y", "0").toDouble()
|
||||||
|
),
|
||||||
|
QSizeF(
|
||||||
|
qde.attribute("width", "0").toDouble(),
|
||||||
|
qde.attribute("height", "0").toDouble()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PartEllipse::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (scene()) {
|
||||||
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||||
|
informations -> updateForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(QGraphicsEllipseItem::itemChange(change, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PartEllipse::sceneTopLeft() const {
|
||||||
|
return(mapToScene(rect().topLeft()));
|
||||||
|
}
|
31
editor/partellipse.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef PART_ELLIPSE_H
|
||||||
|
#define PART_ELLIPSE_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
class EllipseEditor;
|
||||||
|
class PartEllipse : public QGraphicsEllipseItem, public CustomElementGraphicPart {
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
PartEllipse(QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||||
|
virtual ~PartEllipse() {
|
||||||
|
qDebug() << "~PartEllipse()";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PartEllipse(const PartEllipse &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
EllipseEditor *informations;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||||
|
virtual const QDomElement toXml(QDomDocument &) const;
|
||||||
|
virtual void fromXml(const QDomElement &);
|
||||||
|
virtual QPointF sceneTopLeft() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||||
|
};
|
||||||
|
#endif
|
143
editor/partline.cpp
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#include "partline.h"
|
||||||
|
#include "lineeditor.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
PartLine::PartLine(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsLineItem(parent, scene), CustomElementGraphicPart() {
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
setAcceptedMouseButtons(Qt::LeftButton);
|
||||||
|
informations = new LineEditor(this);
|
||||||
|
style_editor -> appendWidget(informations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartLine::paint(QPainter *painter, const QStyleOptionGraphicsItem */*q*/, QWidget */*w*/) {
|
||||||
|
applyStylesToQPainter(*painter);
|
||||||
|
QPen t = painter -> pen();
|
||||||
|
if (isSelected()) {
|
||||||
|
t.setColor(Qt::red);
|
||||||
|
painter -> setPen(t);
|
||||||
|
}
|
||||||
|
painter -> setBrush(Qt::NoBrush);
|
||||||
|
painter -> drawLine(line());
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomElement PartLine::toXml(QDomDocument &xml_document) const {
|
||||||
|
QDomElement xml_element = xml_document.createElement("line");
|
||||||
|
QPointF p1(sceneP1());
|
||||||
|
QPointF p2(sceneP2());
|
||||||
|
xml_element.setAttribute("x1", p1.x());
|
||||||
|
xml_element.setAttribute("y1", p1.y());
|
||||||
|
xml_element.setAttribute("x2", p2.x());
|
||||||
|
xml_element.setAttribute("y2", p2.y());
|
||||||
|
stylesToXml(xml_element);
|
||||||
|
return(xml_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartLine::fromXml(const QDomElement &qde) {
|
||||||
|
stylesFromXml(qde);
|
||||||
|
setLine(
|
||||||
|
QLineF(
|
||||||
|
mapFromScene(
|
||||||
|
qde.attribute("x1", "0").toDouble(),
|
||||||
|
qde.attribute("y1", "0").toDouble()
|
||||||
|
),
|
||||||
|
mapFromScene(
|
||||||
|
qde.attribute("x2", "0").toDouble(),
|
||||||
|
qde.attribute("y2", "0").toDouble()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PartLine::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (scene()) {
|
||||||
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||||
|
informations -> updateForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(QGraphicsLineItem::itemChange(change, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PartLine::sceneP1() const {
|
||||||
|
return(mapToScene(line().p1()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPointF PartLine::sceneP2() const {
|
||||||
|
return(mapToScene(line().p2()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
QPainterPath PartLine::shape() const {
|
||||||
|
QList<QPointF> points = fourShapePoints();
|
||||||
|
QPainterPath t;
|
||||||
|
t.setFillRule(Qt::WindingFill);
|
||||||
|
t.moveTo(points.at(0));
|
||||||
|
t.lineTo(points.at(1));
|
||||||
|
t.lineTo(points.at(2));
|
||||||
|
t.lineTo(points.at(3));
|
||||||
|
t.lineTo(points.at(0));
|
||||||
|
return(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
QRectF PartLine::boundingRect() const {
|
||||||
|
QList<QPointF> points = fourShapePoints();
|
||||||
|
qreal min_x = points.first().x();
|
||||||
|
qreal max_x = points.first().x();
|
||||||
|
qreal min_y = points.first().y();
|
||||||
|
qreal max_y = points.first().y();
|
||||||
|
foreach(QPointF p, points) {
|
||||||
|
if (p.x() > max_x) max_x = p.x();
|
||||||
|
if (p.x() < min_x) min_x = p.x();
|
||||||
|
if (p.y() > max_y) max_y = p.y();
|
||||||
|
if (p.y() < min_y) min_y = p.y();
|
||||||
|
}
|
||||||
|
QRectF r;
|
||||||
|
r.setCoords(min_x, min_y, max_x, max_y);
|
||||||
|
return(r);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
@return une liste contenant les deux points de la droite + les 4 points entourant ces deux points
|
||||||
|
*/
|
||||||
|
QList<QPointF> PartLine::fourShapePoints() const {
|
||||||
|
// on a donc A(xa , ya) et B(xb, yb)
|
||||||
|
QPointF a = line().p1();
|
||||||
|
QPointF b = line().p2();
|
||||||
|
|
||||||
|
// on calcule le vecteur AB : (xb-xa, yb-ya)
|
||||||
|
QPointF v_ab = b - a;
|
||||||
|
|
||||||
|
// et la distance AB : racine des coordonnees du vecteur au carre
|
||||||
|
qreal ab = sqrt(pow(v_ab.x(), 2) + pow(v_ab.y(), 2));
|
||||||
|
|
||||||
|
// ensuite on definit le vecteur u(a, b) qui est egal au vecteur AB divise
|
||||||
|
// par sa longueur et multiplie par la longueur de la marge que tu veux
|
||||||
|
// laisser
|
||||||
|
QPointF u = v_ab / ab * 2.0;
|
||||||
|
|
||||||
|
// on définit le vecteur v(-b , a) qui est perpendiculaire à AB
|
||||||
|
QPointF v(-u.y(), u.x());
|
||||||
|
QPointF m = -u + v; // on a le vecteur M = -u + v
|
||||||
|
QPointF n = -u - v; // et le vecteur N=-u-v
|
||||||
|
QPointF h = a + m; // H = A + M
|
||||||
|
QPointF k = a + n; // K = A + N
|
||||||
|
QPointF i = b - n; // I = B - N
|
||||||
|
QPointF j = b - m; // J = B - M
|
||||||
|
|
||||||
|
QList<QPointF> result;
|
||||||
|
result << h << i << j << k;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF PartLine::boundingRect() const {
|
||||||
|
qreal adjust = 1.5;
|
||||||
|
QRectF r(QGraphicsLineItem::boundingRect());
|
||||||
|
r.adjust(-adjust, -adjust, adjust, adjust);
|
||||||
|
return(r);
|
||||||
|
}
|
37
editor/partline.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef PART_LINE_H
|
||||||
|
#define PART_LINE_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
class LineEditor;
|
||||||
|
class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart {
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
PartLine(QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||||
|
virtual ~PartLine() {
|
||||||
|
qDebug() << "~PartLine()";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PartLine(const PartLine &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
LineEditor *informations;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0);
|
||||||
|
virtual const QDomElement toXml(QDomDocument &) const;
|
||||||
|
virtual void fromXml(const QDomElement &);
|
||||||
|
virtual QPointF sceneP1() const;
|
||||||
|
virtual QPointF sceneP2() const;
|
||||||
|
virtual QPainterPath shape() const;
|
||||||
|
virtual QRectF boundingRect() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<QPointF> fourShapePoints() const;
|
||||||
|
};
|
||||||
|
#endif
|
69
editor/partpolygon.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "partpolygon.h"
|
||||||
|
#include "qet.h"
|
||||||
|
#include "polygoneditor.h"
|
||||||
|
PartPolygon::PartPolygon(QGraphicsItem *parent, QGraphicsScene *scene) :
|
||||||
|
QGraphicsPolygonItem(parent, scene),
|
||||||
|
CustomElementGraphicPart(),
|
||||||
|
closed(false)
|
||||||
|
{
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
setAcceptedMouseButtons(Qt::LeftButton);
|
||||||
|
informations = new PolygonEditor(this);
|
||||||
|
style_editor -> appendWidget(informations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartPolygon::fromXml(const QDomElement &qde) {
|
||||||
|
stylesFromXml(qde);
|
||||||
|
int i = 1;
|
||||||
|
while(true) {
|
||||||
|
if (
|
||||||
|
QET::attributeIsAReal(qde, QString("x%1").arg(i)) &&\
|
||||||
|
QET::attributeIsAReal(qde, QString("y%1").arg(i))
|
||||||
|
) ++ i;
|
||||||
|
else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPolygonF temp_polygon;
|
||||||
|
for (int j = 1 ; j < i ; ++ j) {
|
||||||
|
temp_polygon << QPointF(
|
||||||
|
qde.attribute(QString("x%1").arg(j)).toDouble(),
|
||||||
|
qde.attribute(QString("y%1").arg(j)).toDouble()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setPolygon(temp_polygon);
|
||||||
|
|
||||||
|
closed = qde.attribute("closed") != "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomElement PartPolygon::toXml(QDomDocument &xml_document) const {
|
||||||
|
QDomElement xml_element = xml_document.createElement("polygon");
|
||||||
|
int i = 1;
|
||||||
|
foreach(QPointF point, polygon()) {
|
||||||
|
xml_element.setAttribute(QString("x%1").arg(i), point.x());
|
||||||
|
xml_element.setAttribute(QString("y%1").arg(i), point.y());
|
||||||
|
++ i;
|
||||||
|
}
|
||||||
|
if (!closed) xml_element.setAttribute("closed", "false");
|
||||||
|
stylesToXml(xml_element);
|
||||||
|
return(xml_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartPolygon::paint(QPainter *painter, const QStyleOptionGraphicsItem */*q*/, QWidget */*w*/) {
|
||||||
|
applyStylesToQPainter(*painter);
|
||||||
|
QPen t = painter -> pen();
|
||||||
|
if (isSelected()) {
|
||||||
|
t.setColor(Qt::red);
|
||||||
|
painter -> setPen(t);
|
||||||
|
}
|
||||||
|
if (closed) painter -> drawPolygon(polygon());
|
||||||
|
else painter -> drawPolyline(polygon());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PartPolygon::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (scene()) {
|
||||||
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||||
|
informations -> updateForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(QGraphicsPolygonItem::itemChange(change, value));
|
||||||
|
}
|
61
editor/partpolygon.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#ifndef PART_POLYGON_H
|
||||||
|
#define PART_POLYGON_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
class PolygonEditor;
|
||||||
|
class PartPolygon : public QGraphicsPolygonItem, public CustomElementGraphicPart {
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
PartPolygon(QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||||
|
virtual ~PartPolygon() {
|
||||||
|
qDebug() << "~PartPolygon()";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PartPolygon(const PartPolygon &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
bool closed;
|
||||||
|
PolygonEditor *informations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
constructeur
|
||||||
|
paint()
|
||||||
|
widget bidon pour l'edition
|
||||||
|
methode pour poser le polygone :
|
||||||
|
-mousePressEvent = pose un nouveau point
|
||||||
|
-mouseMoveEvent = deplace ce point
|
||||||
|
-mouveReleaseEvent = finalise ce point
|
||||||
|
utiliser QPolygonF ; memoriser le point en cours (tout comme le
|
||||||
|
partploygon en cours) et ne l'ajouter au qpolygonf que lors du
|
||||||
|
mouseReleaseEvent
|
||||||
|
*/
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
void fromXml(const QDomElement &);
|
||||||
|
const QDomElement toXml(QDomDocument &) const;
|
||||||
|
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
|
||||||
|
void setClosed(bool c);
|
||||||
|
bool isClosed() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
Specifie si le polygone doit etre ferme
|
||||||
|
@param c true pour un polygone ferme, false sinon
|
||||||
|
*/
|
||||||
|
inline void PartPolygon::setClosed(bool c) {
|
||||||
|
closed = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Indique si le polygone est ferme
|
||||||
|
@return true si le polygone est ferme, false sinon
|
||||||
|
*/
|
||||||
|
inline bool PartPolygon::isClosed() const {
|
||||||
|
return(closed);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
117
editor/partterminal.cpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#include "partterminal.h"
|
||||||
|
#include "terminal.h"
|
||||||
|
#include "terminaleditor.h"
|
||||||
|
|
||||||
|
PartTerminal::PartTerminal(QGraphicsItem *parent, QGraphicsScene *scene) :
|
||||||
|
CustomElementPart(),
|
||||||
|
QGraphicsItem(parent, scene),
|
||||||
|
_orientation(QET::North)
|
||||||
|
{
|
||||||
|
informations = new TerminalEditor(this);
|
||||||
|
updateSecondPoint();
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
setZValue(100000);
|
||||||
|
}
|
||||||
|
|
||||||
|
PartTerminal::~PartTerminal() {
|
||||||
|
qDebug() << "~PartTerminal()";
|
||||||
|
delete informations;
|
||||||
|
};
|
||||||
|
|
||||||
|
void PartTerminal::fromXml(const QDomElement &xml_elmt) {
|
||||||
|
// lit la position de la borne
|
||||||
|
qreal term_x = 0.0, term_y = 0.0;
|
||||||
|
QET::attributeIsAReal(xml_elmt, "x", &term_x);
|
||||||
|
QET::attributeIsAReal(xml_elmt, "y", &term_y);
|
||||||
|
setPos(QPointF(term_x, term_y));
|
||||||
|
|
||||||
|
// lit l'orientation de la borne
|
||||||
|
_orientation = QET::orientationFromString(xml_elmt.attribute("orientation"));
|
||||||
|
updateSecondPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomElement PartTerminal::toXml(QDomDocument &xml_document) const {
|
||||||
|
QDomElement xml_element = xml_document.createElement("terminal");
|
||||||
|
|
||||||
|
// ecrit la position de la borne
|
||||||
|
xml_element.setAttribute("x", QString("%1").arg(pos().x()));
|
||||||
|
xml_element.setAttribute("y", QString("%1").arg(pos().y()));
|
||||||
|
|
||||||
|
// ecrit l'orientation de la borne
|
||||||
|
xml_element.setAttribute("orientation", orientationToString(_orientation));
|
||||||
|
|
||||||
|
return(xml_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PartTerminal::elementInformations() {
|
||||||
|
return(informations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartTerminal::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) {
|
||||||
|
p -> save();
|
||||||
|
|
||||||
|
// annulation des renderhints
|
||||||
|
p -> setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
p -> setRenderHint(QPainter::TextAntialiasing, false);
|
||||||
|
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
||||||
|
|
||||||
|
QPen t;
|
||||||
|
t.setWidthF(1.0);
|
||||||
|
|
||||||
|
// dessin de la borne en rouge
|
||||||
|
t.setColor(Qt::red);
|
||||||
|
p -> setPen(t);
|
||||||
|
p -> drawLine(QPointF(0.0, 0.0), second_point);
|
||||||
|
|
||||||
|
// dessin du point d'amarrage au conducteur en bleu
|
||||||
|
t.setColor(Terminal::couleur_neutre);
|
||||||
|
p -> setPen(t);
|
||||||
|
p -> setBrush(Terminal::couleur_neutre);
|
||||||
|
p -> drawPoint(QPointF(0.0, 0.0));
|
||||||
|
p -> restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF PartTerminal::boundingRect() const {
|
||||||
|
QPointF p1, p2;
|
||||||
|
if (second_point.x() <= 0.0 && second_point.y() <= 0.0) {
|
||||||
|
p1 = second_point;
|
||||||
|
p2 = QPointF(0.0, 0.0);
|
||||||
|
} else {
|
||||||
|
p1 = QPointF(0.0, 0.0);
|
||||||
|
p2 = second_point;
|
||||||
|
}
|
||||||
|
QRectF br;
|
||||||
|
br.setTopLeft (p1 - QPointF(2.0, 2.0));
|
||||||
|
br.setBottomRight(p2 + QPointF(2.0, 2.0));
|
||||||
|
return(br);
|
||||||
|
}
|
||||||
|
|
||||||
|
QET::Orientation PartTerminal::orientation() const {
|
||||||
|
return(_orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartTerminal::setOrientation(QET::Orientation ori) {
|
||||||
|
prepareGeometryChange();
|
||||||
|
_orientation = ori;
|
||||||
|
updateSecondPoint();
|
||||||
|
informations -> updateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PartTerminal::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (scene()) {
|
||||||
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||||
|
informations -> updateForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(QGraphicsItem::itemChange(change, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartTerminal::updateSecondPoint() {
|
||||||
|
qreal ts = 4.0; // terminal size
|
||||||
|
switch(_orientation) {
|
||||||
|
case QET::North: second_point = QPointF(0.0, ts); break;
|
||||||
|
case QET::East : second_point = QPointF(-ts, 0.0); break;
|
||||||
|
case QET::South: second_point = QPointF(0.0, -ts); break;
|
||||||
|
case QET::West : second_point = QPointF(ts, 0.0); break;
|
||||||
|
}
|
||||||
|
}
|
37
editor/partterminal.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef PART_TERMINAL_H
|
||||||
|
#define PART_TERMINAL_H
|
||||||
|
#include "customelementpart.h"
|
||||||
|
#include "qet.h"
|
||||||
|
#include <QtGui>
|
||||||
|
class TerminalEditor;
|
||||||
|
class PartTerminal : public CustomElementPart, public QGraphicsItem {
|
||||||
|
public:
|
||||||
|
// constructeurs, destructeur
|
||||||
|
PartTerminal(QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||||
|
virtual ~PartTerminal();
|
||||||
|
private:
|
||||||
|
PartTerminal(const PartTerminal &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
QET::Orientation _orientation;
|
||||||
|
QPointF second_point;
|
||||||
|
TerminalEditor *informations;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
virtual void fromXml(const QDomElement &);
|
||||||
|
virtual const QDomElement toXml(QDomDocument &) const;
|
||||||
|
virtual QWidget *elementInformations();
|
||||||
|
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
|
||||||
|
virtual QRectF boundingRect() const;
|
||||||
|
QET::Orientation orientation() const;
|
||||||
|
void setOrientation(QET::Orientation);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateSecondPoint();
|
||||||
|
};
|
||||||
|
#endif
|
104
editor/parttext.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include "parttext.h"
|
||||||
|
#include "texteditor.h"
|
||||||
|
|
||||||
|
PartText::PartText(QGraphicsItem *parent, QGraphicsScene *scene) : QGraphicsTextItem(parent, scene), CustomElementPart(), can_check_changes(true) {
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
setPlainText(tr("T"));
|
||||||
|
infos = new TextEditor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
PartText::~PartText() {
|
||||||
|
qDebug() << "~PartText()";
|
||||||
|
delete infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartText::fromXml(const QDomElement &xml_element) {
|
||||||
|
bool ok;
|
||||||
|
int font_size = xml_element.attribute("size").toInt(&ok);
|
||||||
|
if (!ok || font_size < 1) font_size = 20;
|
||||||
|
|
||||||
|
setFont(QFont(QString("Sans Serif"), font_size));
|
||||||
|
setPlainText(xml_element.attribute("text"));
|
||||||
|
setPos(
|
||||||
|
xml_element.attribute("x").toDouble(),
|
||||||
|
xml_element.attribute("y").toDouble()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QDomElement PartText::toXml(QDomDocument &xml_document) const {
|
||||||
|
QDomElement xml_element = xml_document.createElement("text");
|
||||||
|
xml_element.setAttribute("x", QString("%1").arg(pos().x()));
|
||||||
|
xml_element.setAttribute("y", QString("%1").arg(pos().y()));
|
||||||
|
xml_element.setAttribute("text", toPlainText());
|
||||||
|
xml_element.setAttribute("size", font().pointSize());
|
||||||
|
return(xml_element);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *PartText::elementInformations() {
|
||||||
|
return(infos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Retourne la position du texte, l'origine etant le point en bas a gauche du
|
||||||
|
texte (et pas du cadre)
|
||||||
|
@return la position du texte
|
||||||
|
*/
|
||||||
|
QPointF PartText::pos() const {
|
||||||
|
return(QGraphicsTextItem::pos() + margin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartText::setPos(const QPointF &left_corner_pos) {
|
||||||
|
QGraphicsTextItem::setPos(left_corner_pos - margin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartText::setPos(qreal x, qreal y) {
|
||||||
|
QGraphicsTextItem::setPos(QPointF(x, y) - margin());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return Les coordonnees du point situe en bas a gauche du texte.
|
||||||
|
*/
|
||||||
|
QPointF PartText::margin() const {
|
||||||
|
QFont used_font = font();
|
||||||
|
QFontMetrics qfm(used_font);
|
||||||
|
QPointF margin(
|
||||||
|
(boundingRect().width () - qfm.width(toPlainText())) / 2.0,
|
||||||
|
((boundingRect().height() - used_font.pointSizeF()) / 3.0) + used_font.pointSizeF()
|
||||||
|
);
|
||||||
|
return(margin);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet a l'element texte de redevenir deplacable a la fin de l'edition de texte
|
||||||
|
@param e Le QFocusEvent decrivant la perte de focus
|
||||||
|
*/
|
||||||
|
void PartText::focusOutEvent(QFocusEvent *e) {
|
||||||
|
QGraphicsTextItem::focusOutEvent(e);
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet a l'element texte de devenir editable lorsqu'on double-clique dessus
|
||||||
|
@param e Le QGraphicsSceneMouseEvent qui decrit le double-clic
|
||||||
|
*/
|
||||||
|
void PartText::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e) {
|
||||||
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
|
||||||
|
setTextInteractionFlags(Qt::TextEditorInteraction);
|
||||||
|
QGraphicsTextItem::mouseDoubleClickEvent(e);
|
||||||
|
setFocus(Qt::MouseFocusReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant PartText::itemChange(GraphicsItemChange change, const QVariant &value) {
|
||||||
|
if (scene() && can_check_changes) {
|
||||||
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemSelectedChange) {
|
||||||
|
infos -> updateForm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(QGraphicsTextItem::itemChange(change, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF PartText::boundingRect() const {
|
||||||
|
QRectF r = QGraphicsTextItem::boundingRect();
|
||||||
|
r.adjust(0.0, -2.0, 0.0, 0.0);
|
||||||
|
return(r);
|
||||||
|
}
|
39
editor/parttext.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef PART_TEXT
|
||||||
|
#define PART_TEXT
|
||||||
|
#include <QtGui>
|
||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
class TextEditor;
|
||||||
|
class PartText : public QGraphicsTextItem, public CustomElementPart {
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
PartText(QGraphicsItem * = 0, QGraphicsScene * = 0);
|
||||||
|
virtual ~PartText();
|
||||||
|
|
||||||
|
private:
|
||||||
|
PartText(const PartText &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
TextEditor *infos;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
void fromXml(const QDomElement &);
|
||||||
|
const QDomElement toXml(QDomDocument &) const;
|
||||||
|
QWidget *elementInformations();
|
||||||
|
QPointF pos() const;
|
||||||
|
void setPos(const QPointF &);
|
||||||
|
void setPos(qreal, qreal);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void focusOutEvent(QFocusEvent *);
|
||||||
|
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
|
||||||
|
virtual QVariant itemChange(GraphicsItemChange, const QVariant &);
|
||||||
|
QRectF boundingRect() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool can_check_changes;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPointF margin() const;
|
||||||
|
};
|
||||||
|
#endif
|
89
editor/polygoneditor.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include "polygoneditor.h"
|
||||||
|
#include "partpolygon.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructeur
|
||||||
|
@param p Le polygone a editer
|
||||||
|
@param parent le Widget parent
|
||||||
|
*/
|
||||||
|
PolygonEditor::PolygonEditor(PartPolygon *p, QWidget *parent) :
|
||||||
|
QWidget(parent),
|
||||||
|
points_list(this),
|
||||||
|
close_polygon(tr("Polygone ferm\351"), this)
|
||||||
|
{
|
||||||
|
part = p;
|
||||||
|
// prepare la liste de points
|
||||||
|
points_list.setColumnCount(2);
|
||||||
|
QStringList headers;
|
||||||
|
headers << tr("x") << tr("y");
|
||||||
|
points_list.setHeaderLabels(headers);
|
||||||
|
points_list.setRootIsDecorated(false);
|
||||||
|
updateForm();
|
||||||
|
|
||||||
|
// layout
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout -> addWidget(new QLabel(tr("Points du polygone :")));
|
||||||
|
layout -> addWidget(&points_list);
|
||||||
|
layout -> addWidget(&close_polygon);
|
||||||
|
|
||||||
|
// connexions signaux/slots
|
||||||
|
connect(&close_polygon, SIGNAL(stateChanged(int)), this, SLOT(updatePolygonClosedState()));
|
||||||
|
connect(&points_list, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(validColumn(QTreeWidgetItem *, int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolygonEditor::updatePolygon() {
|
||||||
|
updatePolygonPoints();
|
||||||
|
updatePolygonClosedState();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolygonEditor::updatePolygonPoints() {
|
||||||
|
QVector<QPointF> points = getPointsFromTree();
|
||||||
|
if (points.count() < 2) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this,
|
||||||
|
tr("Erreur"),
|
||||||
|
tr("Le polygone doit comporter au moins deux points.")
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
part -> setPolygon(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolygonEditor::updatePolygonClosedState() {
|
||||||
|
part -> setClosed(close_polygon.isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolygonEditor::updateForm() {
|
||||||
|
while(points_list.takeTopLevelItem(0));
|
||||||
|
foreach(QPointF point, part -> polygon()) {
|
||||||
|
point = part -> mapToScene(point);
|
||||||
|
QStringList qsl;
|
||||||
|
qsl << QString("%1").arg(point.x()) << QString("%1").arg(point.y());
|
||||||
|
QTreeWidgetItem *qtwi = new QTreeWidgetItem(qsl);
|
||||||
|
qtwi -> setFlags(Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable);
|
||||||
|
points_list.addTopLevelItem(qtwi);
|
||||||
|
}
|
||||||
|
close_polygon.setChecked(part -> isClosed());
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<QPointF> PolygonEditor::getPointsFromTree() {
|
||||||
|
QVector<QPointF> points;
|
||||||
|
for(int i = 0 ; i < points_list.topLevelItemCount() ; ++ i) {
|
||||||
|
QTreeWidgetItem *qtwi = points_list.topLevelItem(i);
|
||||||
|
bool x_convert_ok, y_convert_ok;
|
||||||
|
qreal x = qtwi -> text(0).toDouble(&x_convert_ok);
|
||||||
|
qreal y = qtwi -> text(1).toDouble(&y_convert_ok);
|
||||||
|
if (!x_convert_ok || !y_convert_ok) continue;
|
||||||
|
points << part -> mapFromScene(QPointF(x, y));
|
||||||
|
}
|
||||||
|
return(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolygonEditor::validColumn(QTreeWidgetItem *qtwi, int column) {
|
||||||
|
bool convert_ok;
|
||||||
|
qtwi -> text(column).toDouble(&convert_ok);
|
||||||
|
if (convert_ok) {
|
||||||
|
points_list.closePersistentEditor(qtwi, column);
|
||||||
|
updatePolygonPoints();
|
||||||
|
} else points_list.openPersistentEditor(qtwi, column);
|
||||||
|
}
|
35
editor/polygoneditor.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef POLYGON_EDITOR_H
|
||||||
|
#define POLYGON_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class PartPolygon;
|
||||||
|
class PolygonEditor : public QWidget {
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
PolygonEditor(PartPolygon *, QWidget * = 0);
|
||||||
|
~PolygonEditor() {
|
||||||
|
qDebug() << "~PolygonEditor()";
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
PolygonEditor(const PolygonEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
PartPolygon *part;
|
||||||
|
QTreeWidget points_list;
|
||||||
|
QCheckBox close_polygon;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
private:
|
||||||
|
QVector<QPointF> getPointsFromTree();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updatePolygon();
|
||||||
|
void updatePolygonPoints();
|
||||||
|
void updatePolygonClosedState();
|
||||||
|
void updateForm();
|
||||||
|
void validColumn(QTreeWidgetItem *qtwi, int column);
|
||||||
|
};
|
||||||
|
#endif
|
125
editor/qet.cpp
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include "qet.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de convertir une chaine de caracteres ("n", "s", "e" ou "w")
|
||||||
|
en orientation. Si la chaine fait plusieurs caracteres, seul le
|
||||||
|
premier est pris en compte. En cas d'incoherence, QET::North est
|
||||||
|
retourne.
|
||||||
|
@param s Chaine de caractere cense representer une orientation
|
||||||
|
@return l'orientation designee par la chaine de caractere
|
||||||
|
*/
|
||||||
|
QET::Orientation QET::orientationFromString(const QString &s) {
|
||||||
|
QChar c = s[0];
|
||||||
|
if (c == 'e') return(QET::East);
|
||||||
|
else if (c == 's') return(QET::South);
|
||||||
|
else if (c == 'w') return (QET::West);
|
||||||
|
else return(QET::North);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@param o une orientation
|
||||||
|
@return une chaine de caractere representant l'orientation
|
||||||
|
*/
|
||||||
|
QString QET::orientationToString(QET::Orientation o) {
|
||||||
|
QString ret;
|
||||||
|
switch(o) {
|
||||||
|
case QET::North: ret = "n"; break;
|
||||||
|
case QET::East : ret = "e"; break;
|
||||||
|
case QET::South: ret = "s"; break;
|
||||||
|
case QET::West : ret = "w"; break;
|
||||||
|
}
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Indique si deux orientations de Borne sont sur le meme axe (Vertical / Horizontal).
|
||||||
|
@param a La premiere orientation de Borne
|
||||||
|
@param b La seconde orientation de Borne
|
||||||
|
@return Un booleen a true si les deux orientations de bornes sont sur le meme axe
|
||||||
|
*/
|
||||||
|
bool QET::surLeMemeAxe(QET::Orientation a, QET::Orientation b) {
|
||||||
|
if ((a == QET::North || a == QET::South) && (b == QET::North || b == QET::South)) return(true);
|
||||||
|
else if ((a == QET::East || a == QET::West) && (b == QET::East || b == QET::West)) return(true);
|
||||||
|
else return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Indique si une orientation de borne est horizontale (Est / Ouest).
|
||||||
|
@param a L'orientation de borne
|
||||||
|
@return True si l'orientation de borne est horizontale, false sinon
|
||||||
|
*/
|
||||||
|
bool QET::estHorizontale(QET::Orientation a) {
|
||||||
|
return(a == QET::East || a == QET::West);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Indique si une orientation de borne est verticale (Nord / Sud).
|
||||||
|
@param a L'orientation de borne
|
||||||
|
@return True si l'orientation de borne est verticale, false sinon
|
||||||
|
*/
|
||||||
|
bool QET::estVerticale(QET::Orientation a) {
|
||||||
|
return(a == QET::North || a == QET::South);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de connaitre l'orientation suivante apres celle donnee en parametre.
|
||||||
|
Les orientations sont generalement presentees dans l'ordre suivant : Nord,
|
||||||
|
Est, Sud, Ouest.
|
||||||
|
@param o une orientation
|
||||||
|
@return l'orientation suivante
|
||||||
|
*/
|
||||||
|
QET::Orientation QET::nextOrientation(QET::Orientation o) {
|
||||||
|
if (o < 0 || o > 2) return(QET::North);
|
||||||
|
return((QET::Orientation)(o + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de connaitre l'orientation precedant celle donnee en parametre.
|
||||||
|
Les orientations sont generalement presentees dans l'ordre suivant : Nord,
|
||||||
|
Est, Sud, Ouest.
|
||||||
|
@param o une orientation
|
||||||
|
@return l'orientation precedente
|
||||||
|
*/
|
||||||
|
QET::Orientation QET::previousOrientation(QET::Orientation o) {
|
||||||
|
if (o < 0 || o > 3) return(QET::North);
|
||||||
|
if (o == QET::North) return(QET::West);
|
||||||
|
return((QET::Orientation)(o - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir si l'attribut nom_attribut d'un element XML e est bien un
|
||||||
|
entier. Si oui, sa valeur est copiee dans entier.
|
||||||
|
@param e Element XML
|
||||||
|
@param nom_attribut Nom de l'attribut a analyser
|
||||||
|
@param entier Pointeur facultatif vers un entier
|
||||||
|
@return true si l'attribut est bien un entier, false sinon
|
||||||
|
*/
|
||||||
|
bool QET::attributeIsAnInteger(const QDomElement &e, QString nom_attribut, int *entier) {
|
||||||
|
// verifie la presence de l'attribut
|
||||||
|
if (!e.hasAttribute(nom_attribut)) return(false);
|
||||||
|
// verifie la validite de l'attribut
|
||||||
|
bool ok;
|
||||||
|
int tmp = e.attribute(nom_attribut).toInt(&ok);
|
||||||
|
if (!ok) return(false);
|
||||||
|
if (entier != NULL) *entier = tmp;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir si l'attribut nom_attribut d'un element XML e est bien un
|
||||||
|
reel. Si oui, sa valeur est copiee dans reel.
|
||||||
|
@param e Element XML
|
||||||
|
@param nom_attribut Nom de l'attribut a analyser
|
||||||
|
@param reel Pointeur facultatif vers un double
|
||||||
|
@return true si l'attribut est bien un reel, false sinon
|
||||||
|
*/
|
||||||
|
bool QET::attributeIsAReal(const QDomElement &e, QString nom_attribut, double *reel) {
|
||||||
|
// verifie la presence de l'attribut
|
||||||
|
if (!e.hasAttribute(nom_attribut)) return(false);
|
||||||
|
// verifie la validite de l'attribut
|
||||||
|
bool ok;
|
||||||
|
qreal tmp = e.attribute(nom_attribut).toDouble(&ok);
|
||||||
|
if (!ok) return(false);
|
||||||
|
if (reel != NULL) *reel = tmp;
|
||||||
|
return(true);
|
||||||
|
}
|
121
editor/styleeditor.cpp
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#include "styleeditor.h"
|
||||||
|
#include "customelementgraphicpart.h"
|
||||||
|
|
||||||
|
StyleEditor::StyleEditor(CustomElementGraphicPart *p, QWidget *parent) : QWidget(parent), part(p) {
|
||||||
|
// couleur
|
||||||
|
color = new QButtonGroup(this);
|
||||||
|
color -> addButton(black_color = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackColor);
|
||||||
|
color -> addButton(white_color = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteColor);
|
||||||
|
connect(color, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
|
||||||
|
|
||||||
|
// style
|
||||||
|
style = new QButtonGroup(this);
|
||||||
|
style -> addButton(normal_style = new QRadioButton(tr("Normal")), CustomElementGraphicPart::NormalStyle);
|
||||||
|
style -> addButton(dashed_style = new QRadioButton(tr("Pointill\351")), CustomElementGraphicPart::DashedStyle);
|
||||||
|
style -> button(part -> lineStyle()) -> setChecked(true);
|
||||||
|
connect(style, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
|
||||||
|
|
||||||
|
// epaisseur
|
||||||
|
weight = new QButtonGroup(this);
|
||||||
|
weight -> addButton(none_weight = new QRadioButton(tr("Nulle")), CustomElementGraphicPart::NoneWeight);
|
||||||
|
weight -> addButton(thin_weight = new QRadioButton(tr("Fine")), CustomElementGraphicPart::ThinWeight);
|
||||||
|
weight -> addButton(normal_weight = new QRadioButton(tr("Normale")), CustomElementGraphicPart::NormalWeight);
|
||||||
|
connect(weight, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
|
||||||
|
|
||||||
|
// remplissage
|
||||||
|
filling = new QButtonGroup(this);
|
||||||
|
filling -> addButton(no_filling = new QRadioButton(tr("Aucun")), CustomElementGraphicPart::NoneFilling );
|
||||||
|
filling -> addButton(black_filling = new QRadioButton(tr("Noir")), CustomElementGraphicPart::BlackFilling);
|
||||||
|
filling -> addButton(white_filling = new QRadioButton(tr("Blanc")), CustomElementGraphicPart::WhiteFilling);
|
||||||
|
connect(filling, SIGNAL(buttonClicked(int)), this, SLOT(updatePart()));
|
||||||
|
|
||||||
|
// antialiasing
|
||||||
|
antialiasing = new QCheckBox(tr("Antialiasing"));
|
||||||
|
connect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePart()));
|
||||||
|
|
||||||
|
updateForm();
|
||||||
|
|
||||||
|
main_layout = new QVBoxLayout();
|
||||||
|
main_layout -> addWidget(antialiasing);
|
||||||
|
|
||||||
|
main_layout -> addWidget(new QLabel("<u>" + tr("Trait :") + "</u> "));
|
||||||
|
|
||||||
|
QHBoxLayout *color_layout = new QHBoxLayout();
|
||||||
|
color_layout -> addWidget(new QLabel(tr("Couleur : ")));
|
||||||
|
color_layout -> addWidget(black_color);
|
||||||
|
color_layout -> addWidget(white_color);
|
||||||
|
color_layout -> addStretch();
|
||||||
|
main_layout -> addItem(color_layout);
|
||||||
|
|
||||||
|
QHBoxLayout *style_layout = new QHBoxLayout();
|
||||||
|
style_layout -> addWidget(new QLabel(tr("Style : ")));
|
||||||
|
style_layout -> addWidget(normal_style);
|
||||||
|
style_layout -> addWidget(dashed_style);
|
||||||
|
style_layout -> addStretch();
|
||||||
|
main_layout -> addItem(style_layout);
|
||||||
|
|
||||||
|
QHBoxLayout *weight_layout = new QHBoxLayout();
|
||||||
|
weight_layout -> addWidget(new QLabel(tr("\311paisseur : ")));
|
||||||
|
weight_layout -> addWidget(none_weight);
|
||||||
|
weight_layout -> addWidget(thin_weight);
|
||||||
|
weight_layout -> addWidget(normal_weight);
|
||||||
|
weight_layout -> addStretch();
|
||||||
|
main_layout -> addItem(weight_layout);
|
||||||
|
|
||||||
|
main_layout -> addWidget(new QLabel("<u>" + tr("Remplissage :") + "</u> "));
|
||||||
|
|
||||||
|
QHBoxLayout *filling_layout = new QHBoxLayout();
|
||||||
|
filling_layout -> addWidget(no_filling);
|
||||||
|
filling_layout -> addWidget(black_filling);
|
||||||
|
filling_layout -> addWidget(white_filling);
|
||||||
|
filling_layout -> addStretch();
|
||||||
|
main_layout -> addItem(filling_layout);
|
||||||
|
|
||||||
|
main_layout -> addStretch();
|
||||||
|
|
||||||
|
setLayout(main_layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleEditor::~StyleEditor() {
|
||||||
|
qDebug() << "~StyleEditor()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleEditor::updatePart() {
|
||||||
|
// applique l'antialiasing
|
||||||
|
part -> setAntialiased(antialiasing -> isChecked());
|
||||||
|
|
||||||
|
// applique la couleur
|
||||||
|
part -> setColor(static_cast<CEGP::Color>(color -> checkedId()));
|
||||||
|
|
||||||
|
// applique le style
|
||||||
|
part -> setLineStyle(static_cast<CEGP::LineStyle>(style -> checkedId()));
|
||||||
|
|
||||||
|
// applique l'epaisseur
|
||||||
|
part -> setLineWeight(static_cast<CEGP::LineWeight>(weight -> checkedId()));
|
||||||
|
|
||||||
|
// applique le remplissage
|
||||||
|
part -> setFilling(static_cast<CEGP::Filling>(filling -> checkedId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleEditor::updateForm() {
|
||||||
|
// lit l'antialiasing : deconnexion du slot pour eviter l'appel a updatePart()
|
||||||
|
disconnect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePart()));
|
||||||
|
antialiasing -> setChecked(part -> antialiased());
|
||||||
|
connect(antialiasing, SIGNAL(stateChanged(int)), this, SLOT(updatePart()));
|
||||||
|
|
||||||
|
// lit la couleur
|
||||||
|
color -> button(part -> color()) -> setChecked(true);
|
||||||
|
|
||||||
|
// lit le style
|
||||||
|
style -> button(part -> lineStyle()) -> setChecked(true);
|
||||||
|
|
||||||
|
// lit l'epaisseur
|
||||||
|
weight -> button(part -> lineWeight()) -> setChecked(true);
|
||||||
|
|
||||||
|
// lit le remplissage
|
||||||
|
filling -> button(part -> filling()) -> setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StyleEditor::appendWidget(QWidget *w) {
|
||||||
|
main_layout -> insertWidget(7, w);
|
||||||
|
}
|
33
editor/styleeditor.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef STYLE_EDITOR_H
|
||||||
|
#define STYLE_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class CustomElementGraphicPart;
|
||||||
|
class StyleEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
StyleEditor(CustomElementGraphicPart *, QWidget * = 0);
|
||||||
|
virtual ~StyleEditor();
|
||||||
|
|
||||||
|
private:
|
||||||
|
StyleEditor(const StyleEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
CustomElementGraphicPart *part;
|
||||||
|
QVBoxLayout *main_layout;
|
||||||
|
QButtonGroup *color, *style, *weight, *filling;
|
||||||
|
QRadioButton *black_color, *white_color, *normal_style, *dashed_style;
|
||||||
|
QRadioButton *none_weight, *thin_weight, *normal_weight, *no_filling;
|
||||||
|
QRadioButton *black_filling, *white_filling;
|
||||||
|
QCheckBox *antialiasing;
|
||||||
|
|
||||||
|
//methodes
|
||||||
|
public:
|
||||||
|
void appendWidget(QWidget *w);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updatePart();
|
||||||
|
void updateForm();
|
||||||
|
};
|
||||||
|
#endif
|
67
editor/terminaleditor.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "terminaleditor.h"
|
||||||
|
#include "partterminal.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructeur
|
||||||
|
@param term Borne a editer
|
||||||
|
@param parent QWidget parent de ce widget
|
||||||
|
*/
|
||||||
|
TerminalEditor::TerminalEditor(PartTerminal *term, QWidget *parent) : QWidget(parent) {
|
||||||
|
part = term;
|
||||||
|
|
||||||
|
qle_x = new QLineEdit();
|
||||||
|
qle_y = new QLineEdit();
|
||||||
|
|
||||||
|
orientation = new QComboBox();
|
||||||
|
orientation -> addItem(QIcon(":/ico/north.png"), tr("Nord"), QET::North);
|
||||||
|
orientation -> addItem(QIcon(":/ico/east.png"), tr("Est"), QET::East);
|
||||||
|
orientation -> addItem(QIcon(":/ico/south.png"), tr("Sud"), QET::South);
|
||||||
|
orientation -> addItem(QIcon(":/ico/west.png"), tr("Ouest"), QET::West);
|
||||||
|
|
||||||
|
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||||
|
main_layout -> addWidget(new QLabel(tr("Postion : ")));
|
||||||
|
|
||||||
|
QHBoxLayout *position = new QHBoxLayout();
|
||||||
|
position -> addWidget(new QLabel(tr("x : ")));
|
||||||
|
position -> addWidget(qle_x );
|
||||||
|
position -> addWidget(new QLabel(tr("y : ")));
|
||||||
|
position -> addWidget(qle_y );
|
||||||
|
main_layout -> addLayout(position);
|
||||||
|
|
||||||
|
QHBoxLayout *ori = new QHBoxLayout();
|
||||||
|
ori -> addWidget(new QLabel(tr("Orientation : ")));
|
||||||
|
ori -> addWidget(orientation );
|
||||||
|
main_layout -> addLayout(ori);
|
||||||
|
main_layout -> addStretch();
|
||||||
|
setLayout(main_layout);
|
||||||
|
|
||||||
|
connect(qle_x, SIGNAL(textEdited(const QString &)), this, SLOT(updateTerminal()));
|
||||||
|
connect(qle_y, SIGNAL(textEdited(const QString &)), this, SLOT(updateTerminal()));
|
||||||
|
connect(orientation, SIGNAL(activated(int)), this, SLOT(updateTerminal()));
|
||||||
|
|
||||||
|
updateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destructeur
|
||||||
|
*/
|
||||||
|
TerminalEditor::~TerminalEditor() {
|
||||||
|
qDebug() << "~TerminalEditor()";
|
||||||
|
};
|
||||||
|
|
||||||
|
void TerminalEditor::updateTerminal() {
|
||||||
|
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
|
||||||
|
part -> setOrientation(
|
||||||
|
static_cast<QET::Orientation>(
|
||||||
|
orientation -> itemData(
|
||||||
|
orientation -> currentIndex()
|
||||||
|
).toInt()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TerminalEditor::updateForm() {
|
||||||
|
qle_x -> setText(QString("%1").arg(part -> pos().x()));
|
||||||
|
qle_y -> setText(QString("%1").arg(part -> pos().y()));
|
||||||
|
orientation -> setCurrentIndex(static_cast<int>(part -> orientation()));
|
||||||
|
}
|
30
editor/terminaleditor.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef TERMINAL_EDITOR_H
|
||||||
|
#define TERMINAL_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class PartTerminal;
|
||||||
|
/**
|
||||||
|
Cette classe represente un editeur de borne.
|
||||||
|
Elle permet d'editer a travers une interface graphique les
|
||||||
|
proprietes d'une borne d'element.
|
||||||
|
*/
|
||||||
|
class TerminalEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
// Constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
TerminalEditor(PartTerminal *, QWidget * = 0);
|
||||||
|
virtual ~TerminalEditor();
|
||||||
|
private:
|
||||||
|
TerminalEditor(const TerminalEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
PartTerminal *part;
|
||||||
|
QLineEdit *qle_x, *qle_y;
|
||||||
|
QComboBox *orientation;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public slots:
|
||||||
|
void updateTerminal();
|
||||||
|
void updateForm();
|
||||||
|
};
|
||||||
|
#endif
|
68
editor/texteditor.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#include "texteditor.h"
|
||||||
|
#include "parttext.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
Constructeur
|
||||||
|
@param term Champ de texte a editer
|
||||||
|
@param parent QWidget parent de ce widget
|
||||||
|
*/
|
||||||
|
TextEditor::TextEditor(PartText *text, QWidget *parent) : QWidget(parent) {
|
||||||
|
part = text;
|
||||||
|
|
||||||
|
qle_x = new QLineEdit();
|
||||||
|
qle_y = new QLineEdit();
|
||||||
|
qle_text = new QLineEdit();
|
||||||
|
font_size = new QSpinBox();
|
||||||
|
font_size -> setRange(0, 144);
|
||||||
|
|
||||||
|
QVBoxLayout *main_layout = new QVBoxLayout();
|
||||||
|
main_layout -> addWidget(new QLabel(tr("Postion : ")));
|
||||||
|
|
||||||
|
QHBoxLayout *position = new QHBoxLayout();
|
||||||
|
position -> addWidget(new QLabel(tr("x : ")));
|
||||||
|
position -> addWidget(qle_x );
|
||||||
|
position -> addWidget(new QLabel(tr("y : ")));
|
||||||
|
position -> addWidget(qle_y );
|
||||||
|
main_layout -> addLayout(position);
|
||||||
|
|
||||||
|
QHBoxLayout *fs = new QHBoxLayout();
|
||||||
|
fs -> addWidget(new QLabel(tr("Taille : ")));
|
||||||
|
fs -> addWidget(font_size);
|
||||||
|
main_layout -> addLayout(fs);
|
||||||
|
|
||||||
|
QHBoxLayout *t = new QHBoxLayout();
|
||||||
|
t -> addWidget(new QLabel(tr("Texte : ")));
|
||||||
|
t -> addWidget(qle_text);
|
||||||
|
main_layout -> addLayout(t);
|
||||||
|
main_layout -> addStretch();
|
||||||
|
setLayout(main_layout);
|
||||||
|
|
||||||
|
connect(qle_x, SIGNAL(textEdited(const QString &)), this, SLOT(updateText()));
|
||||||
|
connect(qle_y, SIGNAL(textEdited(const QString &)), this, SLOT(updateText()));
|
||||||
|
connect(qle_text, SIGNAL(textEdited(const QString &)), this, SLOT(updateText()));
|
||||||
|
connect(font_size, SIGNAL(valueChanged(int)), this, SLOT(updateText()));
|
||||||
|
|
||||||
|
//updateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Destructeur
|
||||||
|
*/
|
||||||
|
TextEditor::~TextEditor() {
|
||||||
|
qDebug() << "~TextEditor()";
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditor::updateText() {
|
||||||
|
part -> can_check_changes = false;
|
||||||
|
part -> setFont(QFont(part -> font().family(), font_size -> value()));
|
||||||
|
part -> setPlainText(qle_text -> text());
|
||||||
|
part -> setPos(qle_x -> text().toDouble(), qle_y -> text().toDouble());
|
||||||
|
part -> can_check_changes = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditor::updateForm() {
|
||||||
|
qle_x -> setText(QString("%1").arg(part -> pos().x()));
|
||||||
|
qle_y -> setText(QString("%1").arg(part -> pos().y()));
|
||||||
|
qle_text -> setText(part -> toPlainText());
|
||||||
|
font_size -> setValue(part -> font().pointSize());
|
||||||
|
}
|
30
editor/texteditor.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef TEXT_EDITOR_H
|
||||||
|
#define TEXT_EDITOR_H
|
||||||
|
#include <QtGui>
|
||||||
|
class PartText;
|
||||||
|
/**
|
||||||
|
Cette classe represente un editeur de champ de texte non editable
|
||||||
|
Elle permet d'editer a travers une interface graphique les
|
||||||
|
proprietes d'un champ de texte non editable.
|
||||||
|
*/
|
||||||
|
class TextEditor : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
// Constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
TextEditor(PartText *, QWidget * = 0);
|
||||||
|
virtual ~TextEditor();
|
||||||
|
private:
|
||||||
|
TextEditor(const TextEditor &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
PartText *part;
|
||||||
|
QLineEdit *qle_x, *qle_y, *qle_text;
|
||||||
|
QSpinBox *font_size;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public slots:
|
||||||
|
void updateText();
|
||||||
|
void updateForm();
|
||||||
|
};
|
||||||
|
#endif
|
14
element.cpp
@ -123,14 +123,14 @@ QVariant Element::itemChange(GraphicsItemChange change, const QVariant &value) {
|
|||||||
@param o la nouvelle orientation de l'objet
|
@param o la nouvelle orientation de l'objet
|
||||||
@return true si l'orientation a pu etre appliquee, false sinon
|
@return true si l'orientation a pu etre appliquee, false sinon
|
||||||
*/
|
*/
|
||||||
bool Element::setOrientation(Terminal::Orientation o) {
|
bool Element::setOrientation(QET::Orientation o) {
|
||||||
// verifie que l'orientation demandee est acceptee
|
// verifie que l'orientation demandee est acceptee
|
||||||
if (!acceptOrientation(o)) return(false);
|
if (!ori.accept(o)) return(false);
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
// rotation en consequence et rafraichissement de l'element graphique
|
// rotation en consequence et rafraichissement de l'element graphique
|
||||||
qreal rotation_value = 90.0 * (o - ori);
|
qreal rotation_value = 90.0 * (o - ori.current());
|
||||||
rotate(rotation_value);
|
rotate(rotation_value);
|
||||||
ori = o;
|
ori.setCurrent(o);
|
||||||
update();
|
update();
|
||||||
foreach(QGraphicsItem *qgi, children()) {
|
foreach(QGraphicsItem *qgi, children()) {
|
||||||
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) p -> updateConducer();
|
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) p -> updateConducer();
|
||||||
@ -353,8 +353,8 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
|
|||||||
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
|
||||||
bool conv_ok;
|
bool conv_ok;
|
||||||
int read_ori = e.attribute("orientation").toInt(&conv_ok);
|
int read_ori = e.attribute("orientation").toInt(&conv_ok);
|
||||||
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = defaultOrientation();
|
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
|
||||||
setOrientation((Terminal::Orientation)read_ori);
|
setOrientation((QET::Orientation)read_ori);
|
||||||
setSelected(e.attribute("selected") == "selected");
|
setSelected(e.attribute("selected") == "selected");
|
||||||
|
|
||||||
return(true);
|
return(true);
|
||||||
@ -380,7 +380,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
|
|||||||
element.setAttribute("x", pos().x());
|
element.setAttribute("x", pos().x());
|
||||||
element.setAttribute("y", pos().y());
|
element.setAttribute("y", pos().y());
|
||||||
if (isSelected()) element.setAttribute("selected", "selected");
|
if (isSelected()) element.setAttribute("selected", "selected");
|
||||||
element.setAttribute("orientation", QString("%1").arg(orientation()));
|
element.setAttribute("orientation", QString("%1").arg(ori.current()));
|
||||||
|
|
||||||
/* recupere le premier id a utiliser pour les bornes de cet element */
|
/* recupere le premier id a utiliser pour les bornes de cet element */
|
||||||
int id_terminal = 0;
|
int id_terminal = 0;
|
||||||
|
97
element.h
@ -2,6 +2,7 @@
|
|||||||
#define ELEMENT_H
|
#define ELEMENT_H
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
#include "orientationset.h"
|
||||||
/**
|
/**
|
||||||
Cette classe abstraite represente un element electrique.
|
Cette classe abstraite represente un element electrique.
|
||||||
*/
|
*/
|
||||||
@ -21,12 +22,7 @@ class Element : public QGraphicsItem {
|
|||||||
enum { Type = UserType + 1000 };
|
enum { Type = UserType + 1000 };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ori_n;
|
OrientationSet ori;
|
||||||
bool ori_s;
|
|
||||||
bool ori_e;
|
|
||||||
bool ori_w;
|
|
||||||
Terminal::Orientation ori_d;
|
|
||||||
Terminal::Orientation ori;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSize dimensions;
|
QSize dimensions;
|
||||||
@ -74,12 +70,8 @@ class Element : public QGraphicsItem {
|
|||||||
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int>&) const;
|
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int>&) const;
|
||||||
|
|
||||||
// methodes d'acces aux possibilites d'orientation
|
// methodes d'acces aux possibilites d'orientation
|
||||||
Terminal::Orientation orientation() const;
|
bool setOrientation(QET::Orientation o);
|
||||||
Terminal::Orientation defaultOrientation() const;
|
const OrientationSet &orientation() const;
|
||||||
bool acceptOrientation(Terminal::Orientation o) const;
|
|
||||||
Terminal::Orientation nextAcceptableOrientation() const;
|
|
||||||
Terminal::Orientation previousAcceptableOrientation() const;
|
|
||||||
bool setOrientation(Terminal::Orientation o);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
|
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
|
||||||
@ -89,8 +81,6 @@ class Element : public QGraphicsItem {
|
|||||||
bool peut_relier_ses_propres_terminals;
|
bool peut_relier_ses_propres_terminals;
|
||||||
void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
|
void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
|
||||||
void updatePixmap();
|
void updatePixmap();
|
||||||
Terminal::Orientation nextOrientation(Terminal::Orientation o) const;
|
|
||||||
Terminal::Orientation previousOrientation(Terminal::Orientation o) const;
|
|
||||||
static QList<QDomElement> findInDomElement(QDomElement, QString, QString);
|
static QList<QDomElement> findInDomElement(QDomElement, QString, QString);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,85 +107,8 @@ inline void Element::setConnexionsInternesAcceptees(bool cia) {
|
|||||||
Permet de connaitre l'orientation actuelle de l'element
|
Permet de connaitre l'orientation actuelle de l'element
|
||||||
@return L'orientation actuelle de l'element
|
@return L'orientation actuelle de l'element
|
||||||
*/
|
*/
|
||||||
inline Terminal::Orientation Element::orientation() const {
|
inline const OrientationSet & Element::orientation() const {
|
||||||
return(ori);
|
return(ori);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de savoir si l'element peut etre positionne dans une orientation
|
|
||||||
donnee.
|
|
||||||
@param o L'orientation en question
|
|
||||||
@return true si l'orientation est utilisable, false sinon
|
|
||||||
*/
|
|
||||||
inline bool Element::acceptOrientation(Terminal::Orientation o) const {
|
|
||||||
switch(o) {
|
|
||||||
case Terminal::Nord: return(ori_n);
|
|
||||||
case Terminal::Est: return(ori_e);
|
|
||||||
case Terminal::Sud: return(ori_s);
|
|
||||||
case Terminal::Ouest: return(ori_w);
|
|
||||||
default: return(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de connaitre l'orientation par defaut de l'element
|
|
||||||
@return l'orientation par defaut de l'element
|
|
||||||
*/
|
|
||||||
inline Terminal::Orientation Element::defaultOrientation() const {
|
|
||||||
return(ori_d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de connaitre la prochaine orientation autorisee pour cet element
|
|
||||||
@return la prochaine orientation autorisee pour cet element
|
|
||||||
*/
|
|
||||||
inline Terminal::Orientation Element::nextAcceptableOrientation() const {
|
|
||||||
Terminal::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(Terminal::Nord);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de connaitre la precedente orientation autorisee pour cet element
|
|
||||||
@return la precedente orientation autorisee pour cet element
|
|
||||||
*/
|
|
||||||
inline Terminal::Orientation Element::previousAcceptableOrientation() const {
|
|
||||||
Terminal::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(Terminal::Nord);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de connaitre l'orientation suivante apres celle donnee en parametre.
|
|
||||||
Les orientations sont generalement presentees dans l'ordre suivant : Nord,
|
|
||||||
Est, Sud, Ouest.
|
|
||||||
@param o une orientation
|
|
||||||
@return l'orientation suivante
|
|
||||||
*/
|
|
||||||
inline Terminal::Orientation Element::nextOrientation(Terminal::Orientation o) const {
|
|
||||||
if (o < 0 || o > 2) return(Terminal::Nord);
|
|
||||||
return((Terminal::Orientation)(o + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
Permet de connaitre l'orientation precedant celle donnee en parametre.
|
|
||||||
Les orientations sont generalement presentees dans l'ordre suivant : Nord,
|
|
||||||
Est, Sud, Ouest.
|
|
||||||
@param o une orientation
|
|
||||||
@return l'orientation precedente
|
|
||||||
*/
|
|
||||||
inline Terminal::Orientation Element::previousOrientation(Terminal::Orientation o) const {
|
|
||||||
if (o < 0 || o > 3) return(Terminal::Nord);
|
|
||||||
if (o == Terminal::Nord) return(Terminal::Ouest);
|
|
||||||
return((Terminal::Orientation)(o - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -135,3 +135,20 @@ bool ElementsCategory::remove() const {
|
|||||||
return(rmdir(absolutePath()));
|
return(rmdir(absolutePath()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
@return true s'il est possible d'ecrire le fichier qet_directory dans la
|
||||||
|
categorie
|
||||||
|
*/
|
||||||
|
bool ElementsCategory::isWritable() const {
|
||||||
|
// informations sur le dossier de la categorie
|
||||||
|
QFileInfo category(canonicalPath());
|
||||||
|
QFileInfo qet_directory(canonicalPath() + "/.qet_directory");
|
||||||
|
/*
|
||||||
|
soit .qet_directory n'existe pas et le dossier est accessible en ecriture,
|
||||||
|
soit .qet_directory existe et est accessible en ecriture
|
||||||
|
*/
|
||||||
|
return(
|
||||||
|
(!qet_directory.exists() && category.isWritable()) ||\
|
||||||
|
(qet_directory.exists() && qet_directory.isWritable())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -28,6 +28,7 @@ class ElementsCategory : public QDir {
|
|||||||
void addName(const QString &, const QString &);
|
void addName(const QString &, const QString &);
|
||||||
bool write() const;
|
bool write() const;
|
||||||
bool remove() const;
|
bool remove() const;
|
||||||
|
bool isWritable() const;
|
||||||
//bool move(const QString &new_parent);
|
//bool move(const QString &new_parent);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -29,6 +29,16 @@ ElementsCategoryEditor::ElementsCategoryEditor(const QString &category_path, boo
|
|||||||
names_list -> setNames(cat_names);
|
names_list -> setNames(cat_names);
|
||||||
//names_list -> openPersistentEditor(qtwi, 1);
|
//names_list -> openPersistentEditor(qtwi, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gestion de la lecture seule
|
||||||
|
if (!category -> isWritable()) {
|
||||||
|
QMessageBox::warning(
|
||||||
|
this,
|
||||||
|
tr("\311dition en lecture seule"),
|
||||||
|
tr("Vous n'avez pas les privil\350ges n\351cessaires pour modifier cette cat\351gorie. Elle sera donc ouverte en lecture seule.")
|
||||||
|
);
|
||||||
|
names_list -> setReadOnly(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +70,8 @@ void ElementsCategoryEditor::buildDialog() {
|
|||||||
categorie
|
categorie
|
||||||
*/
|
*/
|
||||||
void ElementsCategoryEditor::acceptCreation() {
|
void ElementsCategoryEditor::acceptCreation() {
|
||||||
|
if (!category -> isWritable()) QDialog::accept();
|
||||||
|
|
||||||
// il doit y avoir au moins un nom
|
// il doit y avoir au moins un nom
|
||||||
if (!names_list -> checkOneName()) return;
|
if (!names_list -> checkOneName()) return;
|
||||||
|
|
||||||
@ -83,6 +95,8 @@ void ElementsCategoryEditor::acceptCreation() {
|
|||||||
categorie
|
categorie
|
||||||
*/
|
*/
|
||||||
void ElementsCategoryEditor::acceptUpdate() {
|
void ElementsCategoryEditor::acceptUpdate() {
|
||||||
|
if (!category -> isWritable()) QDialog::accept();
|
||||||
|
|
||||||
// il doit y avoir au moins un nom
|
// il doit y avoir au moins un nom
|
||||||
if (!names_list -> checkOneName()) return;
|
if (!names_list -> checkOneName()) return;
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "elementspanel.h"
|
#include "elementspanel.h"
|
||||||
#include "customelement.h"
|
|
||||||
#include "elementscategory.h"
|
#include "elementscategory.h"
|
||||||
|
#include "elementscategoryeditor.h"
|
||||||
|
#include "customelement.h"
|
||||||
|
#include "customelementeditor.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructeur
|
Constructeur
|
||||||
@ -33,6 +35,9 @@ ElementsPanel::ElementsPanel(QWidget *parent) : QTreeWidget(parent) {
|
|||||||
qp.setColor(QPalette::Highlight, QColor("#678db2"));
|
qp.setColor(QPalette::Highlight, QColor("#678db2"));
|
||||||
qp.setColor(QPalette::HighlightedText, Qt::white);
|
qp.setColor(QPalette::HighlightedText, Qt::white);
|
||||||
setPalette(qp);
|
setPalette(qp);
|
||||||
|
|
||||||
|
// double-cliquer sur un element permet de l'editer
|
||||||
|
connect(this, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(slot_doubleClick(QTreeWidgetItem *, int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,6 +119,7 @@ void ElementsPanel::addDir(QTreeWidgetItem *qtwi_parent, QString adr_dossier, QS
|
|||||||
t.setColorAt(1, QColor("#ffffff"));
|
t.setColorAt(1, QColor("#ffffff"));
|
||||||
qtwi_dossier -> setBackground(0, QBrush(t));
|
qtwi_dossier -> setBackground(0, QBrush(t));
|
||||||
qtwi_dossier -> setExpanded(true);
|
qtwi_dossier -> setExpanded(true);
|
||||||
|
qtwi_dossier -> setData(0, 42, adr_dossier);
|
||||||
|
|
||||||
// ajout des sous-categories / sous-dossiers
|
// ajout des sous-categories / sous-dossiers
|
||||||
QStringList dossiers = category.entryList(QStringList(), QDir::AllDirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDir::Name);
|
QStringList dossiers = category.entryList(QStringList(), QDir::AllDirs | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDir::Name);
|
||||||
@ -160,3 +166,25 @@ void ElementsPanel::reload() {
|
|||||||
// chargement des elements de la collection utilisateur
|
// chargement des elements de la collection utilisateur
|
||||||
addDir(invisibleRootItem(), QETApp::customElementsDir(), tr("Collection utilisateur"));
|
addDir(invisibleRootItem(), QETApp::customElementsDir(), tr("Collection utilisateur"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ElementsPanel::slot_doubleClick(QTreeWidgetItem *qtwi, int) {
|
||||||
|
// recupere le fichier ou le dossier correspondant au QTreeWidgetItem
|
||||||
|
QString filename = qtwi -> data(0, 42).toString();
|
||||||
|
|
||||||
|
// le fichier doit exister
|
||||||
|
QFileInfo infos_file(filename);
|
||||||
|
if (!infos_file.exists()) return;
|
||||||
|
|
||||||
|
|
||||||
|
if (infos_file.isFile()) {
|
||||||
|
// il s'agit d'un element
|
||||||
|
CustomElementEditor *cee = new CustomElementEditor();
|
||||||
|
cee -> fromFile(filename);
|
||||||
|
cee -> show();
|
||||||
|
} else if (infos_file.isDir()) {
|
||||||
|
// il s'agit d'une categorie
|
||||||
|
ElementsCategory c(filename);
|
||||||
|
ElementsCategoryEditor ece(filename, true);
|
||||||
|
if (ece.exec() == QDialog::Accepted) reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ class ElementsPanel : public QTreeWidget {
|
|||||||
void addDir(QTreeWidgetItem *, QString, QString = QString());
|
void addDir(QTreeWidgetItem *, QString, QString = QString());
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void slot_doubleClick(QTreeWidgetItem *, int);
|
||||||
void dragMoveEvent(QDragMoveEvent *);
|
void dragMoveEvent(QDragMoveEvent *);
|
||||||
void dropEvent(QDropEvent *);
|
void dropEvent(QDropEvent *);
|
||||||
void startDrag(Qt::DropActions);
|
void startDrag(Qt::DropActions);
|
||||||
|
@ -35,6 +35,6 @@ ElementsPanelWidget::~ElementsPanelWidget() {
|
|||||||
Appelle l'assistant de creation de nouvel element
|
Appelle l'assistant de creation de nouvel element
|
||||||
*/
|
*/
|
||||||
void ElementsPanelWidget::newElement() {
|
void ElementsPanelWidget::newElement() {
|
||||||
NewElementWizard *new_element_wizard = new NewElementWizard();
|
NewElementWizard new_element_wizard;
|
||||||
new_element_wizard -> exec();
|
new_element_wizard.exec();
|
||||||
}
|
}
|
||||||
|
BIN
ico/add_col.png
Executable file
After Width: | Height: | Size: 513 B |
BIN
ico/allowed.png
Executable file
After Width: | Height: | Size: 537 B |
BIN
ico/arc.png
Normal file
After Width: | Height: | Size: 277 B |
BIN
ico/circle.png
Normal file
After Width: | Height: | Size: 497 B |
BIN
ico/east.png
Normal file
After Width: | Height: | Size: 165 B |
BIN
ico/ellipse.png
Normal file
After Width: | Height: | Size: 737 B |
BIN
ico/forbidden.png
Executable file
After Width: | Height: | Size: 1018 B |
BIN
ico/line.png
Normal file
After Width: | Height: | Size: 282 B |
BIN
ico/north.png
Normal file
After Width: | Height: | Size: 163 B |
BIN
ico/orientations.png
Normal file
After Width: | Height: | Size: 192 B |
BIN
ico/polygon.png
Normal file
After Width: | Height: | Size: 589 B |
BIN
ico/remove_col.png
Executable file
After Width: | Height: | Size: 351 B |
BIN
ico/south.png
Normal file
After Width: | Height: | Size: 162 B |
BIN
ico/terminal.png
Normal file
After Width: | Height: | Size: 165 B |
BIN
ico/text.png
Normal file
After Width: | Height: | Size: 808 B |
BIN
ico/textfield.png
Normal file
After Width: | Height: | Size: 982 B |
BIN
ico/west.png
Normal file
After Width: | Height: | Size: 167 B |
@ -4,7 +4,7 @@
|
|||||||
Constructeur
|
Constructeur
|
||||||
@param parent QWidget parent de la liste de noms
|
@param parent QWidget parent de la liste de noms
|
||||||
*/
|
*/
|
||||||
NamesListWidget::NamesListWidget(QWidget *parent) : QWidget(parent) {
|
NamesListWidget::NamesListWidget(QWidget *parent) : QWidget(parent), read_only(false) {
|
||||||
QVBoxLayout *names_list_layout = new QVBoxLayout();
|
QVBoxLayout *names_list_layout = new QVBoxLayout();
|
||||||
setLayout(names_list_layout);
|
setLayout(names_list_layout);
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ NamesListWidget::~NamesListWidget() {
|
|||||||
*/
|
*/
|
||||||
void NamesListWidget::addLine() {
|
void NamesListWidget::addLine() {
|
||||||
clean();
|
clean();
|
||||||
|
if (read_only) return;
|
||||||
QTreeWidgetItem *qtwi = new QTreeWidgetItem();
|
QTreeWidgetItem *qtwi = new QTreeWidgetItem();
|
||||||
qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||||
tree_names -> addTopLevelItem(qtwi);
|
tree_names -> addTopLevelItem(qtwi);
|
||||||
@ -45,8 +46,8 @@ bool NamesListWidget::checkOneName() {
|
|||||||
if (!hash_names.count()) {
|
if (!hash_names.count()) {
|
||||||
QMessageBox::critical(
|
QMessageBox::critical(
|
||||||
this,
|
this,
|
||||||
tr("La cat\351gorie doit avoir au moins un nom."),
|
tr("Il doit y avoir au moins un nom."),
|
||||||
tr("Vous devez entrer au moins un nom pour la cat\351gorie.")
|
tr("Vous devez entrer au moins un nom.")
|
||||||
);
|
);
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
@ -62,7 +63,7 @@ void NamesListWidget::updateHash() {
|
|||||||
for (int i = 0 ; i < names_count ; ++ i) {
|
for (int i = 0 ; i < names_count ; ++ i) {
|
||||||
QString lang = tree_names -> topLevelItem(i) -> text(0);
|
QString lang = tree_names -> topLevelItem(i) -> text(0);
|
||||||
QString value = tree_names -> topLevelItem(i) -> text(1);
|
QString value = tree_names -> topLevelItem(i) -> text(1);
|
||||||
hash_names.addName(lang, value);
|
if (lang != "" && value != "") hash_names.addName(lang, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,7 +96,25 @@ void NamesListWidget::setNames(const NamesList &provided_names) {
|
|||||||
QStringList values;
|
QStringList values;
|
||||||
values << lang << value;
|
values << lang << value;
|
||||||
QTreeWidgetItem *qtwi = new QTreeWidgetItem(values);
|
QTreeWidgetItem *qtwi = new QTreeWidgetItem(values);
|
||||||
qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
if (!read_only) qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||||
tree_names -> addTopLevelItem(qtwi);
|
tree_names -> addTopLevelItem(qtwi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NamesListWidget::check() {
|
||||||
|
if (checkOneName()) emit(inputChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void NamesListWidget::setReadOnly(bool ro) {
|
||||||
|
read_only = ro;
|
||||||
|
int names_count = tree_names -> topLevelItemCount() - 1;
|
||||||
|
for (int i = names_count ; i >= 0 ; -- i) {
|
||||||
|
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
|
if (!read_only) flags |= Qt::ItemIsEditable;
|
||||||
|
tree_names -> topLevelItem(i) -> setFlags(flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NamesListWidget::isReadOnly() const {
|
||||||
|
return(read_only);
|
||||||
|
}
|
||||||
|
@ -22,12 +22,15 @@ class NamesListWidget : public QWidget {
|
|||||||
QTreeWidget *tree_names;
|
QTreeWidget *tree_names;
|
||||||
QPushButton *button_add_line;
|
QPushButton *button_add_line;
|
||||||
NamesList hash_names;
|
NamesList hash_names;
|
||||||
|
bool read_only;
|
||||||
|
|
||||||
// methodes
|
// methodes
|
||||||
public:
|
public:
|
||||||
bool checkOneName();
|
bool checkOneName();
|
||||||
NamesList names();
|
NamesList names();
|
||||||
void setNames(const NamesList &);
|
void setNames(const NamesList &);
|
||||||
|
void setReadOnly(bool);
|
||||||
|
bool isReadOnly() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void clean();
|
void clean();
|
||||||
@ -35,5 +38,9 @@ class NamesListWidget : public QWidget {
|
|||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addLine();
|
void addLine();
|
||||||
|
void check();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void inputChecked();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
#include "elementscategorieswidget.h"
|
#include "elementscategorieswidget.h"
|
||||||
#include "elementscategorieslist.h"
|
#include "elementscategorieslist.h"
|
||||||
#include "nameslistwidget.h"
|
#include "nameslistwidget.h"
|
||||||
|
#include "orientationsetwidget.h"
|
||||||
#include "diagram.h"
|
#include "diagram.h"
|
||||||
#include "element.h"
|
#include "element.h"
|
||||||
|
#include "customelementeditor.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructeur
|
Constructeur
|
||||||
@ -76,6 +78,7 @@ void NewElementWizard::previous() {
|
|||||||
case Names:
|
case Names:
|
||||||
current_state = Filename;
|
current_state = Filename;
|
||||||
step2 -> show();
|
step2 -> show();
|
||||||
|
qle_filename -> setFocus();
|
||||||
step3 -> hide();
|
step3 -> hide();
|
||||||
break;
|
break;
|
||||||
case Dimensions:
|
case Dimensions:
|
||||||
@ -102,6 +105,7 @@ void NewElementWizard::next() {
|
|||||||
current_state = Filename;
|
current_state = Filename;
|
||||||
step1 -> hide();
|
step1 -> hide();
|
||||||
step2 -> show();
|
step2 -> show();
|
||||||
|
qle_filename -> setFocus();
|
||||||
button_previous -> setEnabled(true);
|
button_previous -> setEnabled(true);
|
||||||
break;
|
break;
|
||||||
case Filename:
|
case Filename:
|
||||||
@ -158,7 +162,9 @@ void NewElementWizard::buildStep2() {
|
|||||||
explication2 -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
explication2 -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||||||
explication2 -> setWordWrap(true);
|
explication2 -> setWordWrap(true);
|
||||||
step2_layout -> addWidget(explication1);
|
step2_layout -> addWidget(explication1);
|
||||||
step2_layout -> addWidget(qle_filename = new QLineEdit());
|
qle_filename = new QLineEdit(tr("nouvel_element"));
|
||||||
|
qle_filename -> selectAll();
|
||||||
|
step2_layout -> addWidget(qle_filename);
|
||||||
step2_layout -> addWidget(explication2);
|
step2_layout -> addWidget(explication2);
|
||||||
step2_layout -> addSpacing(100);
|
step2_layout -> addSpacing(100);
|
||||||
step2 -> setLayout(step2_layout);
|
step2 -> setLayout(step2_layout);
|
||||||
@ -266,37 +272,12 @@ void NewElementWizard::buildStep5() {
|
|||||||
explication -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
explication -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||||||
explication -> setWordWrap(true);
|
explication -> setWordWrap(true);
|
||||||
|
|
||||||
#define MK_COMBO_BOX(a) a##_orientation = new QComboBox(); \
|
orientation_set = new OrientationSetWidget();
|
||||||
a##_orientation -> addItem(tr("Par d\351faut"), "d"); \
|
|
||||||
a##_orientation -> addItem(tr("Possible"), "y"); \
|
|
||||||
a##_orientation -> addItem(tr("Impossible"), "n");
|
|
||||||
|
|
||||||
// 4 combo box
|
|
||||||
MK_COMBO_BOX(north)
|
|
||||||
MK_COMBO_BOX(east)
|
|
||||||
MK_COMBO_BOX(south)
|
|
||||||
MK_COMBO_BOX(west)
|
|
||||||
|
|
||||||
#undef MK_COMBO_BOX
|
|
||||||
|
|
||||||
east_orientation -> setCurrentIndex(1);
|
|
||||||
south_orientation -> setCurrentIndex(1);
|
|
||||||
west_orientation -> setCurrentIndex(1);
|
|
||||||
|
|
||||||
QGridLayout *qgl = new QGridLayout();
|
|
||||||
qgl -> addWidget(new QLabel(tr("Nord :")), 0, 0);
|
|
||||||
qgl -> addWidget(north_orientation, 0, 1);
|
|
||||||
qgl -> addWidget(new QLabel(tr("Est :")), 1, 0);
|
|
||||||
qgl -> addWidget(east_orientation, 1, 1);
|
|
||||||
qgl -> addWidget(new QLabel(tr("Sud :")), 2, 0);
|
|
||||||
qgl -> addWidget(south_orientation, 2, 1);
|
|
||||||
qgl -> addWidget(new QLabel(tr("Ouest :")), 3, 0);
|
|
||||||
qgl -> addWidget(west_orientation, 3, 1);
|
|
||||||
|
|
||||||
QVBoxLayout *step5_layout = new QVBoxLayout();
|
QVBoxLayout *step5_layout = new QVBoxLayout();
|
||||||
step5_layout -> addWidget(explication);
|
step5_layout -> addWidget(explication);
|
||||||
step5_layout -> addLayout(qgl);
|
step5_layout -> addWidget(orientation_set);
|
||||||
step5_layout -> addSpacing(75);
|
step5_layout -> addSpacing(25);
|
||||||
step5 -> setLayout(step5_layout);
|
step5 -> setLayout(step5_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,6 +330,7 @@ bool NewElementWizard::validStep2() {
|
|||||||
return(answer == QMessageBox::Yes);
|
return(answer == QMessageBox::Yes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chosen_file = dir_path + "/" + file_name;
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,19 +359,7 @@ bool NewElementWizard::validStep4() {
|
|||||||
@return true si l'etape est validee, false sinon
|
@return true si l'etape est validee, false sinon
|
||||||
*/
|
*/
|
||||||
bool NewElementWizard::validStep5() {
|
bool NewElementWizard::validStep5() {
|
||||||
int nb_orientations = 0;
|
// l'editeur d'orientations se charge deja de valider tout ca
|
||||||
if (!north_orientation -> currentIndex()) ++ nb_orientations;
|
|
||||||
if (!east_orientation -> currentIndex()) ++ nb_orientations;
|
|
||||||
if (!south_orientation -> currentIndex()) ++ nb_orientations;
|
|
||||||
if (!west_orientation -> currentIndex()) ++ nb_orientations;
|
|
||||||
if (nb_orientations != 1) {
|
|
||||||
QMessageBox::critical(
|
|
||||||
this,
|
|
||||||
tr("Erreur"),
|
|
||||||
tr("Il doit y avoir exactement une orientation par d\351faut.")
|
|
||||||
);
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,6 +415,12 @@ void NewElementWizard::updateHotspotLimits() {
|
|||||||
Cree le nouvel element
|
Cree le nouvel element
|
||||||
*/
|
*/
|
||||||
void NewElementWizard::createNewElement() {
|
void NewElementWizard::createNewElement() {
|
||||||
/// @todo
|
CustomElementEditor *edit_new_element = new CustomElementEditor(parentWidget());
|
||||||
QMessageBox::warning(this, "Creation de l'element", "Not Implemented Yet");
|
edit_new_element -> setSize(QSize(sb_width -> value() * 10, sb_height -> value() * 10));
|
||||||
|
edit_new_element -> setHotspot(QPoint(sb_hotspot_x -> value(), sb_hotspot_y -> value()));
|
||||||
|
edit_new_element -> setNames(element_names -> names());
|
||||||
|
edit_new_element -> setOrientations(orientation_set -> orientationSet());
|
||||||
|
edit_new_element -> setFileName(chosen_file);
|
||||||
|
edit_new_element -> show();
|
||||||
|
accept();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
class ElementsCategoriesWidget;
|
class ElementsCategoriesWidget;
|
||||||
class NamesListWidget;
|
class NamesListWidget;
|
||||||
|
class OrientationSetWidget;
|
||||||
class Diagram;
|
class Diagram;
|
||||||
class NewElementWizard : public QDialog {
|
class NewElementWizard : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -38,6 +39,7 @@ class NewElementWizard : public QDialog {
|
|||||||
QSpinBox *sb_hotspot_x;
|
QSpinBox *sb_hotspot_x;
|
||||||
QSpinBox *sb_hotspot_y;
|
QSpinBox *sb_hotspot_y;
|
||||||
NamesListWidget *element_names;
|
NamesListWidget *element_names;
|
||||||
|
OrientationSetWidget *orientation_set;
|
||||||
QPushButton *button_previous;
|
QPushButton *button_previous;
|
||||||
QPushButton *button_next;
|
QPushButton *button_next;
|
||||||
WizardState current_state;
|
WizardState current_state;
|
||||||
@ -47,6 +49,7 @@ class NewElementWizard : public QDialog {
|
|||||||
QComboBox *east_orientation;
|
QComboBox *east_orientation;
|
||||||
QComboBox *south_orientation;
|
QComboBox *south_orientation;
|
||||||
QComboBox *west_orientation;
|
QComboBox *west_orientation;
|
||||||
|
QString chosen_file;
|
||||||
|
|
||||||
// methodes
|
// methodes
|
||||||
private:
|
private:
|
||||||
|
164
orientationset.cpp
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
#include "orientationset.h"
|
||||||
|
|
||||||
|
OrientationSet::OrientationSet() :
|
||||||
|
north_ori(true),
|
||||||
|
east_ori(true),
|
||||||
|
south_ori(true),
|
||||||
|
west_ori(true),
|
||||||
|
default_ori(QET::North),
|
||||||
|
current_ori(QET::North)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool OrientationSet::setNorth (bool ori) {
|
||||||
|
// pour desactiver une orientation, il doit y avoir au moins une autre orientation possible
|
||||||
|
bool can_set_ori = ori ? true : east_ori || south_ori || west_ori;
|
||||||
|
if (can_set_ori) {
|
||||||
|
north_ori = ori;
|
||||||
|
// en cas de desactivation d'une orientation, il faut verifier voire corriger les orientations courante et par defaut
|
||||||
|
if (!ori) {
|
||||||
|
if (default_ori == QET::North) default_ori = next();
|
||||||
|
if (current_ori == QET::North) current_ori = next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(can_set_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrientationSet::setEast (bool ori) {
|
||||||
|
// pour desactiver une orientation, il doit y avoir au moins une autre orientation possible
|
||||||
|
bool can_set_ori = ori ? true : south_ori || west_ori || north_ori;
|
||||||
|
if (can_set_ori) {
|
||||||
|
east_ori = ori;
|
||||||
|
// en cas de desactivation d'une orientation, il faut verifier voire corriger les orientations courante et par defaut
|
||||||
|
if (!ori) {
|
||||||
|
if (default_ori == QET::East) default_ori = next();
|
||||||
|
if (current_ori == QET::East) current_ori = next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(can_set_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrientationSet::setSouth (bool ori) {
|
||||||
|
// pour desactiver une orientation, il doit y avoir au moins une autre orientation possible
|
||||||
|
bool can_set_ori = ori ? true : west_ori || north_ori || east_ori;
|
||||||
|
if (can_set_ori) {
|
||||||
|
south_ori = ori;
|
||||||
|
// en cas de desactivation d'une orientation, il faut verifier voire corriger les orientations courante et par defaut
|
||||||
|
if (!ori) {
|
||||||
|
if (default_ori == QET::South) default_ori = next();
|
||||||
|
if (current_ori == QET::South) current_ori = next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(can_set_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrientationSet::setWest (bool ori) {
|
||||||
|
// pour desactiver une orientation, il doit y avoir au moins une autre orientation possible
|
||||||
|
bool can_set_ori = ori ? true : north_ori || east_ori || south_ori;
|
||||||
|
if (can_set_ori) {
|
||||||
|
west_ori = ori;
|
||||||
|
// en cas de desactivation d'une orientation, il faut verifier voire corriger les orientations courante et par defaut
|
||||||
|
if (!ori) {
|
||||||
|
if (default_ori == QET::West) default_ori = next();
|
||||||
|
if (current_ori == QET::West) current_ori = next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(can_set_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrientationSet::setCurrent(QET::Orientation ori) {
|
||||||
|
bool can_set_ori = accept(ori);
|
||||||
|
if (can_set_ori) current_ori = ori;
|
||||||
|
return(can_set_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
QET::Orientation OrientationSet::next() const {
|
||||||
|
QET::Orientation result = current_ori;
|
||||||
|
do result = QET::nextOrientation(result); while (!accept(result));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
QET::Orientation OrientationSet::previous() const {
|
||||||
|
QET::Orientation result = current_ori;
|
||||||
|
do result = QET::previousOrientation(result); while (!accept(result));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OrientationSet OrientationSet::operator++(int) {
|
||||||
|
OrientationSet before(*this);
|
||||||
|
setNext();
|
||||||
|
return(before);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OrientationSet OrientationSet::operator--(int) {
|
||||||
|
OrientationSet before(*this);
|
||||||
|
setPrevious();
|
||||||
|
return(before);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Permet de savoir si une orientation donnee peut etre utilisee.
|
||||||
|
@param o L'orientation en question
|
||||||
|
@return true si l'orientation est utilisable, false sinon
|
||||||
|
*/
|
||||||
|
bool OrientationSet::accept(QET::Orientation ori) const {
|
||||||
|
bool accepted_ori = false;
|
||||||
|
switch(ori) {
|
||||||
|
case QET::North: accepted_ori = north_ori; break;
|
||||||
|
case QET::East : accepted_ori = east_ori; break;
|
||||||
|
case QET::South: accepted_ori = south_ori; break;
|
||||||
|
case QET::West : accepted_ori = west_ori; break;
|
||||||
|
}
|
||||||
|
return(accepted_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
QET::Orientation OrientationSet::setNext() {
|
||||||
|
setCurrent(next());
|
||||||
|
return(current_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
QET::Orientation OrientationSet::setPrevious() {
|
||||||
|
setCurrent(previous());
|
||||||
|
return(current_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OrientationSet OrientationSet::operator++() {
|
||||||
|
setNext();
|
||||||
|
return(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const OrientationSet OrientationSet::operator--() {
|
||||||
|
setPrevious();
|
||||||
|
return(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrientationSet::fromString(const QString &str) {
|
||||||
|
QRegExp osv("^([dyn])([dyn])([dyn])([dyn])$"); // osv : Orientation String Validator
|
||||||
|
if (osv.indexIn(str) == -1) return(false);
|
||||||
|
QStringList matches = osv.capturedTexts();
|
||||||
|
|
||||||
|
// il doit y avoir exactement UN d dans les 4 lettres capturees
|
||||||
|
if (matches.count("d") != 1) return(false);
|
||||||
|
|
||||||
|
bool *ori_pointers[4] = { &north_ori, &east_ori, &south_ori, &west_ori };
|
||||||
|
QET::Orientation ori_ints[4] = { QET::North, QET::East, QET::South, QET::West };
|
||||||
|
for(int i = 0 ; i < 4 ; ++ i) {
|
||||||
|
QString current = matches.at(i + 1);
|
||||||
|
if (current == "d") {
|
||||||
|
current_ori = default_ori = ori_ints[i];
|
||||||
|
current = "y";
|
||||||
|
}
|
||||||
|
*(ori_pointers[i]) = (current == "y");
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString OrientationSet::toString() const {
|
||||||
|
bool ori_pointers[4] = { north_ori, east_ori, south_ori, west_ori };
|
||||||
|
QET::Orientation ori_ints[4] = { QET::North, QET::East, QET::South, QET::West };
|
||||||
|
QString result("");
|
||||||
|
for(int i = 0 ; i < 4 ; ++ i) {
|
||||||
|
if (default_ori == ori_ints[i]) result += "d";
|
||||||
|
else result += (ori_pointers[i] ? "y" : "n");
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
76
orientationset.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#ifndef ORIENTATION_SET_H
|
||||||
|
#define ORIENTATION_SET_H
|
||||||
|
#include "qet.h"
|
||||||
|
class OrientationSet {
|
||||||
|
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
OrientationSet();
|
||||||
|
virtual ~OrientationSet() {};
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
bool north_ori;
|
||||||
|
bool east_ori;
|
||||||
|
bool south_ori;
|
||||||
|
bool west_ori;
|
||||||
|
QET::Orientation default_ori;
|
||||||
|
QET::Orientation current_ori;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
bool north() const;
|
||||||
|
bool east() const;
|
||||||
|
bool south() const;
|
||||||
|
bool west() const;
|
||||||
|
bool setNorth(bool);
|
||||||
|
bool setEast(bool);
|
||||||
|
bool setSouth(bool);
|
||||||
|
bool setWest(bool);
|
||||||
|
QET::Orientation defaultOrientation() const;
|
||||||
|
void setDefaultOrientation(const QET::Orientation &);
|
||||||
|
QET::Orientation current() const;
|
||||||
|
bool setCurrent(QET::Orientation);
|
||||||
|
QET::Orientation next() const;
|
||||||
|
QET::Orientation previous() const;
|
||||||
|
QET::Orientation setNext();
|
||||||
|
QET::Orientation setPrevious();
|
||||||
|
bool accept(QET::Orientation) const;
|
||||||
|
const OrientationSet operator++(int);
|
||||||
|
const OrientationSet operator--(int);
|
||||||
|
const OrientationSet operator++();
|
||||||
|
const OrientationSet operator--();
|
||||||
|
bool fromString(const QString &);
|
||||||
|
QString toString() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool OrientationSet::north() const {
|
||||||
|
return(north_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OrientationSet::east() const {
|
||||||
|
return(east_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OrientationSet::south() const {
|
||||||
|
return(south_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool OrientationSet::west() const {
|
||||||
|
return(west_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void OrientationSet::setDefaultOrientation(const QET::Orientation& theValue) {
|
||||||
|
default_ori = theValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QET::Orientation OrientationSet::defaultOrientation() const {
|
||||||
|
return(default_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QET::Orientation OrientationSet::current() const {
|
||||||
|
return(current_ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
111
orientationsetwidget.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include "orientationsetwidget.h"
|
||||||
|
|
||||||
|
OrientationSetWidget::OrientationSetWidget(QWidget *parent) : QWidget(parent) {
|
||||||
|
|
||||||
|
default_radios = new QButtonGroup(this);
|
||||||
|
|
||||||
|
#define MK_COMBO_BOX(a) a##_orientation = new QComboBox();\
|
||||||
|
a##_orientation -> addItem(QIcon(":/ico/allowed.png"), tr("Possible"), "y");\
|
||||||
|
a##_orientation -> addItem(QIcon(":/ico/forbidden.png"),tr("Impossible"), "n");\
|
||||||
|
connect(a##_orientation, SIGNAL(activated(int)), this, SLOT(updateOrientationSet()));\
|
||||||
|
a##_default = new QRadioButton();
|
||||||
|
|
||||||
|
// 4 combo box, 4 boutons radios
|
||||||
|
MK_COMBO_BOX(north)
|
||||||
|
MK_COMBO_BOX(east)
|
||||||
|
MK_COMBO_BOX(south)
|
||||||
|
MK_COMBO_BOX(west)
|
||||||
|
|
||||||
|
#undef MK_COMBO_BOX
|
||||||
|
|
||||||
|
default_radios -> addButton(north_default, QET::North);
|
||||||
|
default_radios -> addButton(east_default, QET::East);
|
||||||
|
default_radios -> addButton(south_default, QET::South);
|
||||||
|
default_radios -> addButton(west_default, QET::West);
|
||||||
|
connect(default_radios, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(slot_defaultChanged(QAbstractButton *)));
|
||||||
|
|
||||||
|
// petites icones symbolisant les orientations
|
||||||
|
QLabel *north_pixmap = new QLabel(tr("Nord :"));
|
||||||
|
north_pixmap -> setPixmap(QPixmap(":/ico/north.png"));
|
||||||
|
QLabel *east_pixmap = new QLabel(tr("Est :"));
|
||||||
|
east_pixmap -> setPixmap(QPixmap(":/ico/east.png"));
|
||||||
|
QLabel *south_pixmap = new QLabel(tr("Sud :"));
|
||||||
|
south_pixmap -> setPixmap(QPixmap(":/ico/south.png"));
|
||||||
|
QLabel *west_pixmap = new QLabel(tr("Ouest :"));
|
||||||
|
west_pixmap -> setPixmap(QPixmap(":/ico/west.png"));
|
||||||
|
|
||||||
|
QGridLayout *qgl = new QGridLayout(this);
|
||||||
|
qgl -> addWidget(new QLabel(tr("Par d\351faut")), 0, 3);
|
||||||
|
qgl -> addWidget(north_pixmap, 1, 0);
|
||||||
|
qgl -> addWidget(new QLabel(tr("Nord :")), 1, 1);
|
||||||
|
qgl -> addWidget(north_orientation, 1, 2);
|
||||||
|
qgl -> addWidget(north_default, 1, 3, Qt::AlignHCenter);
|
||||||
|
qgl -> addWidget(east_pixmap, 2, 0);
|
||||||
|
qgl -> addWidget(new QLabel(tr("Est :")), 2, 1);
|
||||||
|
qgl -> addWidget(east_orientation, 2, 2);
|
||||||
|
qgl -> addWidget(east_default, 2, 3, Qt::AlignHCenter);
|
||||||
|
qgl -> addWidget(south_pixmap, 3, 0);
|
||||||
|
qgl -> addWidget(new QLabel(tr("Sud :")), 3, 1);
|
||||||
|
qgl -> addWidget(south_orientation, 3, 2);
|
||||||
|
qgl -> addWidget(south_default, 3, 3, Qt::AlignHCenter);
|
||||||
|
qgl -> addWidget(west_pixmap, 4, 0);
|
||||||
|
qgl -> addWidget(new QLabel(tr("Ouest :")), 4, 1);
|
||||||
|
qgl -> addWidget(west_orientation, 4, 2);
|
||||||
|
qgl -> addWidget(west_default, 4, 3, Qt::AlignHCenter);
|
||||||
|
|
||||||
|
// les combobox s'etendent autant que possible
|
||||||
|
qgl -> setColumnStretch(2, 1);
|
||||||
|
|
||||||
|
// l'orientation par defaut par defaut est le Nord
|
||||||
|
north_default -> setChecked(true);
|
||||||
|
slot_defaultChanged(north_default);
|
||||||
|
}
|
||||||
|
|
||||||
|
OrientationSet OrientationSetWidget::orientationSet() const {
|
||||||
|
return(ori);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrientationSetWidget::setOrientationSet(const OrientationSet &os) {
|
||||||
|
ori = os;
|
||||||
|
updateForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrientationSetWidget::slot_defaultChanged(QAbstractButton *button) {
|
||||||
|
if (button == north_default) north_orientation -> setCurrentIndex(0);
|
||||||
|
else if (button == east_default) east_orientation -> setCurrentIndex(0);
|
||||||
|
else if (button == south_default) south_orientation -> setCurrentIndex(0);
|
||||||
|
else if (button == west_default) west_orientation -> setCurrentIndex(0);
|
||||||
|
|
||||||
|
north_orientation -> setEnabled(button != north_default);
|
||||||
|
east_orientation -> setEnabled(button != east_default);
|
||||||
|
south_orientation -> setEnabled(button != south_default);
|
||||||
|
west_orientation -> setEnabled(button != west_default);
|
||||||
|
|
||||||
|
updateOrientationSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrientationSetWidget::updateOrientationSet() {
|
||||||
|
ori.setNorth(!north_orientation -> currentIndex());
|
||||||
|
ori.setEast (!east_orientation -> currentIndex());
|
||||||
|
ori.setSouth(!south_orientation -> currentIndex());
|
||||||
|
ori.setWest (!west_orientation -> currentIndex());
|
||||||
|
ori.setDefaultOrientation(static_cast<QET::Orientation>(default_radios -> checkedId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrientationSetWidget::updateForm() {
|
||||||
|
north_orientation -> setCurrentIndex(ori.north() ? 0 : 1);
|
||||||
|
east_orientation -> setCurrentIndex(ori.east() ? 0 : 1);
|
||||||
|
south_orientation -> setCurrentIndex(ori.south() ? 0 : 1);
|
||||||
|
west_orientation -> setCurrentIndex(ori.west() ? 0 : 1);
|
||||||
|
QRadioButton *default_button = NULL;
|
||||||
|
switch(ori.defaultOrientation()) {
|
||||||
|
case QET::North: default_button = north_default; break;
|
||||||
|
case QET::East : default_button = east_default ; break;
|
||||||
|
case QET::South: default_button = south_default; break;
|
||||||
|
case QET::West : default_button = west_default ; break;
|
||||||
|
}
|
||||||
|
if (default_button != NULL) {
|
||||||
|
default_button -> setChecked(true);
|
||||||
|
slot_defaultChanged(default_button);
|
||||||
|
}
|
||||||
|
}
|
40
orientationsetwidget.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#ifndef ORIENTATION_SET_WIDGET_H
|
||||||
|
#define ORIENTATION_SET_WIDGET_H
|
||||||
|
#include <QtGui>
|
||||||
|
#include "orientationset.h"
|
||||||
|
class OrientationSetWidget : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
// constructeurs, destructeur
|
||||||
|
public:
|
||||||
|
OrientationSetWidget(QWidget * = 0);
|
||||||
|
virtual ~OrientationSetWidget() {};
|
||||||
|
|
||||||
|
private:
|
||||||
|
OrientationSetWidget(const OrientationSetWidget &);
|
||||||
|
|
||||||
|
// attributs
|
||||||
|
private:
|
||||||
|
OrientationSet ori;
|
||||||
|
QComboBox *north_orientation;
|
||||||
|
QComboBox *east_orientation;
|
||||||
|
QComboBox *south_orientation;
|
||||||
|
QComboBox *west_orientation;
|
||||||
|
QRadioButton *north_default;
|
||||||
|
QRadioButton *east_default;
|
||||||
|
QRadioButton *south_default;
|
||||||
|
QRadioButton *west_default;
|
||||||
|
QButtonGroup *default_radios;
|
||||||
|
|
||||||
|
// methodes
|
||||||
|
public:
|
||||||
|
OrientationSet orientationSet() const;
|
||||||
|
void setOrientationSet(const OrientationSet &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateForm();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void slot_defaultChanged(QAbstractButton *);
|
||||||
|
void updateOrientationSet();
|
||||||
|
};
|
||||||
|
#endif
|
@ -1,11 +1,11 @@
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Automatically generated by qmake (2.01a) ven. avr. 6 18:45:47 2007
|
# Automatically generated by qmake (2.01a) dim. avr. 29 22:04:08 2007
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET =
|
TARGET =
|
||||||
DEPENDPATH += . lang
|
DEPENDPATH += . editor lang
|
||||||
INCLUDEPATH += .
|
INCLUDEPATH += . editor
|
||||||
|
|
||||||
# Input
|
# Input
|
||||||
HEADERS += aboutqet.h \
|
HEADERS += aboutqet.h \
|
||||||
@ -28,8 +28,28 @@ HEADERS += aboutqet.h \
|
|||||||
nameslist.h \
|
nameslist.h \
|
||||||
nameslistwidget.h \
|
nameslistwidget.h \
|
||||||
newelementwizard.h \
|
newelementwizard.h \
|
||||||
|
qet.h \
|
||||||
qetapp.h \
|
qetapp.h \
|
||||||
terminal.h
|
terminal.h \
|
||||||
|
editor/customelementeditor.h \
|
||||||
|
editor/customelementgraphicpart.h \
|
||||||
|
editor/customelementpart.h \
|
||||||
|
editor/editorscene.h \
|
||||||
|
editor/ellipseeditor.h \
|
||||||
|
editor/lineeditor.h \
|
||||||
|
editor/partellipse.h \
|
||||||
|
editor/partline.h \
|
||||||
|
editor/styleeditor.h \
|
||||||
|
editor/partcircle.h \
|
||||||
|
editor/circleeditor.h \
|
||||||
|
orientationset.h \
|
||||||
|
orientationsetwidget.h \
|
||||||
|
editor/partpolygon.h \
|
||||||
|
editor/polygoneditor.h \
|
||||||
|
editor/partterminal.h \
|
||||||
|
editor/terminaleditor.h \
|
||||||
|
editor/parttext.h \
|
||||||
|
editor/texteditor.h
|
||||||
SOURCES += aboutqet.cpp \
|
SOURCES += aboutqet.cpp \
|
||||||
borderinset.cpp \
|
borderinset.cpp \
|
||||||
conducer.cpp \
|
conducer.cpp \
|
||||||
@ -52,9 +72,27 @@ SOURCES += aboutqet.cpp \
|
|||||||
nameslistwidget.cpp \
|
nameslistwidget.cpp \
|
||||||
newelementwizard.cpp \
|
newelementwizard.cpp \
|
||||||
qetapp.cpp \
|
qetapp.cpp \
|
||||||
terminal.cpp
|
terminal.cpp \
|
||||||
|
editor/customelementeditor.cpp \
|
||||||
|
editor/customelementgraphicpart.cpp \
|
||||||
|
editor/customelementpart.cpp \
|
||||||
|
editor/editorscene.cpp \
|
||||||
|
editor/ellipseeditor.cpp \
|
||||||
|
editor/lineeditor.cpp \
|
||||||
|
editor/partellipse.cpp \
|
||||||
|
editor/partline.cpp \
|
||||||
|
editor/styleeditor.cpp \
|
||||||
|
editor/qet.cpp \
|
||||||
|
editor/partcircle.cpp \
|
||||||
|
editor/circleeditor.cpp \
|
||||||
|
orientationset.cpp \
|
||||||
|
orientationsetwidget.cpp \
|
||||||
|
editor/partpolygon.cpp \
|
||||||
|
editor/polygoneditor.cpp \
|
||||||
|
editor/partterminal.cpp \
|
||||||
|
editor/terminaleditor.cpp \
|
||||||
|
editor/parttext.cpp \
|
||||||
|
editor/texteditor.cpp
|
||||||
RESOURCES += qelectrotech.qrc
|
RESOURCES += qelectrotech.qrc
|
||||||
TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts
|
TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts
|
||||||
CONFIG += debug warn_on
|
|
||||||
QT += xml
|
QT += xml
|
||||||
|
|
||||||
|
@ -2,39 +2,56 @@
|
|||||||
<qresource>
|
<qresource>
|
||||||
<file>ico/qet.png</file>
|
<file>ico/qet.png</file>
|
||||||
<file>ico/qelectrotech.png</file>
|
<file>ico/qelectrotech.png</file>
|
||||||
|
<file>ico/allowed.png</file>
|
||||||
|
<file>ico/add_col.png</file>
|
||||||
|
<file>ico/arc.png</file>
|
||||||
<file>ico/button_cancel.png</file>
|
<file>ico/button_cancel.png</file>
|
||||||
<file>ico/button_ok.png</file>
|
<file>ico/button_ok.png</file>
|
||||||
|
<file>ico/circle.png</file>
|
||||||
<file>ico/configure.png</file>
|
<file>ico/configure.png</file>
|
||||||
<file>ico/copy.png</file>
|
<file>ico/copy.png</file>
|
||||||
<file>ico/cut.png</file>
|
<file>ico/cut.png</file>
|
||||||
<file>ico/delete.png</file>
|
<file>ico/delete.png</file>
|
||||||
|
<file>ico/east.png</file>
|
||||||
<file>ico/editdelete.png</file>
|
<file>ico/editdelete.png</file>
|
||||||
|
<file>ico/ellipse.png</file>
|
||||||
<file>ico/entrer_fs.png</file>
|
<file>ico/entrer_fs.png</file>
|
||||||
<file>ico/exit.png</file>
|
<file>ico/exit.png</file>
|
||||||
<file>ico/export.png</file>
|
<file>ico/export.png</file>
|
||||||
<file>ico/fileclose.png</file>
|
<file>ico/fileclose.png</file>
|
||||||
|
<file>ico/forbidden.png</file>
|
||||||
<file>ico/import.png</file>
|
<file>ico/import.png</file>
|
||||||
<file>ico/info.png</file>
|
<file>ico/info.png</file>
|
||||||
|
<file>ico/line.png</file>
|
||||||
<file>ico/masquer.png</file>
|
<file>ico/masquer.png</file>
|
||||||
<file>ico/move.png</file>
|
<file>ico/move.png</file>
|
||||||
<file>ico/new.png</file>
|
<file>ico/new.png</file>
|
||||||
|
<file>ico/north.png</file>
|
||||||
<file>ico/open.png</file>
|
<file>ico/open.png</file>
|
||||||
|
<file>ico/orientations.png</file>
|
||||||
<file>ico/paste.png</file>
|
<file>ico/paste.png</file>
|
||||||
<file>ico/pivoter.png</file>
|
<file>ico/pivoter.png</file>
|
||||||
|
<file>ico/polygon.png</file>
|
||||||
<file>ico/print.png</file>
|
<file>ico/print.png</file>
|
||||||
<file>ico/qt.png</file>
|
<file>ico/qt.png</file>
|
||||||
<file>ico/redo.png</file>
|
<file>ico/redo.png</file>
|
||||||
<file>ico/reload.png</file>
|
<file>ico/reload.png</file>
|
||||||
|
<file>ico/remove_col.png</file>
|
||||||
<file>ico/restaurer.png</file>
|
<file>ico/restaurer.png</file>
|
||||||
<file>ico/saveas.png</file>
|
<file>ico/saveas.png</file>
|
||||||
<file>ico/save.png</file>
|
<file>ico/save.png</file>
|
||||||
<file>ico/select.png</file>
|
<file>ico/select.png</file>
|
||||||
<file>ico/sortir_fs.png</file>
|
<file>ico/sortir_fs.png</file>
|
||||||
|
<file>ico/south.png</file>
|
||||||
|
<file>ico/terminal.png</file>
|
||||||
|
<file>ico/text.png</file>
|
||||||
|
<file>ico/textfield.png</file>
|
||||||
<file>ico/toolbars.png</file>
|
<file>ico/toolbars.png</file>
|
||||||
<file>ico/undo.png</file>
|
<file>ico/undo.png</file>
|
||||||
<file>ico/viewmagfit.png</file>
|
<file>ico/viewmagfit.png</file>
|
||||||
<file>ico/viewmag-.png</file>
|
<file>ico/viewmag-.png</file>
|
||||||
<file>ico/viewmag.png</file>
|
<file>ico/viewmag.png</file>
|
||||||
<file>ico/viewmag+.png</file>
|
<file>ico/viewmag+.png</file>
|
||||||
|
<file>ico/west.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
21
qet.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef _QET_H
|
||||||
|
#define _QET_H
|
||||||
|
#include <QtXml>
|
||||||
|
/**
|
||||||
|
Ce fichier contient des fonctions utiles pouvant etre appelees depuis
|
||||||
|
n'importe ou. Il contient egalement des enums utilises dans plusieurs
|
||||||
|
classes de l'application
|
||||||
|
*/
|
||||||
|
namespace QET {
|
||||||
|
enum Orientation {North, East, South, West};
|
||||||
|
QET::Orientation nextOrientation(QET::Orientation);
|
||||||
|
QET::Orientation previousOrientation(QET::Orientation);
|
||||||
|
QET::Orientation orientationFromString(const QString &);
|
||||||
|
QString orientationToString(QET::Orientation);
|
||||||
|
bool surLeMemeAxe(QET::Orientation, QET::Orientation);
|
||||||
|
bool estHorizontale(QET::Orientation);
|
||||||
|
bool estVerticale(QET::Orientation);
|
||||||
|
bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL);
|
||||||
|
bool attributeIsAReal(const QDomElement &, QString , double * = NULL);
|
||||||
|
}
|
||||||
|
#endif
|
@ -221,8 +221,8 @@ void QETApp::actions() {
|
|||||||
supprimer = new QAction(QIcon(":/ico/delete.png"), tr("Supprimer"), this);
|
supprimer = new QAction(QIcon(":/ico/delete.png"), tr("Supprimer"), this);
|
||||||
pivoter = new QAction(QIcon(":/ico/pivoter.png"), tr("Pivoter"), this);
|
pivoter = new QAction(QIcon(":/ico/pivoter.png"), tr("Pivoter"), this);
|
||||||
infos_diagram = new QAction(QIcon(":/ico/info.png"), tr("Informations sur le sch\351ma"), this);
|
infos_diagram = new QAction(QIcon(":/ico/info.png"), tr("Informations sur le sch\351ma"), this);
|
||||||
add_column = new QAction( tr("Ajouter une colonne"), this);
|
add_column = new QAction(QIcon(":/ico/add_col.png"), tr("Ajouter une colonne"), this);
|
||||||
remove_column = new QAction( tr("Enlever une colonne"), this);
|
remove_column = new QAction(QIcon(":/ico/remove_col.png"), tr("Enlever une colonne"), this);
|
||||||
expand_diagram = new QAction( tr("Agrandir le sch\351ma"), this);
|
expand_diagram = new QAction( tr("Agrandir le sch\351ma"), this);
|
||||||
shrink_diagram = new QAction( tr("R\351tr\351cir le sch\351ma"), this);
|
shrink_diagram = new QAction( tr("R\351tr\351cir le sch\351ma"), this);
|
||||||
|
|
||||||
|
50
terminal.cpp
@ -3,26 +3,31 @@
|
|||||||
#include "element.h"
|
#include "element.h"
|
||||||
#include "conducer.h"
|
#include "conducer.h"
|
||||||
|
|
||||||
|
QColor Terminal::couleur_neutre = QColor(Qt::blue);
|
||||||
|
QColor Terminal::couleur_autorise = QColor(Qt::darkGreen);
|
||||||
|
QColor Terminal::couleur_prudence = QColor("#ff8000");
|
||||||
|
QColor Terminal::couleur_interdit = QColor(Qt::red);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Fonction privee pour initialiser la borne.
|
Fonction privee pour initialiser la borne.
|
||||||
@param pf position du point d'amarrage pour un conducteur
|
@param pf position du point d'amarrage pour un conducteur
|
||||||
@param o orientation de la borne : Qt::Horizontal ou Qt::Vertical
|
@param o orientation de la borne : Qt::Horizontal ou Qt::Vertical
|
||||||
*/
|
*/
|
||||||
void Terminal::initialise(QPointF pf, Terminal::Orientation o) {
|
void Terminal::initialise(QPointF pf, QET::Orientation o) {
|
||||||
// definition du pount d'amarrage pour un conducteur
|
// definition du pount d'amarrage pour un conducteur
|
||||||
amarrage_conducer = pf;
|
amarrage_conducer = pf;
|
||||||
|
|
||||||
// definition de l'orientation de la terminal (par defaut : sud)
|
// definition de l'orientation de la terminal (par defaut : sud)
|
||||||
if (o < Terminal::Nord || o > Terminal::Ouest) sens = Terminal::Sud;
|
if (o < QET::North || o > QET::West) sens = QET::South;
|
||||||
else sens = o;
|
else sens = o;
|
||||||
|
|
||||||
// calcul de la position du point d'amarrage a l'element
|
// calcul de la position du point d'amarrage a l'element
|
||||||
amarrage_elmt = amarrage_conducer;
|
amarrage_elmt = amarrage_conducer;
|
||||||
switch(sens) {
|
switch(sens) {
|
||||||
case Terminal::Nord : amarrage_elmt += QPointF(0, TAILLE_BORNE); break;
|
case QET::North: amarrage_elmt += QPointF(0, TAILLE_BORNE); break;
|
||||||
case Terminal::Est : amarrage_elmt += QPointF(-TAILLE_BORNE, 0); break;
|
case QET::East : amarrage_elmt += QPointF(-TAILLE_BORNE, 0); break;
|
||||||
case Terminal::Ouest : amarrage_elmt += QPointF(TAILLE_BORNE, 0); break;
|
case QET::West : amarrage_elmt += QPointF(TAILLE_BORNE, 0); break;
|
||||||
case Terminal::Sud :
|
case QET::South:
|
||||||
default : amarrage_elmt += QPointF(0, -TAILLE_BORNE);
|
default : amarrage_elmt += QPointF(0, -TAILLE_BORNE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,18 +41,16 @@ void Terminal::initialise(QPointF pf, Terminal::Orientation o) {
|
|||||||
setAcceptedMouseButtons(Qt::LeftButton);
|
setAcceptedMouseButtons(Qt::LeftButton);
|
||||||
hovered = false;
|
hovered = false;
|
||||||
setToolTip("Terminal");
|
setToolTip("Terminal");
|
||||||
couleur_neutre = QColor(Qt::blue);
|
|
||||||
couleur_autorise = QColor(Qt::darkGreen);
|
|
||||||
couleur_prudence = QColor("#ff8000");
|
|
||||||
couleur_interdit = QColor(Qt::red);
|
|
||||||
couleur_hovered = couleur_neutre;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructeur par defaut
|
Constructeur par defaut
|
||||||
*/
|
*/
|
||||||
Terminal::Terminal() : QGraphicsItem(0, 0) {
|
Terminal::Terminal() :
|
||||||
initialise(QPointF(0.0, 0.0), Terminal::Sud);
|
QGraphicsItem(0, 0),
|
||||||
|
couleur_hovered(Terminal::couleur_neutre)
|
||||||
|
{
|
||||||
|
initialise(QPointF(0.0, 0.0), QET::South);
|
||||||
diagram_scene = 0;
|
diagram_scene = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +61,10 @@ Terminal::Terminal() : QGraphicsItem(0, 0) {
|
|||||||
@param e Element auquel cette borne appartient
|
@param e Element auquel cette borne appartient
|
||||||
@param s Scene sur laquelle figure cette borne
|
@param s Scene sur laquelle figure cette borne
|
||||||
*/
|
*/
|
||||||
Terminal::Terminal(QPointF pf, Terminal::Orientation o, Element *e, Diagram *s) : QGraphicsItem(e, s) {
|
Terminal::Terminal(QPointF pf, QET::Orientation o, Element *e, Diagram *s) :
|
||||||
|
QGraphicsItem(e, s),
|
||||||
|
couleur_hovered(Terminal::couleur_neutre)
|
||||||
|
{
|
||||||
initialise(pf, o);
|
initialise(pf, o);
|
||||||
diagram_scene = s;
|
diagram_scene = s;
|
||||||
}
|
}
|
||||||
@ -71,7 +77,10 @@ Terminal::Terminal(QPointF pf, Terminal::Orientation o, Element *e, Diagram *s)
|
|||||||
@param e Element auquel cette borne appartient
|
@param e Element auquel cette borne appartient
|
||||||
@param s Scene sur laquelle figure cette borne
|
@param s Scene sur laquelle figure cette borne
|
||||||
*/
|
*/
|
||||||
Terminal::Terminal(qreal pf_x, qreal pf_y, Terminal::Orientation o, Element *e, Diagram *s) : QGraphicsItem(e, s) {
|
Terminal::Terminal(qreal pf_x, qreal pf_y, QET::Orientation o, Element *e, Diagram *s) :
|
||||||
|
QGraphicsItem(e, s),
|
||||||
|
couleur_hovered(Terminal::couleur_neutre)
|
||||||
|
{
|
||||||
initialise(QPointF(pf_x, pf_y), o);
|
initialise(QPointF(pf_x, pf_y), o);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,19 +102,18 @@ Terminal::~Terminal() {
|
|||||||
pivote. Sinon elle renvoie son sens normal.
|
pivote. Sinon elle renvoie son sens normal.
|
||||||
@return L'orientation actuelle de la Terminal.
|
@return L'orientation actuelle de la Terminal.
|
||||||
*/
|
*/
|
||||||
Terminal::Orientation Terminal::orientation() const {
|
QET::Orientation Terminal::orientation() const {
|
||||||
//true pour une orientation verticale, false pour une orientation horizontale
|
|
||||||
if (Element *elt = qgraphicsitem_cast<Element *>(parentItem())) {
|
if (Element *elt = qgraphicsitem_cast<Element *>(parentItem())) {
|
||||||
// orientations actuelle et par defaut de l'element
|
// orientations actuelle et par defaut de l'element
|
||||||
Terminal::Orientation ori_cur = elt -> orientation();
|
QET::Orientation ori_cur = elt -> orientation().current();
|
||||||
Terminal::Orientation ori_def = elt -> defaultOrientation();
|
QET::Orientation ori_def = elt -> orientation().defaultOrientation();
|
||||||
if (ori_cur == ori_def) return(sens);
|
if (ori_cur == ori_def) return(sens);
|
||||||
else {
|
else {
|
||||||
// calcul l'angle de rotation implique par l'orientation de l'element parent
|
// 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
|
// angle de rotation de la borne sur la scene, divise par 90
|
||||||
int angle = ori_cur - ori_def + sens;
|
int angle = ori_cur - ori_def + sens;
|
||||||
while (angle >= 4) angle -= 4;
|
while (angle >= 4) angle -= 4;
|
||||||
return((Terminal::Orientation)angle);
|
return((QET::Orientation)angle);
|
||||||
}
|
}
|
||||||
} else return(sens);
|
} else return(sens);
|
||||||
}
|
}
|
||||||
@ -410,7 +418,7 @@ bool Terminal::valideXml(QDomElement &terminal) {
|
|||||||
// parse l'orientation
|
// parse l'orientation
|
||||||
int terminal_or = terminal.attribute("orientation").toInt(&conv_ok);
|
int terminal_or = terminal.attribute("orientation").toInt(&conv_ok);
|
||||||
if (!conv_ok) return(false);
|
if (!conv_ok) return(false);
|
||||||
if (terminal_or != Terminal::Nord && terminal_or != Terminal::Sud && terminal_or != Terminal::Est && terminal_or != Terminal::Ouest) return(false);
|
if (terminal_or != QET::North && terminal_or != QET::South && terminal_or != QET::East && terminal_or != QET::West) return(false);
|
||||||
|
|
||||||
// a ce stade, la borne est syntaxiquement correcte
|
// a ce stade, la borne est syntaxiquement correcte
|
||||||
return(true);
|
return(true);
|
||||||
|
24
terminal.h
@ -3,6 +3,7 @@
|
|||||||
#define TAILLE_BORNE 4
|
#define TAILLE_BORNE 4
|
||||||
#include <QtGui>
|
#include <QtGui>
|
||||||
#include <QtXml>
|
#include <QtXml>
|
||||||
|
#include "qet.h"
|
||||||
class Conducer;
|
class Conducer;
|
||||||
class Diagram;
|
class Diagram;
|
||||||
class Element;
|
class Element;
|
||||||
@ -14,10 +15,9 @@ class Terminal : public QGraphicsItem {
|
|||||||
|
|
||||||
// constructeurs, destructeur
|
// constructeurs, destructeur
|
||||||
public:
|
public:
|
||||||
enum Orientation {Nord, Est, Sud, Ouest};
|
|
||||||
Terminal();
|
Terminal();
|
||||||
Terminal(QPointF, Terminal::Orientation, Element * = 0, Diagram * = 0);
|
Terminal(QPointF, QET::Orientation, Element * = 0, Diagram * = 0);
|
||||||
Terminal(qreal, qreal, Terminal::Orientation, Element * = 0, Diagram * = 0);
|
Terminal(qreal, qreal, QET::Orientation, Element * = 0, Diagram * = 0);
|
||||||
virtual ~Terminal();
|
virtual ~Terminal();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -39,7 +39,7 @@ class Terminal : public QGraphicsItem {
|
|||||||
|
|
||||||
// methodes de lecture
|
// methodes de lecture
|
||||||
QList<Conducer *> conducers() const;
|
QList<Conducer *> conducers() const;
|
||||||
Terminal::Orientation orientation() const;
|
QET::Orientation orientation() const;
|
||||||
QPointF amarrageConducer() const;
|
QPointF amarrageConducer() const;
|
||||||
void updateConducer(QPointF = QPointF());
|
void updateConducer(QPointF = QPointF());
|
||||||
|
|
||||||
@ -61,6 +61,12 @@ class Terminal : public QGraphicsItem {
|
|||||||
public:
|
public:
|
||||||
enum { Type = UserType + 1002 };
|
enum { Type = UserType + 1002 };
|
||||||
|
|
||||||
|
// differentes couleurs statiques utilisables pour l'effet "hover"
|
||||||
|
static QColor couleur_neutre;
|
||||||
|
static QColor couleur_autorise;
|
||||||
|
static QColor couleur_prudence;
|
||||||
|
static QColor couleur_interdit;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// pointeur vers la QGraphicsScene de type Diagram (evite quelques casts en interne)
|
// pointeur vers la QGraphicsScene de type Diagram (evite quelques casts en interne)
|
||||||
Diagram *diagram_scene;
|
Diagram *diagram_scene;
|
||||||
@ -68,7 +74,7 @@ class Terminal : public QGraphicsItem {
|
|||||||
QPointF amarrage_conducer;
|
QPointF amarrage_conducer;
|
||||||
QPointF amarrage_elmt;
|
QPointF amarrage_elmt;
|
||||||
// orientation de la borne
|
// orientation de la borne
|
||||||
Terminal::Orientation sens;
|
QET::Orientation sens;
|
||||||
// liste des conducers lies a cette borne
|
// liste des conducers lies a cette borne
|
||||||
QList<Conducer *> liste_conducers;
|
QList<Conducer *> liste_conducers;
|
||||||
// pointeur vers un rectangle correspondant au bounding rect ; permet de ne calculer le bounding rect qu'une seule fois ; le pointeur c'est parce que le compilo exige une methode const
|
// pointeur vers un rectangle correspondant au bounding rect ; permet de ne calculer le bounding rect qu'une seule fois ; le pointeur c'est parce que le compilo exige une methode const
|
||||||
@ -76,13 +82,9 @@ class Terminal : public QGraphicsItem {
|
|||||||
Terminal *terminal_precedente;
|
Terminal *terminal_precedente;
|
||||||
bool hovered;
|
bool hovered;
|
||||||
// methode initialisant les differents membres de la borne
|
// methode initialisant les differents membres de la borne
|
||||||
void initialise(QPointF, Terminal::Orientation);
|
void initialise(QPointF, QET::Orientation);
|
||||||
// differentes couleurs utilisables pour l'effet "hover"
|
// couleur de l'effet hover de la patte
|
||||||
QColor couleur_hovered;
|
QColor couleur_hovered;
|
||||||
QColor couleur_neutre;
|
|
||||||
QColor couleur_autorise;
|
|
||||||
QColor couleur_prudence;
|
|
||||||
QColor couleur_interdit;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|