Files
qelectrotech-source-mirror/editor/partline.cpp
xavierqet 900439c00e Prise en compte d'un cas particulier pour les lignes dans l'editeur d'elements.
Si une ligne equivalait a un point (= avait ses deux points egaux), la fonction pour calculer les quatre points delimitant la shape renvoyait un resultat stupide, ce qui genereait de nombreux avertissements en mode release et l'echec d'un assert en mode debug.
De plus, l'enregistrement de ce genre de lignes est desormais evite dans la methode toXml().



git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@98 bfdf4180-ca20-0410-9c96-a3a8aa849046
2007-08-13 23:01:48 +00:00

163 lines
4.2 KiB
C++

#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 {
QPointF p1(sceneP1());
QPointF p2(sceneP2());
// cas particulier : on n'enregistre pas les lignes equivalentes a un point
if (p1 == p2) {
QDomElement *null_qdom_elmt = new QDomElement();
return(*null_qdom_elmt);
}
QDomElement xml_element = xml_document.createElement("line");
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 {
const qreal marge = 2.0;
// on a donc A(xa , ya) et B(xb, yb)
QPointF a = line().p1();
QPointF b = line().p2();
QList<QPointF> result;
// cas particulier : la droite se ramene a un point
if (a == b) {
result << QPointF(a.x() - marge, a.y() - marge);
result << QPointF(a.x() - marge, a.y() + marge);
result << QPointF(a.x() + marge, a.y() + marge);
result << QPointF(a.x() + marge, a.y() - marge);
} else {
// 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 * marge;
// 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
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);
}