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) {
|
||||
// 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;
|
||||
|
||||
// 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 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");
|
||||
|
||||
// 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 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;
|
||||
Terminal::Orientation ori_depart, ori_arrivee;
|
||||
QET::Orientation ori_depart, ori_arrivee;
|
||||
|
||||
// s'assure qu'il n'y a ni points
|
||||
QList<QPointF> points;
|
||||
@ -236,34 +236,34 @@ void Conducer::priv_calculeConducer(const QPointF &p1, Terminal::Orientation o1,
|
||||
// commence le vrai trajet
|
||||
if (depart.y() < arrivee.y()) {
|
||||
// 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 »
|
||||
qreal ligne_inter_x = (depart.x() + arrivee.x()) / 2.0;
|
||||
points << QPointF(ligne_inter_x, depart.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 »
|
||||
qreal ligne_inter_y = (depart.y() + arrivee.y()) / 2.0;
|
||||
points << QPointF(depart.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 »
|
||||
} else {
|
||||
points << QPointF(depart.x(), arrivee.y()); // cas « 1 »
|
||||
}
|
||||
} else {
|
||||
// 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 »
|
||||
qreal ligne_inter_y = (depart.y() + arrivee.y()) / 2.0;
|
||||
points << QPointF(depart.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 »
|
||||
qreal ligne_inter_x = (depart.x() + arrivee.x()) / 2.0;
|
||||
points << QPointF(ligne_inter_x, depart.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 »
|
||||
} else {
|
||||
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
|
||||
@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;
|
||||
switch(terminal_orientation) {
|
||||
case Terminal::Nord:
|
||||
case QET::North:
|
||||
extended_terminal = QPointF(terminal.x(), terminal.y() - ext_size);
|
||||
break;
|
||||
case Terminal::Est:
|
||||
case QET::East:
|
||||
extended_terminal = QPointF(terminal.x() + ext_size, terminal.y());
|
||||
break;
|
||||
case Terminal::Sud:
|
||||
case QET::South:
|
||||
extended_terminal = QPointF(terminal.x(), terminal.y() + ext_size);
|
||||
break;
|
||||
case Terminal::Ouest:
|
||||
case QET::West:
|
||||
extended_terminal = QPointF(terminal.x() - ext_size, terminal.y());
|
||||
break;
|
||||
default: extended_terminal = terminal;
|
||||
@ -356,36 +356,6 @@ void Conducer::paint(QPainter *qp, const QStyleOptionGraphicsItem */*qsogi*/, QW
|
||||
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
|
||||
*/
|
||||
|
@ -71,17 +71,14 @@ class Conducer : public QGraphicsPathItem {
|
||||
private:
|
||||
void segmentsToPath();
|
||||
void updatePoints();
|
||||
void priv_calculeConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
||||
void priv_modifieConducer(const QPointF &, Terminal::Orientation, const QPointF &, Terminal::Orientation);
|
||||
void priv_calculeConducer(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
|
||||
void priv_modifieConducer(const QPointF &, QET::Orientation, const QPointF &, QET::Orientation);
|
||||
int nbSegments() const;
|
||||
QList<QPointF> segmentsToPoints() const;
|
||||
void pointsToSegments(QList<QPointF>);
|
||||
bool hasClickedOn(QPointF, QPointF) const;
|
||||
void calculateTextItemPosition();
|
||||
static QPointF extendTerminal(const QPointF &, Terminal::Orientation, qreal = 12.0);
|
||||
static bool surLeMemeAxe(Terminal::Orientation, Terminal::Orientation);
|
||||
static bool estHorizontale(Terminal::Orientation a);
|
||||
static bool estVerticale(Terminal::Orientation a);
|
||||
static QPointF extendTerminal(const QPointF &, QET::Orientation, qreal = 12.0);
|
||||
static qreal conducer_bound(qreal tobound, qreal bound1, qreal bound2);
|
||||
static qreal conducer_bound(qreal tobound, qreal bound, bool positive);
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "customelement.h"
|
||||
#include "elementtextitem.h"
|
||||
#include "diagram.h"
|
||||
|
||||
/**
|
||||
Constructeur de la classe ElementPerso. Permet d'instancier un element
|
||||
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
|
||||
int w, h, hot_x, hot_y;
|
||||
if (
|
||||
!attributeIsAnInteger(racine, QString("width"), &w) ||\
|
||||
!attributeIsAnInteger(racine, QString("height"), &h) ||\
|
||||
!attributeIsAnInteger(racine, QString("hotspot_x"), &hot_x) ||\
|
||||
!attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) ||\
|
||||
!QET::attributeIsAnInteger(racine, QString("width"), &w) ||\
|
||||
!QET::attributeIsAnInteger(racine, QString("height"), &h) ||\
|
||||
!QET::attributeIsAnInteger(racine, QString("hotspot_x"), &hot_x) ||\
|
||||
!QET::attributeIsAnInteger(racine, QString("hotspot_y"), &hot_y) ||\
|
||||
!validOrientationAttribute(racine)
|
||||
) {
|
||||
if (etat != NULL) *etat = 5;
|
||||
@ -78,6 +77,7 @@ CustomElement::CustomElement(QString &nom_fichier, QGraphicsItem *qgi, Diagram *
|
||||
setSize(w, h);
|
||||
setHotspot(QPoint(hot_x, hot_y));
|
||||
setConnexionsInternesAcceptees(racine.attribute("ci") == "true");
|
||||
|
||||
// la definition est supposee avoir des enfants
|
||||
if (racine.firstChild().isNull()) {
|
||||
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
|
||||
*/
|
||||
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
|
||||
double x1, y1, x2, y2;
|
||||
if (!attributeIsAReal(e, QString("x1"), &x1)) return(false);
|
||||
if (!attributeIsAReal(e, QString("y1"), &y1)) return(false);
|
||||
if (!attributeIsAReal(e, QString("x2"), &x2)) return(false);
|
||||
if (!attributeIsAReal(e, QString("y2"), &y2)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("x1"), &x1)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("y1"), &y1)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("x2"), &x2)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("y2"), &y2)) return(false);
|
||||
qp.save();
|
||||
setPainterStyle(e, qp);
|
||||
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) {
|
||||
// verifie la presence des attributs obligatoires
|
||||
double cercle_x, cercle_y, cercle_r;
|
||||
if (!attributeIsAReal(e, QString("x"), &cercle_x)) return(false);
|
||||
if (!attributeIsAReal(e, QString("y"), &cercle_y)) return(false);
|
||||
if (!attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("x"), &cercle_x)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("y"), &cercle_y)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("diameter"), &cercle_r)) return(false);
|
||||
qp.save();
|
||||
setPainterStyle(e, qp);
|
||||
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) {
|
||||
// verifie la presence des attributs obligatoires
|
||||
double ellipse_x, ellipse_y, ellipse_l, ellipse_h;
|
||||
if (!attributeIsAReal(e, QString("x"), &ellipse_x)) return(false);
|
||||
if (!attributeIsAReal(e, QString("y"), &ellipse_y)) return(false);
|
||||
if (!attributeIsAReal(e, QString("width"), &ellipse_l)) return(false);
|
||||
if (!attributeIsAReal(e, QString("height"), &ellipse_h)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("x"), &ellipse_x)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("y"), &ellipse_y)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("width"), &ellipse_l)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("height"), &ellipse_h)) return(false);
|
||||
qp.save();
|
||||
setPainterStyle(e, qp);
|
||||
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) {
|
||||
// verifie la presence des attributs obligatoires
|
||||
double arc_x, arc_y, arc_l, arc_h, arc_s, arc_a;
|
||||
if (!attributeIsAReal(e, QString("x"), &arc_x)) return(false);
|
||||
if (!attributeIsAReal(e, QString("y"), &arc_y)) return(false);
|
||||
if (!attributeIsAReal(e, QString("width"), &arc_l)) return(false);
|
||||
if (!attributeIsAReal(e, QString("height"), &arc_h)) return(false);
|
||||
if (!attributeIsAReal(e, QString("start"), &arc_s)) return(false);
|
||||
if (!attributeIsAReal(e, QString("angle"), &arc_a)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("x"), &arc_x)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("y"), &arc_y)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("width"), &arc_l)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("height"), &arc_h)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("start"), &arc_s)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("angle"), &arc_a)) return(false);
|
||||
|
||||
qp.save();
|
||||
setPainterStyle(e, qp);
|
||||
@ -306,7 +314,7 @@ bool CustomElement::parseArc(QDomElement &e, QPainter &qp) {
|
||||
bool CustomElement::parsePolygon(QDomElement &e, QPainter &qp) {
|
||||
int i = 1;
|
||||
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;
|
||||
}
|
||||
if (i < 3) return(false);
|
||||
@ -338,9 +346,9 @@ bool CustomElement::parseText(QDomElement &e, QPainter &qp) {
|
||||
qreal pos_x, pos_y;
|
||||
int size;
|
||||
if (
|
||||
!attributeIsAReal(e, "x", &pos_x) ||\
|
||||
!attributeIsAReal(e, "y", &pos_y) ||\
|
||||
!attributeIsAnInteger(e, "size", &size) ||\
|
||||
!QET::attributeIsAReal(e, "x", &pos_x) ||\
|
||||
!QET::attributeIsAReal(e, "y", &pos_y) ||\
|
||||
!QET::attributeIsAnInteger(e, "size", &size) ||\
|
||||
!e.hasAttribute("text")
|
||||
) return(false);
|
||||
|
||||
@ -368,9 +376,9 @@ bool CustomElement::parseInput(QDomElement &e, Diagram *s) {
|
||||
qreal pos_x, pos_y;
|
||||
int size;
|
||||
if (
|
||||
!attributeIsAReal(e, "x", &pos_x) ||\
|
||||
!attributeIsAReal(e, "y", &pos_y) ||\
|
||||
!attributeIsAnInteger(e, "size", &size)
|
||||
!QET::attributeIsAReal(e, "x", &pos_x) ||\
|
||||
!QET::attributeIsAReal(e, "y", &pos_y) ||\
|
||||
!QET::attributeIsAnInteger(e, "size", &size)
|
||||
) return(false);
|
||||
|
||||
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) {
|
||||
// verifie la presence et la validite des attributs obligatoires
|
||||
double terminalx, terminaly;
|
||||
Terminal::Orientation terminalo;
|
||||
if (!attributeIsAReal(e, QString("x"), &terminalx)) return(false);
|
||||
if (!attributeIsAReal(e, QString("y"), &terminaly)) return(false);
|
||||
QET::Orientation terminalo;
|
||||
if (!QET::attributeIsAReal(e, QString("x"), &terminalx)) return(false);
|
||||
if (!QET::attributeIsAReal(e, QString("y"), &terminaly)) return(false);
|
||||
if (!e.hasAttribute("orientation")) return(false);
|
||||
if (e.attribute("orientation") == "n") terminalo = Terminal::Nord;
|
||||
else if (e.attribute("orientation") == "s") terminalo = Terminal::Sud;
|
||||
else if (e.attribute("orientation") == "e") terminalo = Terminal::Est;
|
||||
else if (e.attribute("orientation") == "w") terminalo = Terminal::Ouest;
|
||||
if (e.attribute("orientation") == "n") terminalo = QET::North;
|
||||
else if (e.attribute("orientation") == "s") terminalo = QET::South;
|
||||
else if (e.attribute("orientation") == "e") terminalo = QET::East;
|
||||
else if (e.attribute("orientation") == "w") terminalo = QET::West;
|
||||
else return(false);
|
||||
new Terminal(terminalx, terminaly, terminalo, this, s);
|
||||
++ nb_terminals;
|
||||
@ -419,44 +427,6 @@ void CustomElement::setQPainterAntiAliasing(QPainter &qp, bool 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
|
||||
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
|
||||
*/
|
||||
bool CustomElement::validOrientationAttribute(QDomElement &e) {
|
||||
// verifie la presence de l'attribut orientation
|
||||
if (!e.hasAttribute("orientation")) return(false);
|
||||
QString t = e.attribute("orientation");
|
||||
// verification syntaxique : 4 lettres, un d, que des y ou des n pour le reste
|
||||
if (t.length() != 4) return(false);
|
||||
int d_pos = -1;
|
||||
for (int i = 0 ; i < 4 ; ++ i) {
|
||||
QChar c = t.at(i);
|
||||
if (c != 'd' && c != 'y' && c != 'n') return(false);
|
||||
if (c == 'd') {
|
||||
if (d_pos == -1) d_pos = i;
|
||||
else return(false);
|
||||
}
|
||||
}
|
||||
if (d_pos == -1) return(false);
|
||||
|
||||
// orientation : 4 lettres = nord/est/sud/ouest avec d = default, y = yes et n = no
|
||||
ori_n = (t.at(0) == 'd' || t.at(0) == 'y');
|
||||
ori_e = (t.at(1) == 'd' || t.at(1) == 'y');
|
||||
ori_s = (t.at(2) == 'd' || t.at(2) == 'y');
|
||||
ori_w = (t.at(3) == 'd' || t.at(3) == 'y');
|
||||
ori_d = (Terminal::Orientation)d_pos;
|
||||
ori = ori_d;
|
||||
return(true);
|
||||
return(ori.fromString(e.attribute("orientation")));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include "fixedelement.h"
|
||||
#include <QtGui>
|
||||
#include "nameslist.h"
|
||||
class CustomElementPart;
|
||||
// #include "customelementpart.h"
|
||||
// #include "cep_line.h"
|
||||
/**
|
||||
Cette classe represente un element electrique. Elle est utilisable
|
||||
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);
|
||||
virtual ~CustomElement();
|
||||
|
||||
friend class CustomElementPart;
|
||||
|
||||
private:
|
||||
CustomElement(const CustomElement &);
|
||||
|
||||
@ -47,8 +52,6 @@ class CustomElement : public FixedElement {
|
||||
bool parseInput(QDomElement &, Diagram *);
|
||||
bool parseTerminal(QDomElement &, Diagram *);
|
||||
void setQPainterAntiAliasing(QPainter &, bool);
|
||||
bool attributeIsAnInteger(QDomElement &, QString, int * = NULL);
|
||||
bool attributeIsAReal(QDomElement &, QString, double * = NULL);
|
||||
bool validOrientationAttribute(QDomElement &);
|
||||
void setPainterStyle(QDomElement &, QPainter &);
|
||||
};
|
||||
|
@ -153,7 +153,7 @@ void DiagramView::pivoter() {
|
||||
if (scene -> selectedItems().isEmpty()) return;
|
||||
foreach (QGraphicsItem *item, scene -> selectedItems()) {
|
||||
if (Element *elt = qgraphicsitem_cast<Element *>(item)) {
|
||||
elt -> setOrientation(elt -> nextAcceptableOrientation());
|
||||
elt -> setOrientation(elt -> orientation().next());
|
||||
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
|
||||
@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
|
||||
if (!acceptOrientation(o)) return(false);
|
||||
if (!ori.accept(o)) return(false);
|
||||
prepareGeometryChange();
|
||||
// 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);
|
||||
ori = o;
|
||||
ori.setCurrent(o);
|
||||
update();
|
||||
foreach(QGraphicsItem *qgi, children()) {
|
||||
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);
|
||||
bool conv_ok;
|
||||
int read_ori = e.attribute("orientation").toInt(&conv_ok);
|
||||
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = defaultOrientation();
|
||||
setOrientation((Terminal::Orientation)read_ori);
|
||||
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = ori.defaultOrientation();
|
||||
setOrientation((QET::Orientation)read_ori);
|
||||
setSelected(e.attribute("selected") == "selected");
|
||||
|
||||
return(true);
|
||||
@ -380,7 +380,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
|
||||
element.setAttribute("x", pos().x());
|
||||
element.setAttribute("y", pos().y());
|
||||
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 */
|
||||
int id_terminal = 0;
|
||||
|
97
element.h
@ -2,6 +2,7 @@
|
||||
#define ELEMENT_H
|
||||
#include <QtGui>
|
||||
#include "terminal.h"
|
||||
#include "orientationset.h"
|
||||
/**
|
||||
Cette classe abstraite represente un element electrique.
|
||||
*/
|
||||
@ -21,12 +22,7 @@ class Element : public QGraphicsItem {
|
||||
enum { Type = UserType + 1000 };
|
||||
|
||||
protected:
|
||||
bool ori_n;
|
||||
bool ori_s;
|
||||
bool ori_e;
|
||||
bool ori_w;
|
||||
Terminal::Orientation ori_d;
|
||||
Terminal::Orientation ori;
|
||||
OrientationSet ori;
|
||||
|
||||
private:
|
||||
QSize dimensions;
|
||||
@ -74,12 +70,8 @@ class Element : public QGraphicsItem {
|
||||
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int>&) const;
|
||||
|
||||
// methodes d'acces aux possibilites d'orientation
|
||||
Terminal::Orientation orientation() const;
|
||||
Terminal::Orientation defaultOrientation() const;
|
||||
bool acceptOrientation(Terminal::Orientation o) const;
|
||||
Terminal::Orientation nextAcceptableOrientation() const;
|
||||
Terminal::Orientation previousAcceptableOrientation() const;
|
||||
bool setOrientation(Terminal::Orientation o);
|
||||
bool setOrientation(QET::Orientation o);
|
||||
const OrientationSet &orientation() const;
|
||||
|
||||
protected:
|
||||
void drawAxes(QPainter *, const QStyleOptionGraphicsItem *);
|
||||
@ -89,8 +81,6 @@ class Element : public QGraphicsItem {
|
||||
bool peut_relier_ses_propres_terminals;
|
||||
void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
|
||||
void updatePixmap();
|
||||
Terminal::Orientation nextOrientation(Terminal::Orientation o) const;
|
||||
Terminal::Orientation previousOrientation(Terminal::Orientation o) const;
|
||||
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
|
||||
@return L'orientation actuelle de l'element
|
||||
*/
|
||||
inline Terminal::Orientation Element::orientation() const {
|
||||
inline const OrientationSet & Element::orientation() const {
|
||||
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
|
||||
|
@ -135,3 +135,20 @@ bool ElementsCategory::remove() const {
|
||||
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 &);
|
||||
bool write() const;
|
||||
bool remove() const;
|
||||
bool isWritable() const;
|
||||
//bool move(const QString &new_parent);
|
||||
|
||||
private:
|
||||
|
@ -29,6 +29,16 @@ ElementsCategoryEditor::ElementsCategoryEditor(const QString &category_path, boo
|
||||
names_list -> setNames(cat_names);
|
||||
//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
|
||||
*/
|
||||
void ElementsCategoryEditor::acceptCreation() {
|
||||
if (!category -> isWritable()) QDialog::accept();
|
||||
|
||||
// il doit y avoir au moins un nom
|
||||
if (!names_list -> checkOneName()) return;
|
||||
|
||||
@ -83,6 +95,8 @@ void ElementsCategoryEditor::acceptCreation() {
|
||||
categorie
|
||||
*/
|
||||
void ElementsCategoryEditor::acceptUpdate() {
|
||||
if (!category -> isWritable()) QDialog::accept();
|
||||
|
||||
// il doit y avoir au moins un nom
|
||||
if (!names_list -> checkOneName()) return;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "elementspanel.h"
|
||||
#include "customelement.h"
|
||||
#include "elementscategory.h"
|
||||
#include "elementscategoryeditor.h"
|
||||
#include "customelement.h"
|
||||
#include "customelementeditor.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@ -33,6 +35,9 @@ ElementsPanel::ElementsPanel(QWidget *parent) : QTreeWidget(parent) {
|
||||
qp.setColor(QPalette::Highlight, QColor("#678db2"));
|
||||
qp.setColor(QPalette::HighlightedText, Qt::white);
|
||||
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"));
|
||||
qtwi_dossier -> setBackground(0, QBrush(t));
|
||||
qtwi_dossier -> setExpanded(true);
|
||||
qtwi_dossier -> setData(0, 42, adr_dossier);
|
||||
|
||||
// ajout des sous-categories / sous-dossiers
|
||||
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
|
||||
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());
|
||||
|
||||
public slots:
|
||||
void slot_doubleClick(QTreeWidgetItem *, int);
|
||||
void dragMoveEvent(QDragMoveEvent *);
|
||||
void dropEvent(QDropEvent *);
|
||||
void startDrag(Qt::DropActions);
|
||||
|
@ -35,6 +35,6 @@ ElementsPanelWidget::~ElementsPanelWidget() {
|
||||
Appelle l'assistant de creation de nouvel element
|
||||
*/
|
||||
void ElementsPanelWidget::newElement() {
|
||||
NewElementWizard *new_element_wizard = new NewElementWizard();
|
||||
new_element_wizard -> exec();
|
||||
NewElementWizard new_element_wizard;
|
||||
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
|
||||
@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();
|
||||
setLayout(names_list_layout);
|
||||
|
||||
@ -32,6 +32,7 @@ NamesListWidget::~NamesListWidget() {
|
||||
*/
|
||||
void NamesListWidget::addLine() {
|
||||
clean();
|
||||
if (read_only) return;
|
||||
QTreeWidgetItem *qtwi = new QTreeWidgetItem();
|
||||
qtwi -> setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
|
||||
tree_names -> addTopLevelItem(qtwi);
|
||||
@ -45,8 +46,8 @@ bool NamesListWidget::checkOneName() {
|
||||
if (!hash_names.count()) {
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
tr("La cat\351gorie doit avoir au moins un nom."),
|
||||
tr("Vous devez entrer au moins un nom pour la cat\351gorie.")
|
||||
tr("Il doit y avoir au moins un nom."),
|
||||
tr("Vous devez entrer au moins un nom.")
|
||||
);
|
||||
return(false);
|
||||
}
|
||||
@ -62,7 +63,7 @@ void NamesListWidget::updateHash() {
|
||||
for (int i = 0 ; i < names_count ; ++ i) {
|
||||
QString lang = tree_names -> topLevelItem(i) -> text(0);
|
||||
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;
|
||||
values << lang << value;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
QPushButton *button_add_line;
|
||||
NamesList hash_names;
|
||||
bool read_only;
|
||||
|
||||
// methodes
|
||||
public:
|
||||
bool checkOneName();
|
||||
NamesList names();
|
||||
void setNames(const NamesList &);
|
||||
void setReadOnly(bool);
|
||||
bool isReadOnly() const;
|
||||
|
||||
private:
|
||||
void clean();
|
||||
@ -35,5 +38,9 @@ class NamesListWidget : public QWidget {
|
||||
|
||||
public slots:
|
||||
void addLine();
|
||||
void check();
|
||||
|
||||
signals:
|
||||
void inputChecked();
|
||||
};
|
||||
#endif
|
||||
|
@ -2,8 +2,10 @@
|
||||
#include "elementscategorieswidget.h"
|
||||
#include "elementscategorieslist.h"
|
||||
#include "nameslistwidget.h"
|
||||
#include "orientationsetwidget.h"
|
||||
#include "diagram.h"
|
||||
#include "element.h"
|
||||
#include "customelementeditor.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@ -76,6 +78,7 @@ void NewElementWizard::previous() {
|
||||
case Names:
|
||||
current_state = Filename;
|
||||
step2 -> show();
|
||||
qle_filename -> setFocus();
|
||||
step3 -> hide();
|
||||
break;
|
||||
case Dimensions:
|
||||
@ -102,6 +105,7 @@ void NewElementWizard::next() {
|
||||
current_state = Filename;
|
||||
step1 -> hide();
|
||||
step2 -> show();
|
||||
qle_filename -> setFocus();
|
||||
button_previous -> setEnabled(true);
|
||||
break;
|
||||
case Filename:
|
||||
@ -158,7 +162,9 @@ void NewElementWizard::buildStep2() {
|
||||
explication2 -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||||
explication2 -> setWordWrap(true);
|
||||
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 -> addSpacing(100);
|
||||
step2 -> setLayout(step2_layout);
|
||||
@ -266,37 +272,12 @@ void NewElementWizard::buildStep5() {
|
||||
explication -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
||||
explication -> setWordWrap(true);
|
||||
|
||||
#define MK_COMBO_BOX(a) a##_orientation = new QComboBox(); \
|
||||
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);
|
||||
orientation_set = new OrientationSetWidget();
|
||||
|
||||
QVBoxLayout *step5_layout = new QVBoxLayout();
|
||||
step5_layout -> addWidget(explication);
|
||||
step5_layout -> addLayout(qgl);
|
||||
step5_layout -> addSpacing(75);
|
||||
step5_layout -> addWidget(orientation_set);
|
||||
step5_layout -> addSpacing(25);
|
||||
step5 -> setLayout(step5_layout);
|
||||
}
|
||||
|
||||
@ -349,6 +330,7 @@ bool NewElementWizard::validStep2() {
|
||||
return(answer == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
chosen_file = dir_path + "/" + file_name;
|
||||
return(true);
|
||||
}
|
||||
|
||||
@ -377,19 +359,7 @@ bool NewElementWizard::validStep4() {
|
||||
@return true si l'etape est validee, false sinon
|
||||
*/
|
||||
bool NewElementWizard::validStep5() {
|
||||
int nb_orientations = 0;
|
||||
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);
|
||||
}
|
||||
// l'editeur d'orientations se charge deja de valider tout ca
|
||||
return(true);
|
||||
}
|
||||
|
||||
@ -445,6 +415,12 @@ void NewElementWizard::updateHotspotLimits() {
|
||||
Cree le nouvel element
|
||||
*/
|
||||
void NewElementWizard::createNewElement() {
|
||||
/// @todo
|
||||
QMessageBox::warning(this, "Creation de l'element", "Not Implemented Yet");
|
||||
CustomElementEditor *edit_new_element = new CustomElementEditor(parentWidget());
|
||||
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 NamesListWidget;
|
||||
class OrientationSetWidget;
|
||||
class Diagram;
|
||||
class NewElementWizard : public QDialog {
|
||||
Q_OBJECT
|
||||
@ -38,6 +39,7 @@ class NewElementWizard : public QDialog {
|
||||
QSpinBox *sb_hotspot_x;
|
||||
QSpinBox *sb_hotspot_y;
|
||||
NamesListWidget *element_names;
|
||||
OrientationSetWidget *orientation_set;
|
||||
QPushButton *button_previous;
|
||||
QPushButton *button_next;
|
||||
WizardState current_state;
|
||||
@ -47,6 +49,7 @@ class NewElementWizard : public QDialog {
|
||||
QComboBox *east_orientation;
|
||||
QComboBox *south_orientation;
|
||||
QComboBox *west_orientation;
|
||||
QString chosen_file;
|
||||
|
||||
// methodes
|
||||
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
|
||||
TARGET =
|
||||
DEPENDPATH += . lang
|
||||
INCLUDEPATH += .
|
||||
DEPENDPATH += . editor lang
|
||||
INCLUDEPATH += . editor
|
||||
|
||||
# Input
|
||||
HEADERS += aboutqet.h \
|
||||
@ -28,8 +28,28 @@ HEADERS += aboutqet.h \
|
||||
nameslist.h \
|
||||
nameslistwidget.h \
|
||||
newelementwizard.h \
|
||||
qet.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 \
|
||||
borderinset.cpp \
|
||||
conducer.cpp \
|
||||
@ -52,9 +72,27 @@ SOURCES += aboutqet.cpp \
|
||||
nameslistwidget.cpp \
|
||||
newelementwizard.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
|
||||
TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts
|
||||
CONFIG += debug warn_on
|
||||
QT += xml
|
||||
|
||||
|
@ -2,39 +2,56 @@
|
||||
<qresource>
|
||||
<file>ico/qet.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_ok.png</file>
|
||||
<file>ico/circle.png</file>
|
||||
<file>ico/configure.png</file>
|
||||
<file>ico/copy.png</file>
|
||||
<file>ico/cut.png</file>
|
||||
<file>ico/delete.png</file>
|
||||
<file>ico/east.png</file>
|
||||
<file>ico/editdelete.png</file>
|
||||
<file>ico/ellipse.png</file>
|
||||
<file>ico/entrer_fs.png</file>
|
||||
<file>ico/exit.png</file>
|
||||
<file>ico/export.png</file>
|
||||
<file>ico/fileclose.png</file>
|
||||
<file>ico/forbidden.png</file>
|
||||
<file>ico/import.png</file>
|
||||
<file>ico/info.png</file>
|
||||
<file>ico/line.png</file>
|
||||
<file>ico/masquer.png</file>
|
||||
<file>ico/move.png</file>
|
||||
<file>ico/new.png</file>
|
||||
<file>ico/north.png</file>
|
||||
<file>ico/open.png</file>
|
||||
<file>ico/orientations.png</file>
|
||||
<file>ico/paste.png</file>
|
||||
<file>ico/pivoter.png</file>
|
||||
<file>ico/polygon.png</file>
|
||||
<file>ico/print.png</file>
|
||||
<file>ico/qt.png</file>
|
||||
<file>ico/redo.png</file>
|
||||
<file>ico/reload.png</file>
|
||||
<file>ico/remove_col.png</file>
|
||||
<file>ico/restaurer.png</file>
|
||||
<file>ico/saveas.png</file>
|
||||
<file>ico/save.png</file>
|
||||
<file>ico/select.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/undo.png</file>
|
||||
<file>ico/viewmagfit.png</file>
|
||||
<file>ico/viewmag-.png</file>
|
||||
<file>ico/viewmag.png</file>
|
||||
<file>ico/viewmag+.png</file>
|
||||
<file>ico/west.png</file>
|
||||
</qresource>
|
||||
</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);
|
||||
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);
|
||||
add_column = new QAction( tr("Ajouter une colonne"), this);
|
||||
remove_column = new QAction( tr("Enlever une colonne"), this);
|
||||
add_column = new QAction(QIcon(":/ico/add_col.png"), tr("Ajouter 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);
|
||||
shrink_diagram = new QAction( tr("R\351tr\351cir le sch\351ma"), this);
|
||||
|
||||
|
52
terminal.cpp
@ -3,27 +3,32 @@
|
||||
#include "element.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.
|
||||
@param pf position du point d'amarrage pour un conducteur
|
||||
@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
|
||||
amarrage_conducer = pf;
|
||||
|
||||
// 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;
|
||||
|
||||
// calcul de la position du point d'amarrage a l'element
|
||||
amarrage_elmt = amarrage_conducer;
|
||||
switch(sens) {
|
||||
case Terminal::Nord : amarrage_elmt += QPointF(0, TAILLE_BORNE); break;
|
||||
case Terminal::Est : amarrage_elmt += QPointF(-TAILLE_BORNE, 0); break;
|
||||
case Terminal::Ouest : amarrage_elmt += QPointF(TAILLE_BORNE, 0); break;
|
||||
case Terminal::Sud :
|
||||
default : amarrage_elmt += QPointF(0, -TAILLE_BORNE);
|
||||
case QET::North: amarrage_elmt += QPointF(0, TAILLE_BORNE); break;
|
||||
case QET::East : amarrage_elmt += QPointF(-TAILLE_BORNE, 0); break;
|
||||
case QET::West : amarrage_elmt += QPointF(TAILLE_BORNE, 0); break;
|
||||
case QET::South:
|
||||
default : amarrage_elmt += QPointF(0, -TAILLE_BORNE);
|
||||
}
|
||||
|
||||
// par defaut : pas de conducteur
|
||||
@ -36,18 +41,16 @@ void Terminal::initialise(QPointF pf, Terminal::Orientation o) {
|
||||
setAcceptedMouseButtons(Qt::LeftButton);
|
||||
hovered = false;
|
||||
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
|
||||
*/
|
||||
Terminal::Terminal() : QGraphicsItem(0, 0) {
|
||||
initialise(QPointF(0.0, 0.0), Terminal::Sud);
|
||||
Terminal::Terminal() :
|
||||
QGraphicsItem(0, 0),
|
||||
couleur_hovered(Terminal::couleur_neutre)
|
||||
{
|
||||
initialise(QPointF(0.0, 0.0), QET::South);
|
||||
diagram_scene = 0;
|
||||
}
|
||||
|
||||
@ -58,7 +61,10 @@ Terminal::Terminal() : QGraphicsItem(0, 0) {
|
||||
@param e Element auquel cette borne appartient
|
||||
@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);
|
||||
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 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);
|
||||
}
|
||||
|
||||
@ -93,19 +102,18 @@ Terminal::~Terminal() {
|
||||
pivote. Sinon elle renvoie son sens normal.
|
||||
@return L'orientation actuelle de la Terminal.
|
||||
*/
|
||||
Terminal::Orientation Terminal::orientation() const {
|
||||
//true pour une orientation verticale, false pour une orientation horizontale
|
||||
QET::Orientation Terminal::orientation() const {
|
||||
if (Element *elt = qgraphicsitem_cast<Element *>(parentItem())) {
|
||||
// orientations actuelle et par defaut de l'element
|
||||
Terminal::Orientation ori_cur = elt -> orientation();
|
||||
Terminal::Orientation ori_def = elt -> defaultOrientation();
|
||||
QET::Orientation ori_cur = elt -> orientation().current();
|
||||
QET::Orientation ori_def = elt -> orientation().defaultOrientation();
|
||||
if (ori_cur == ori_def) return(sens);
|
||||
else {
|
||||
// calcul l'angle de rotation implique par l'orientation de l'element parent
|
||||
// angle de rotation de la borne sur la scene, divise par 90
|
||||
int angle = ori_cur - ori_def + sens;
|
||||
while (angle >= 4) angle -= 4;
|
||||
return((Terminal::Orientation)angle);
|
||||
return((QET::Orientation)angle);
|
||||
}
|
||||
} else return(sens);
|
||||
}
|
||||
@ -410,7 +418,7 @@ bool Terminal::valideXml(QDomElement &terminal) {
|
||||
// parse l'orientation
|
||||
int terminal_or = terminal.attribute("orientation").toInt(&conv_ok);
|
||||
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
|
||||
return(true);
|
||||
|
24
terminal.h
@ -3,6 +3,7 @@
|
||||
#define TAILLE_BORNE 4
|
||||
#include <QtGui>
|
||||
#include <QtXml>
|
||||
#include "qet.h"
|
||||
class Conducer;
|
||||
class Diagram;
|
||||
class Element;
|
||||
@ -14,10 +15,9 @@ class Terminal : public QGraphicsItem {
|
||||
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
enum Orientation {Nord, Est, Sud, Ouest};
|
||||
Terminal();
|
||||
Terminal(QPointF, Terminal::Orientation, Element * = 0, Diagram * = 0);
|
||||
Terminal(qreal, qreal, Terminal::Orientation, Element * = 0, Diagram * = 0);
|
||||
Terminal(QPointF, QET::Orientation, Element * = 0, Diagram * = 0);
|
||||
Terminal(qreal, qreal, QET::Orientation, Element * = 0, Diagram * = 0);
|
||||
virtual ~Terminal();
|
||||
|
||||
private:
|
||||
@ -39,7 +39,7 @@ class Terminal : public QGraphicsItem {
|
||||
|
||||
// methodes de lecture
|
||||
QList<Conducer *> conducers() const;
|
||||
Terminal::Orientation orientation() const;
|
||||
QET::Orientation orientation() const;
|
||||
QPointF amarrageConducer() const;
|
||||
void updateConducer(QPointF = QPointF());
|
||||
|
||||
@ -61,6 +61,12 @@ class Terminal : public QGraphicsItem {
|
||||
public:
|
||||
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:
|
||||
// pointeur vers la QGraphicsScene de type Diagram (evite quelques casts en interne)
|
||||
Diagram *diagram_scene;
|
||||
@ -68,7 +74,7 @@ class Terminal : public QGraphicsItem {
|
||||
QPointF amarrage_conducer;
|
||||
QPointF amarrage_elmt;
|
||||
// orientation de la borne
|
||||
Terminal::Orientation sens;
|
||||
QET::Orientation sens;
|
||||
// liste des conducers lies a cette borne
|
||||
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
|
||||
@ -76,13 +82,9 @@ class Terminal : public QGraphicsItem {
|
||||
Terminal *terminal_precedente;
|
||||
bool hovered;
|
||||
// methode initialisant les differents membres de la borne
|
||||
void initialise(QPointF, Terminal::Orientation);
|
||||
// differentes couleurs utilisables pour l'effet "hover"
|
||||
void initialise(QPointF, QET::Orientation);
|
||||
// couleur de l'effet hover de la patte
|
||||
QColor couleur_hovered;
|
||||
QColor couleur_neutre;
|
||||
QColor couleur_autorise;
|
||||
QColor couleur_prudence;
|
||||
QColor couleur_interdit;
|
||||
};
|
||||
|
||||
/**
|
||||
|