2007-12-01 10:47:15 +00:00
|
|
|
/*
|
2014-01-29 18:37:45 +00:00
|
|
|
Copyright 2006-2014 The QElectroTech Team
|
2007-12-01 10:47:15 +00:00
|
|
|
This file is part of QElectroTech.
|
|
|
|
|
|
|
|
QElectroTech is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
QElectroTech is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2007-07-10 22:54:22 +00:00
|
|
|
#include "partarc.h"
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
|
|
|
Constructeur
|
|
|
|
@param editor L'editeur d'element concerne
|
|
|
|
@param parent Le QGraphicsItem parent de cet arc
|
|
|
|
@param scene La scene sur laquelle figure cet arc
|
|
|
|
*/
|
2007-08-25 03:43:05 +00:00
|
|
|
PartArc::PartArc(QETElementEditor *editor, QGraphicsItem *parent, QGraphicsScene *scene) :
|
|
|
|
CustomElementGraphicPart(editor),
|
2014-05-29 13:46:04 +00:00
|
|
|
QGraphicsEllipseItem(parent, scene),
|
2007-07-10 22:54:22 +00:00
|
|
|
_angle(-90),
|
|
|
|
start_angle(0)
|
|
|
|
{
|
2013-02-08 22:05:15 +00:00
|
|
|
setFlags(QGraphicsItem::ItemIsSelectable);
|
2010-01-20 00:16:55 +00:00
|
|
|
#if QT_VERSION >= 0x040600
|
|
|
|
setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
|
|
|
|
#endif
|
2007-07-10 22:54:22 +00:00
|
|
|
setAcceptedMouseButtons(Qt::LeftButton);
|
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/// Destructeur
|
|
|
|
PartArc::~PartArc() {
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Dessine l'arc de cercle
|
|
|
|
@param painter QPainter a utiliser pour rendre le dessin
|
|
|
|
@param options Options pour affiner le rendu
|
|
|
|
@param widget Widget sur lequel le rendu est effectue
|
|
|
|
*/
|
2009-11-22 16:12:22 +00:00
|
|
|
void PartArc::paint(QPainter *painter, const QStyleOptionGraphicsItem *options, QWidget *widget) {
|
|
|
|
Q_UNUSED(widget);
|
2007-07-10 22:54:22 +00:00
|
|
|
applyStylesToQPainter(*painter);
|
|
|
|
// enleve systematiquement la couleur de fond
|
|
|
|
painter -> setBrush(Qt::NoBrush);
|
|
|
|
QPen t = painter -> pen();
|
2009-04-18 18:54:25 +00:00
|
|
|
t.setCosmetic(options && options -> levelOfDetail < 1.0);
|
|
|
|
painter -> setPen(t);
|
|
|
|
|
2007-07-10 22:54:22 +00:00
|
|
|
if (isSelected()) {
|
|
|
|
// dessine l'ellipse en noir
|
|
|
|
painter -> drawEllipse(rect());
|
|
|
|
|
|
|
|
// dessine l'arc en rouge
|
|
|
|
t.setColor(Qt::red);
|
|
|
|
painter -> setPen(t);
|
|
|
|
}
|
2009-04-18 18:54:25 +00:00
|
|
|
|
2007-07-10 22:54:22 +00:00
|
|
|
painter -> drawArc(rect(), start_angle * 16, _angle * 16);
|
|
|
|
if (isSelected()) {
|
|
|
|
// dessine la croix au centre de l'ellipse
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
|
|
|
Exporte l'arc de cercle en XML
|
|
|
|
@param xml_document Document XML a utiliser pour creer l'element XML
|
|
|
|
@return un element XML decrivant l'arc de cercle
|
|
|
|
*/
|
2007-07-10 22:54:22 +00:00
|
|
|
const QDomElement PartArc::toXml(QDomDocument &xml_document) const {
|
|
|
|
QDomElement xml_element = xml_document.createElement("arc");
|
|
|
|
QPointF top_left(sceneTopLeft());
|
2008-08-23 19:27:14 +00:00
|
|
|
xml_element.setAttribute("x", QString("%1").arg(top_left.x()));
|
|
|
|
xml_element.setAttribute("y", QString("%1").arg(top_left.y()));
|
|
|
|
xml_element.setAttribute("width", QString("%1").arg(rect().width()));
|
|
|
|
xml_element.setAttribute("height", QString("%1").arg(rect().height()));
|
|
|
|
xml_element.setAttribute("start", QString("%1").arg(start_angle));
|
|
|
|
xml_element.setAttribute("angle", QString("%1").arg(_angle));
|
2007-07-10 22:54:22 +00:00
|
|
|
stylesToXml(xml_element);
|
|
|
|
return(xml_element);
|
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
|
|
|
Importe les proprietes d'un arc de cercle depuis un element XML
|
|
|
|
@param qde Element XML a lire
|
|
|
|
*/
|
2007-07-10 22:54:22 +00:00
|
|
|
void PartArc::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()
|
|
|
|
)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
setStartAngle(qde.attribute("start", "0").toInt());
|
|
|
|
setAngle(qde.attribute("angle", "-90").toInt());
|
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
|
|
|
@return le coin superieur gauche du rectangle dans lequel s'inscrit
|
|
|
|
l'ellipse dont fait partie cet arc, dans les coordonnees de la scene.
|
|
|
|
*/
|
2007-07-10 22:54:22 +00:00
|
|
|
QPointF PartArc::sceneTopLeft() const {
|
|
|
|
return(mapToScene(rect().topLeft()));
|
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
2014-05-29 13:46:04 +00:00
|
|
|
* @brief PartArc::setX
|
|
|
|
* @param x is the center of the rect bounding this ellipse
|
|
|
|
*/
|
|
|
|
void PartArc::setX(const qreal x) {
|
|
|
|
QRectF current_rect = rect();
|
|
|
|
QPointF current_pos = mapToScene(current_rect.center());
|
|
|
|
setRect(current_rect.translated(x - current_pos.x(), 0.0));
|
2007-08-25 03:43:05 +00:00
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
2014-05-29 13:46:04 +00:00
|
|
|
* @brief PartArc::setY
|
|
|
|
* @param y is the center of the rect bounding this ellipse
|
|
|
|
*/
|
|
|
|
void PartArc::setY(const qreal y) {
|
|
|
|
QRectF current_rect = rect();
|
|
|
|
QPointF current_pos = mapToScene(current_rect.center());
|
|
|
|
setRect(current_rect.translated(0.0, y - current_pos.y()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief PartArc::setWidth
|
|
|
|
* @param w is the width of the rect bounding this ellipse
|
|
|
|
*/
|
|
|
|
void PartArc::setWidth(const qreal w) {
|
|
|
|
qreal new_width = qAbs(w);
|
|
|
|
QRectF current_rect = rect();
|
|
|
|
current_rect.translate((new_width - current_rect.width()) / -2.0, 0.0);
|
|
|
|
current_rect.setWidth(new_width);
|
|
|
|
setRect(current_rect);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief PartArc::setHeight
|
|
|
|
* @param h is the heigth of the rect bounding this ellipse
|
|
|
|
*/
|
|
|
|
void PartArc::setHeight(const qreal h) {
|
|
|
|
qreal new_height = qAbs(h);
|
|
|
|
QRectF current_rect = rect();
|
|
|
|
current_rect.translate(0.0, (new_height - current_rect.height()) / -2.0);
|
|
|
|
current_rect.setHeight(new_height);
|
|
|
|
setRect(current_rect);
|
2007-08-25 03:43:05 +00:00
|
|
|
}
|
|
|
|
|
2007-12-05 21:16:01 +00:00
|
|
|
/**
|
|
|
|
Gere les changements intervenant sur cette partie
|
|
|
|
@param change Type de changement
|
|
|
|
@param value Valeur numerique relative au changement
|
|
|
|
*/
|
2007-07-10 22:54:22 +00:00
|
|
|
QVariant PartArc::itemChange(GraphicsItemChange change, const QVariant &value) {
|
|
|
|
if (scene()) {
|
2010-02-18 00:42:41 +00:00
|
|
|
if (change == QGraphicsItem::ItemPositionChange || change == QGraphicsItem::ItemPositionHasChanged) {
|
|
|
|
updateCurrentPartEditor();
|
2007-07-10 22:54:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return(QGraphicsEllipseItem::itemChange(change, value));
|
|
|
|
}
|
|
|
|
|
2007-12-15 21:57:00 +00:00
|
|
|
/**
|
|
|
|
@return true si cette partie n'est pas pertinente et ne merite pas d'etre
|
|
|
|
conservee / enregistree.
|
|
|
|
Un arc est pertinent des lors que ses dimensions et son etendue ne sont
|
|
|
|
pas nulles.
|
|
|
|
*/
|
|
|
|
bool PartArc::isUseless() const {
|
|
|
|
return(rect().isNull() || !angle());
|
|
|
|
}
|
2008-01-07 19:40:08 +00:00
|
|
|
|
2013-02-11 18:35:13 +00:00
|
|
|
/**
|
|
|
|
@return the minimum, margin-less rectangle this part can fit into, in scene
|
|
|
|
coordinates. It is different from boundingRect() because it is not supposed
|
|
|
|
to imply any margin, and it is different from shape because it is a regular
|
|
|
|
rectangle, not a complex shape.
|
|
|
|
*/
|
|
|
|
QRectF PartArc::sceneGeometricRect() const {
|
|
|
|
return(mapToScene(rect()).boundingRect());
|
|
|
|
}
|
|
|
|
|
2013-02-08 22:05:12 +00:00
|
|
|
/**
|
|
|
|
Start the user-induced transformation, provided this primitive is contained
|
|
|
|
within the \a initial_selection_rect bounding rectangle.
|
|
|
|
*/
|
|
|
|
void PartArc::startUserTransformation(const QRectF &initial_selection_rect) {
|
|
|
|
Q_UNUSED(initial_selection_rect)
|
|
|
|
saved_points_.clear();
|
|
|
|
saved_points_ << mapToScene(rect().topLeft()) << mapToScene(rect().bottomRight());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
Handle the user-induced transformation from \a initial_selection_rect to \a new_selection_rect
|
|
|
|
*/
|
|
|
|
void PartArc::handleUserTransformation(const QRectF &initial_selection_rect, const QRectF &new_selection_rect) {
|
|
|
|
QList<QPointF> mapped_points = mapPoints(initial_selection_rect, new_selection_rect, saved_points_);
|
|
|
|
setRect(QRectF(mapFromScene(mapped_points.at(0)), mapFromScene(mapped_points.at(1))));
|
|
|
|
}
|
|
|
|
|
2008-01-07 19:40:08 +00:00
|
|
|
/**
|
|
|
|
@return le rectangle delimitant cette partie.
|
|
|
|
*/
|
|
|
|
QRectF PartArc::boundingRect() const {
|
|
|
|
qreal adjust = 1.5;
|
|
|
|
QRectF r(QGraphicsEllipseItem::boundingRect().normalized());
|
|
|
|
r.adjust(-adjust, -adjust, adjust, adjust);
|
|
|
|
return(r);
|
|
|
|
}
|