diff --git a/sources/editor/esevent/eseventaddline.cpp b/sources/editor/esevent/eseventaddline.cpp index 56c726070..00a25ba21 100644 --- a/sources/editor/esevent/eseventaddline.cpp +++ b/sources/editor/esevent/eseventaddline.cpp @@ -59,8 +59,7 @@ bool ESEventAddLine::mousePressEvent(QGraphicsSceneMouseEvent *event) { if (!m_line) { m_line = new PartLine(m_editor); m_scene -> addItem(m_line); - m_line -> setP1(pos); - m_line -> setP2(pos); + m_line->setLine(QLineF(pos, pos)); return true; } @@ -81,11 +80,14 @@ bool ESEventAddLine::mousePressEvent(QGraphicsSceneMouseEvent *event) { * @param event * @return */ -bool ESEventAddLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { +bool ESEventAddLine::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ updateHelpCross (event -> scenePos()); if (!m_line) return false; - m_line -> setP2(m_scene -> snapToGrid(event -> scenePos())); + QLineF line = m_line->line(); + line.setP2(m_scene -> snapToGrid(event -> scenePos())); + m_line -> setLine(line); return true; } diff --git a/sources/editor/graphicspart/partline.cpp b/sources/editor/graphicspart/partline.cpp index 416fb8170..6ca6c040e 100644 --- a/sources/editor/graphicspart/partline.cpp +++ b/sources/editor/graphicspart/partline.cpp @@ -139,46 +139,6 @@ void PartLine::fromXml(const QDomElement &qde) { second_length = qde.attribute("length2", "1.5").toDouble(); } -/** - * @brief PartLine::p1 - * @return the point p1 of line. - */ -QPointF PartLine::p1() const { - return m_line.p1(); -} - -/** - * @brief PartLine::setP1 - * set first point to P1 - * @param p1 - */ -void PartLine::setP1(const QPointF &p1) -{ - if (p1 == m_line.p1()) return; - prepareGeometryChange(); - m_line.setP1(p1); -} - -/** - * @brief PartLine::p2 - * @return the point p2 of line - */ -QPointF PartLine::p2() const { - return m_line.p2(); -} - -/** - * @brief PartLine::setP2 - * set second point to P2 - * @param p2 - */ -void PartLine::setP2(const QPointF &p2) -{ - if (p2 == m_line.p2()) return; - prepareGeometryChange(); - m_line.setP2(p2); -} - /** * @brief PartLine::mousePressEvent * Handle mouse press event @@ -243,7 +203,7 @@ void PartLine::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) * @return the point p1 in scene coordinate */ QPointF PartLine::sceneP1() const { - return(mapToScene(p1())); + return(mapToScene(m_line.p1())); } /** @@ -251,7 +211,7 @@ QPointF PartLine::sceneP1() const { * @return the point p2 in scen coordinate */ QPointF PartLine::sceneP2() const { - return(mapToScene(p2())); + return(mapToScene(m_line.p2())); } /** @@ -406,10 +366,10 @@ void PartLine::debugPaint(QPainter *painter) painter -> setPen(Qt::red); - foreach(QPointF pointy, fourEndPoints(p1(), p2(), first_length)) + foreach(QPointF pointy, fourEndPoints(m_line.p1(), m_line.p2(), first_length)) painter -> drawEllipse(pointy, 0.1, 0.1); - foreach(QPointF pointy, fourEndPoints(p2(), p1(), second_length)) + foreach(QPointF pointy, fourEndPoints(m_line.p2(), m_line.p1(), second_length)) painter -> drawEllipse(pointy, 0.1, 0.1); painter -> restore(); @@ -526,11 +486,44 @@ QLineF PartLine::line() const { void PartLine::setLine(const QLineF &line) { - if (m_line != line) - { - prepareGeometryChange(); - m_line = line; - } + if (m_line == line) return; + prepareGeometryChange(); + m_line = line; + emit lineChanged(); +} + +void PartLine::setFirstEndType(const Qet::EndType &et) +{ + if (first_end == et) return; + prepareGeometryChange(); + first_end = et; + emit firstEndTypeChanged(); +} + +void PartLine::setSecondEndType(const Qet::EndType &et) +{ + if (second_end == et) return; + prepareGeometryChange(); + second_end = et; + emit secondEndTypeChanged(); +} + +void PartLine::setFirstEndLength(const qreal &l) +{ + qreal length = qMin(qAbs(l), m_line.length()); + if (first_length == length) return; + prepareGeometryChange(); + first_length = length; + emit firstEndLengthChanged(); +} + +void PartLine::setSecondEndLength(const qreal &l) +{ + qreal length = qMin(qAbs(l), m_line.length()); + if (second_length == length) return; + prepareGeometryChange(); + second_length = length; + emit secondEndLengthChanged(); } /** diff --git a/sources/editor/graphicspart/partline.h b/sources/editor/graphicspart/partline.h index 3fa4842f7..6cfda7849 100644 --- a/sources/editor/graphicspart/partline.h +++ b/sources/editor/graphicspart/partline.h @@ -37,24 +37,25 @@ class PartLine : public CustomElementGraphicPart { Q_OBJECT - Q_PROPERTY(QPointF p1 READ p1 WRITE setP1) - Q_PROPERTY(QPointF p2 READ p2 WRITE setP2) Q_PROPERTY(Qet::EndType end1 READ firstEndType WRITE setFirstEndType) Q_PROPERTY(Qet::EndType end2 READ secondEndType WRITE setSecondEndType) Q_PROPERTY(qreal length1 READ firstEndLength WRITE setFirstEndLength) Q_PROPERTY(qreal length2 READ secondEndLength WRITE setSecondEndLength) Q_PROPERTY(QLineF line READ line WRITE setLine) - // constructors, destructor + // constructors, destructor public: - PartLine(QETElementEditor *, QGraphicsItem * = 0); - virtual ~PartLine(); - - private: - PartLine(const PartLine &); - - // attributes + PartLine(QETElementEditor *, QGraphicsItem * = 0); + virtual ~PartLine(); private: + PartLine(const PartLine &); + + signals: + void lineChanged(); + void firstEndTypeChanged(); + void secondEndTypeChanged(); + void firstEndLengthChanged(); + void secondEndLengthChanged(); // methods @@ -85,18 +86,14 @@ class PartLine : public CustomElementGraphicPart QLineF line() const; void setLine(const QLineF &line); - QPointF p1() const; - void setP1 (const QPointF &p1); - QPointF p2 () const; - void setP2 (const QPointF &p2); Qet::EndType firstEndType() const {return first_end;} - void setFirstEndType(const Qet::EndType &et) {first_end = et;} + void setFirstEndType(const Qet::EndType &et); Qet::EndType secondEndType() const {return second_end;} - void setSecondEndType(const Qet::EndType &et) {second_end = et;} + void setSecondEndType(const Qet::EndType &et); qreal firstEndLength() const {return first_length;} - void setFirstEndLength(const qreal &l) {first_length = qMin(qAbs(l), m_line.length());} + void setFirstEndLength(const qreal &l); qreal secondEndLength() const {return second_length;} - void setSecondEndLength(const qreal &l) {second_length = qMin(qAbs(l), m_line.length());} + void setSecondEndLength(const qreal &l); protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/sources/editor/lineeditor.cpp b/sources/editor/lineeditor.cpp index 8e2e5d0b0..fcd5a29a5 100644 --- a/sources/editor/lineeditor.cpp +++ b/sources/editor/lineeditor.cpp @@ -20,6 +20,8 @@ #include "partline.h" #include "qet.h" #include "qeticons.h" +#include "QPropertyUndoCommand/qpropertyundocommand.h" +#include "elementscene.h" /** Constructeur @@ -29,7 +31,8 @@ */ LineEditor::LineEditor(QETElementEditor *editor, PartLine *line, QWidget *parent) : ElementItemEditor(editor, parent), - part(line) + part(line), + m_locked (false) { style_ = new StyleEditor(editor); @@ -89,27 +92,50 @@ LineEditor::~LineEditor() { } /** - Permet de specifier a cet editeur quelle primitive il doit editer. A noter - qu'un editeur peut accepter ou refuser d'editer une primitive. - L'editeur de ligne acceptera d'editer la primitive new_part s'il s'agit d'un - objet de la classe PartLine. - @param new_part Nouvelle primitive a editer - @return true si l'editeur a accepter d'editer la primitive, false sinon -*/ -bool LineEditor::setPart(CustomElementPart *new_part) { - if (!new_part) { + * @brief LineEditor::setPart + * Specifie to this editor the part to edit. + * Note that an editor can accept or refuse to edit a part. This editor accept only PartLine. + * @param new_part + * @return + */ +bool LineEditor::setPart(CustomElementPart *new_part) +{ + if (!new_part) + { + if (part) + { + disconnect(part, &PartLine::lineChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::firstEndTypeChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::secondEndTypeChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::firstEndLengthChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::secondEndLengthChanged, this, &LineEditor::updateForm); + } part = 0; style_ -> setPart(0); return(true); } - if (PartLine *part_line = dynamic_cast(new_part)) { + if (PartLine *part_line = dynamic_cast(new_part)) + { + if (part == part_line) return true; + if (part) + { + disconnect(part, &PartLine::lineChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::firstEndTypeChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::secondEndTypeChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::firstEndLengthChanged, this, &LineEditor::updateForm); + disconnect(part, &PartLine::secondEndLengthChanged, this, &LineEditor::updateForm); + } part = part_line; style_ -> setPart(part); updateForm(); + connect(part, &PartLine::lineChanged, this, &LineEditor::updateForm); + connect(part, &PartLine::firstEndTypeChanged, this, &LineEditor::updateForm); + connect(part, &PartLine::secondEndTypeChanged, this, &LineEditor::updateForm); + connect(part, &PartLine::firstEndLengthChanged, this, &LineEditor::updateForm); + connect(part, &PartLine::secondEndLengthChanged, this, &LineEditor::updateForm); return(true); - } else { - return(false); } + return(false); } /** @@ -135,40 +161,94 @@ QPointF LineEditor::editedP2() const { return part -> mapFromScene(x2->value(), y2->value()); } -/** - Met a jour la ligne a partir des donnees du formulaire -*/ -void LineEditor::updateLine() { - if (!part) return; - part -> setProperty("end1", end1_type -> itemData(end1_type->currentIndex())); - part -> setProperty("length1", end1_length -> value()); - part -> setProperty("end2", end2_type -> itemData(end2_type->currentIndex())); - part -> setProperty("length2", end2_length -> value()); - part -> setProperty("p1", editedP1()); - part -> setProperty("p2", editedP2()); +/// Met a jour le type de la premiere extremite +void LineEditor::updateLineEndType1() +{ + if (m_locked) return; + m_locked = true; + QVariant end = end1_type -> itemData(end1_type->currentIndex()); + + if (end != part->property("end1")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "end1", part->property("end1"), end); + undo->setText(tr("Modifier une ligne")); + elementScene()->undoStack().push(undo); + } + m_locked = false; } -/// Met a jour l'abscisse du premier point de la ligne et cree un objet d'annulation -void LineEditor::updateLineX1() { addChangePartCommand(tr("abscisse point 1"), part, "p1", editedP1()); } -/// Met a jour l'ordonnee du premier point de la ligne et cree un objet d'annulation -void LineEditor::updateLineY1() { addChangePartCommand(tr("ordonnée point 1"), part, "p1", editedP1()); } -/// Met a jour l'abscisse du second point de la ligne et cree un objet d'annulation -void LineEditor::updateLineX2() { addChangePartCommand(tr("abscisse point 2"), part, "p2", editedP2()); } -/// Met a jour l'ordonnee du second point de la ligne et cree un objet d'annulation -void LineEditor::updateLineY2() { addChangePartCommand(tr("ordonnée point 2"), part, "p2", editedP2()); } -/// Met a jour le type de la premiere extremite -void LineEditor::updateLineEndType1() { addChangePartCommand(tr("type fin 1"), part, "end1", end1_type -> itemData(end1_type->currentIndex())); } /// Met a jour la longueur de la premiere extremite -void LineEditor::updateLineEndLength1() { addChangePartCommand(tr("longueur fin 1"), part, "length1", end1_length -> value()); } +void LineEditor::updateLineEndLength1() +{ + if (m_locked) return; + m_locked = true; + double length = end1_length->value(); + + if (length != part->property("length1")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "length1", part->property("length1"), length); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + m_locked = false; +} + /// Met a jour le type de la seconde extremite -void LineEditor::updateLineEndType2() { addChangePartCommand(tr("type fin 2"), part, "end2", end2_type -> itemData(end2_type->currentIndex())); } +void LineEditor::updateLineEndType2() +{ + if (m_locked) return; + m_locked = true; + QVariant end = end2_type -> itemData(end2_type->currentIndex()); + + if (end != part->property("end2")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "end2", part->property("end2"), end); + undo->setText(tr("Modifier une ligne")); + elementScene()->undoStack().push(undo); + } + m_locked = false; +} + /// Met a jour la longueur de la seconde extremite -void LineEditor::updateLineEndLength2() { addChangePartCommand(tr("longueur fin 2"), part, "length2", end2_length -> value()); } +void LineEditor::updateLineEndLength2() +{ + if (m_locked) return; + m_locked = true; + double length = end2_length->value(); + + if (length != part->property("length2")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "length2", part->property("length2"), length); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + m_locked = false; +} + +void LineEditor::lineEditingFinished() +{ + if (m_locked) return; + m_locked = true; + QLineF line (editedP1(), editedP2()); + + if (line != part->property("line")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(part, "line", part->property("line"), line); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + m_locked = false; +} /** - Met a jour le formulaire d'edition -*/ -void LineEditor::updateForm() { + * @brief LineEditor::updateForm + * Update the value of the widgets + */ +void LineEditor::updateForm() +{ if (!part) return; activeConnections(false); QPointF p1(part -> sceneP1()); @@ -185,24 +265,30 @@ void LineEditor::updateForm() { } /** - Active ou desactive les connexionx signaux/slots entre les widgets internes. - @param active true pour activer les connexions, false pour les desactiver -*/ -void LineEditor::activeConnections(bool active) { - if (active) { - connect(x1, SIGNAL(editingFinished()), this, SLOT(updateLineX1())); - connect(y1, SIGNAL(editingFinished()), this, SLOT(updateLineY1())); - connect(x2, SIGNAL(editingFinished()), this, SLOT(updateLineX2())); - connect(y2, SIGNAL(editingFinished()), this, SLOT(updateLineY2())); + * @brief LineEditor::activeConnections + * Enable/disable connection between editor widget and slot editingFinished + * True == enable | false == disable + * @param active + */ +void LineEditor::activeConnections(bool active) +{ + if (active) + { + connect(x1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); + connect(y1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); + connect(x2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); + connect(y2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); connect(end1_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType1())); connect(end1_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength1())); connect(end2_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType2())); connect(end2_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength2())); - } else { - disconnect(x1, SIGNAL(editingFinished()), this, SLOT(updateLineX1())); - disconnect(y1, SIGNAL(editingFinished()), this, SLOT(updateLineY1())); - disconnect(x2, SIGNAL(editingFinished()), this, SLOT(updateLineX2())); - disconnect(y2, SIGNAL(editingFinished()), this, SLOT(updateLineY2())); + } + else + { + disconnect(x1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); + disconnect(y1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); + disconnect(x2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); + disconnect(y2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinished())); disconnect(end1_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType1())); disconnect(end1_length, SIGNAL(editingFinished()), this, SLOT(updateLineEndLength1())); disconnect(end2_type, SIGNAL(currentIndexChanged(int)), this, SLOT(updateLineEndType2())); diff --git a/sources/editor/lineeditor.h b/sources/editor/lineeditor.h index b070be394..55266ffaa 100644 --- a/sources/editor/lineeditor.h +++ b/sources/editor/lineeditor.h @@ -17,32 +17,37 @@ */ #ifndef LINE_EDITOR_H #define LINE_EDITOR_H -#include + #include "elementitemeditor.h" + class PartLine; class StyleEditor; +class QComboBox; +class QDoubleSpinBox; + /** This class provides a widget to edit lines within the element editor. */ class LineEditor : public ElementItemEditor { Q_OBJECT - // constructors, destructor + // constructors, destructor public: LineEditor(QETElementEditor *, PartLine * = 0, QWidget * = 0); virtual ~LineEditor(); private: LineEditor(const LineEditor &); - // attributes + // attributes private: PartLine *part; StyleEditor *style_; QDoubleSpinBox *x1, *y1, *x2, *y2; QComboBox *end1_type, *end2_type; QDoubleSpinBox*end1_length, *end2_length; + bool m_locked; - // methods + // methods public: virtual bool setPart(CustomElementPart *); virtual CustomElementPart *currentPart() const; @@ -50,15 +55,11 @@ class LineEditor : public ElementItemEditor QPointF editedP2() const; public slots: - void updateLine(); - void updateLineX1(); - void updateLineY1(); - void updateLineX2(); - void updateLineY2(); void updateLineEndType1(); void updateLineEndLength1(); void updateLineEndType2(); void updateLineEndLength2(); + void lineEditingFinished(); void updateForm(); private: