From 6c84b555861309de2b9898fba195831c089dc976 Mon Sep 17 00:00:00 2001 From: Martin Marmsoler Date: Mon, 22 Jun 2020 23:25:11 +0200 Subject: [PATCH] allow multiedit also for arceditor, ellipse, line, rectangle and show properties when single polygon is selected --- sources/editor/arceditor.cpp | 197 ++++++++++++++++----- sources/editor/arceditor.h | 14 +- sources/editor/ellipseeditor.cpp | 149 +++++++++++++--- sources/editor/ellipseeditor.h | 13 +- sources/editor/lineeditor.cpp | 235 +++++++++++++++++++------- sources/editor/lineeditor.h | 13 +- sources/editor/qetelementeditor.cpp | 37 +++- sources/editor/ui/polygoneditor.cpp | 29 ++-- sources/editor/ui/polygoneditor.h | 9 + sources/editor/ui/rectangleeditor.cpp | 220 +++++++++++++++++++++--- sources/editor/ui/rectangleeditor.h | 14 ++ 11 files changed, 760 insertions(+), 170 deletions(-) diff --git a/sources/editor/arceditor.cpp b/sources/editor/arceditor.cpp index 2b18b6879..8276869e4 100644 --- a/sources/editor/arceditor.cpp +++ b/sources/editor/arceditor.cpp @@ -77,6 +77,23 @@ ArcEditor::ArcEditor(QETElementEditor *editor, PartArc *arc, QWidget *parent) : /// Destructeur ArcEditor::~ArcEditor() {} +void ArcEditor::setUpChangeConnections() +{ + m_change_connections << connect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm); + m_change_connections << connect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm); + m_change_connections << connect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm); + // TODO: implement position changes! + //m_change_connections << connect(part, &PartArc::) +} + +void ArcEditor::disconnectChangeConnections() +{ + for (QMetaObject::Connection c : m_change_connections) { + disconnect(c); + } + m_change_connections.clear(); +} + /** * @brief ArcEditor::setPart * Specifie to this editor the part to edit. @@ -89,11 +106,8 @@ bool ArcEditor::setPart(CustomElementPart *new_part) if (!new_part) { if (part) - { - disconnect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm); - disconnect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm); - disconnect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm); - } + disconnectChangeConnections(); + part = nullptr; style_ -> setPart(nullptr); return(true); @@ -103,23 +117,27 @@ bool ArcEditor::setPart(CustomElementPart *new_part) { if (part == part_arc) return true; if (part) - { - disconnect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm); - disconnect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm); - disconnect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm); - } + disconnectChangeConnections(); part = part_arc; style_ -> setPart(part); updateForm(); - connect(part, &PartArc::rectChanged, this, &ArcEditor::updateForm); - connect(part, &PartArc::spanAngleChanged, this, &ArcEditor::updateForm); - connect(part, &PartArc::startAngleChanged, this, &ArcEditor::updateForm); + setUpChangeConnections(); return(true); } return(false); } +bool ArcEditor::setParts(QList parts) +{ + if (parts.isEmpty()) + return false; + + if (!setPart(parts.first())) + return false; + return style_->setParts(parts); +} + /** * @brief ArcEditor::currentPart * @return the curent edited part, or 0 if there is no edited part @@ -140,15 +158,20 @@ void ArcEditor::updateArcS() { if (m_locked) return; m_locked = true; - double value = start_angle->value() * 16; + double value = start_angle->value() * 16; - if (value != part->property("startAngle")) - { - QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "startAngle", part->property("startAngle"), value); - undo->setText("Modifier l'angle de depart d'un arc"); - undo->enableAnimation(); - elementScene()->undoStack().push(undo); - } + for (auto part: style_->currentParts()) { + + PartArc* arc = static_cast(part); + + if (value != arc->property("startAngle")) + { + QPropertyUndoCommand *undo= new QPropertyUndoCommand(arc, "startAngle", arc->property("startAngle"), value); + undo->setText("Modifier l'angle de depart d'un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } @@ -163,13 +186,17 @@ void ArcEditor::updateArcA() m_locked = true; double value = angle->value() * 16; - if (value != part->property("spanAngle")) - { - QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "spanAngle", part->property("spanAngle"), value); - undo->setText("Modifier l'angle d'un arc"); - undo->enableAnimation(); - elementScene()->undoStack().push(undo); - } + for (auto part: style_->currentParts()) { + + PartArc* arc = static_cast(part); + if (value != arc->property("spanAngle")) + { + QPropertyUndoCommand *undo= new QPropertyUndoCommand(arc, "spanAngle", arc->property("spanAngle"), value); + undo->setText("Modifier l'angle d'un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } @@ -178,24 +205,102 @@ void ArcEditor::updateArcA() * @brief ArcEditor::updateArcRect * Update the geometrie of the rect that define this arc according the the edited values */ -void ArcEditor::updateArcRect() +void ArcEditor::updateArcRectX() { if (m_locked) return; m_locked = true; - QPointF point = part->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2); - QRectF rect(point, QSizeF(h->value(), v->value())); - if (rect != part->property("rect")) - { - QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "rect", part->property("rect"), rect); - undo->setText("Modifier un arc"); - undo->enableAnimation(); - elementScene()->undoStack().push(undo); - } + for (auto part: style_->currentParts()) { + + PartArc* arc = static_cast(part); + QRectF rect = arc->property("rect").toRectF(); + QPointF point = arc->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2); // does not matter which value y is, because only the x value is used + rect.setX(point.x()); // change only the x value + + if (rect != part->property("rect")) + { + QPropertyUndoCommand *undo= new QPropertyUndoCommand(arc, "rect", arc->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } +void ArcEditor::updateArcRectY() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartArc* arc = static_cast(part); + QRectF rect = arc->property("rect").toRectF(); + + QPointF point = arc->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2); + rect.setY(point.y()); + + if (rect != arc->property("rect")) + { + QPropertyUndoCommand *undo= new QPropertyUndoCommand(arc, "rect", arc->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + + } + + m_locked = false; +} + +void ArcEditor::updateArcRectH() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartArc* arc = static_cast(part); + QRectF rect = arc->property("rect").toRectF(); + + if (rect.width() != h->value()) + { + rect.setWidth(h->value()); + QPropertyUndoCommand *undo= new QPropertyUndoCommand(arc, "rect", arc->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void ArcEditor::updateArcRectV() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartArc* arc = static_cast(part); + QRectF rect = arc->property("rect").toRectF(); + + if (rect.height() != v->value()) + { + rect.setHeight(v->value()); + QPropertyUndoCommand *undo= new QPropertyUndoCommand(arc, "rect", arc->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + /** * @brief ArcEditor::updateForm * Update the value of the widgets @@ -224,19 +329,19 @@ void ArcEditor::activeConnections(bool active) { if (active) { - connect(x, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); - connect(y, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); - connect(h, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); - connect(v, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); + connect(x, SIGNAL(editingFinished()), this, SLOT(updateArcRectX())); + connect(y, SIGNAL(editingFinished()), this, SLOT(updateArcRectY())); + connect(h, SIGNAL(editingFinished()), this, SLOT(updateArcRectH())); + connect(v, SIGNAL(editingFinished()), this, SLOT(updateArcRectV())); connect(start_angle, SIGNAL(editingFinished()), this, SLOT(updateArcS())); connect(angle, SIGNAL(editingFinished()), this, SLOT(updateArcA())); } else { - disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); - disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); - disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); - disconnect(v, SIGNAL(editingFinished()), this, SLOT(updateArcRect())); + disconnect(x, SIGNAL(editingFinished()), this, SLOT(updateArcRectX())); + disconnect(y, SIGNAL(editingFinished()), this, SLOT(updateArcRectY())); + disconnect(h, SIGNAL(editingFinished()), this, SLOT(updateArcRectH())); + disconnect(v, SIGNAL(editingFinished()), this, SLOT(updateArcRectV())); disconnect(start_angle, SIGNAL(editingFinished()), this, SLOT(updateArcS())); disconnect(angle, SIGNAL(editingFinished()), this, SLOT(updateArcA())); } diff --git a/sources/editor/arceditor.h b/sources/editor/arceditor.h index 56c345e84..df88557ea 100644 --- a/sources/editor/arceditor.h +++ b/sources/editor/arceditor.h @@ -46,20 +46,32 @@ class ArcEditor : public ElementItemEditor QDoubleSpinBox *x, *y, *h, *v; QSpinBox *angle, *start_angle; bool m_locked; + + QList m_change_connections; // methods public: bool setPart(CustomElementPart *) override; + bool setParts(QList parts) override; CustomElementPart *currentPart() const override; QList currentParts() const override; public slots: void updateArcS(); void updateArcA(); - void updateArcRect(); + void updateArcRectX(); + void updateArcRectY(); + void updateArcRectH(); + void updateArcRectV(); void updateForm() override; private: void activeConnections(bool); + /*! + * \brief setUpChangeConnections + * Setup the connection from the arc(s) to the widget, to update it when the arc(s) are changed (moved ...) + */ + void setUpChangeConnections(); + void disconnectChangeConnections(); }; #endif diff --git a/sources/editor/ellipseeditor.cpp b/sources/editor/ellipseeditor.cpp index e8bec6731..b374f090d 100644 --- a/sources/editor/ellipseeditor.cpp +++ b/sources/editor/ellipseeditor.cpp @@ -70,6 +70,19 @@ EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWi EllipseEditor::~EllipseEditor() { } +void EllipseEditor::setUpChangeConnections() +{ + m_change_connections << connect(part, &PartEllipse::rectChanged, this, &EllipseEditor::updateForm); +} + +void EllipseEditor::disconnectChangeConnections() +{ + for (QMetaObject::Connection c : m_change_connections) { + disconnect(c); + } + m_change_connections.clear(); +} + /** Permet de specifier a cet editeur quelle primitive il doit editer. A noter qu'un editeur peut accepter ou refuser d'editer une primitive. @@ -83,7 +96,7 @@ bool EllipseEditor::setPart(CustomElementPart *new_part) if (!new_part) { if (part) - disconnect(part, &PartEllipse::rectChanged, this, &EllipseEditor::updateForm); + disconnectChangeConnections(); part = nullptr; style_ -> setPart(nullptr); return(true); @@ -92,16 +105,26 @@ bool EllipseEditor::setPart(CustomElementPart *new_part) { if (part == part_ellipse) return true; if (part) - disconnect(part, &PartEllipse::rectChanged, this, &EllipseEditor::updateForm); + disconnectChangeConnections(); part = part_ellipse; style_ -> setPart(part); updateForm(); - connect(part, &PartEllipse::rectChanged, this, &EllipseEditor::updateForm); + setUpChangeConnections(); return(true); } return(false); } +bool EllipseEditor::setParts(QList parts) +{ + if (parts.isEmpty()) + return false; + + if (!setPart(parts.first())) + return false; + return style_->setParts(parts); +} + /** @return la primitive actuellement editee, ou 0 si ce widget n'en edite pas */ @@ -113,22 +136,100 @@ QList EllipseEditor::currentParts() const { return style_->currentParts(); } -void EllipseEditor::editingFinished() +void EllipseEditor::editingFinishedX() { - if (m_locked) return; - m_locked = true; - QPointF point = part->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2); - QRectF rect(point, QSizeF(h->value(), v->value())); + if (m_locked) return; + m_locked = true; - if (rect != part->property("rect")) - { - QPropertyUndoCommand *undo= new QPropertyUndoCommand(part, "rect", part->property("rect"), rect); - undo->setText("Modifier une ellipse"); - undo->enableAnimation(); - elementScene()->undoStack().push(undo); - } + for (auto part: style_->currentParts()) { - m_locked = false; + PartEllipse* ell = static_cast(part); + QRectF rect = ell->property("rect").toRectF(); + QPointF point = ell->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2); // does not matter which value y is, because only the x value is used + rect.setX(point.x()); // change only the x value + + if (rect != part->property("rect")) + { + QPropertyUndoCommand *undo= new QPropertyUndoCommand(ell, "rect", ell->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void EllipseEditor::editingFinishedY() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartEllipse* ell = static_cast(part); + QRectF rect = ell->property("rect").toRectF(); + + QPointF point = ell->mapFromScene(x->value() - h->value()/2, y->value() - v->value()/2); + rect.setY(point.y()); + + if (rect != ell->property("rect")) + { + QPropertyUndoCommand *undo= new QPropertyUndoCommand(ell, "rect", ell->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + + } + + m_locked = false; +} + +void EllipseEditor::editingFinishedH() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartEllipse* ell = static_cast(part); + QRectF rect = ell->property("rect").toRectF(); + + if (rect.width() != h->value()) + { + rect.setWidth(h->value()); + QPropertyUndoCommand *undo= new QPropertyUndoCommand(ell, "rect", ell->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void EllipseEditor::editingFinishedV() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartEllipse* ell = static_cast(part); + QRectF rect = ell->property("rect").toRectF(); + + if (rect.height() != v->value()) + { + rect.setHeight(v->value()); + QPropertyUndoCommand *undo= new QPropertyUndoCommand(ell, "rect", ell->property("rect"), rect); + undo->setText("Modifier un arc"); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; } /** @@ -154,16 +255,16 @@ void EllipseEditor::activeConnections(bool active) { if (active) { - connect(x, SIGNAL(editingFinished()), this, SLOT(editingFinished())); - connect(y, SIGNAL(editingFinished()), this, SLOT(editingFinished())); - connect(h, SIGNAL(editingFinished()), this, SLOT(editingFinished())); - connect(v, SIGNAL(editingFinished()), this, SLOT(editingFinished())); + connect(x, SIGNAL(editingFinished()), this, SLOT(editingFinishedX())); + connect(y, SIGNAL(editingFinished()), this, SLOT(editingFinishedY())); + connect(h, SIGNAL(editingFinished()), this, SLOT(editingFinishedH())); + connect(v, SIGNAL(editingFinished()), this, SLOT(editingFinishedV())); } else { - disconnect(x, SIGNAL(editingFinished()), this, SLOT(editingFinished())); - disconnect(y, SIGNAL(editingFinished()), this, SLOT(editingFinished())); - disconnect(h, SIGNAL(editingFinished()), this, SLOT(editingFinished())); - disconnect(v, SIGNAL(editingFinished()), this, SLOT(editingFinished())); + disconnect(x, SIGNAL(editingFinished()), this, SLOT(editingFinishedX())); + disconnect(y, SIGNAL(editingFinished()), this, SLOT(editingFinishedY())); + disconnect(h, SIGNAL(editingFinished()), this, SLOT(editingFinishedH())); + disconnect(v, SIGNAL(editingFinished()), this, SLOT(editingFinishedV())); } } diff --git a/sources/editor/ellipseeditor.h b/sources/editor/ellipseeditor.h index 91d5d457a..c42ffd029 100644 --- a/sources/editor/ellipseeditor.h +++ b/sources/editor/ellipseeditor.h @@ -44,18 +44,29 @@ class EllipseEditor : public ElementItemEditor StyleEditor *style_; QDoubleSpinBox *x, *y, *h, *v; bool m_locked; + QList m_change_connections; // methods public: bool setPart(CustomElementPart *) override; + bool setParts(QList parts) override; CustomElementPart *currentPart() const override; QList currentParts() const override; public slots: - void editingFinished(); + void editingFinishedX(); + void editingFinishedY(); + void editingFinishedH(); + void editingFinishedV(); void updateForm() override; private: void activeConnections(bool); + /*! + * \brief setUpChangeConnections + * Setup the connection from the ellipse(s) to the widget, to update it when the ellipse(s) are changed (moved ...) + */ + void setUpChangeConnections(); + void disconnectChangeConnections(); }; #endif diff --git a/sources/editor/lineeditor.cpp b/sources/editor/lineeditor.cpp index 92a5a8f08..ca774feb8 100644 --- a/sources/editor/lineeditor.cpp +++ b/sources/editor/lineeditor.cpp @@ -92,6 +92,23 @@ LineEditor::LineEditor(QETElementEditor *editor, PartLine *line, QWidget *parent LineEditor::~LineEditor() { } +void LineEditor::setUpChangeConnections() +{ + m_change_connections << connect(part, &PartLine::lineChanged, this, &LineEditor::updateForm); + m_change_connections << connect(part, &PartLine::firstEndTypeChanged, this, &LineEditor::updateForm); + m_change_connections << connect(part, &PartLine::secondEndTypeChanged, this, &LineEditor::updateForm); + m_change_connections << connect(part, &PartLine::firstEndLengthChanged, this, &LineEditor::updateForm); + m_change_connections << connect(part, &PartLine::secondEndLengthChanged, this, &LineEditor::updateForm); +} + +void LineEditor::disconnectChangeConnections() +{ + for (QMetaObject::Connection c : m_change_connections) { + disconnect(c); + } + m_change_connections.clear(); +} + /** * @brief LineEditor::setPart * Specifie to this editor the part to edit. @@ -105,11 +122,7 @@ bool LineEditor::setPart(CustomElementPart *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); + disconnectChangeConnections(); } part = nullptr; style_ -> setPart(nullptr); @@ -120,25 +133,27 @@ bool LineEditor::setPart(CustomElementPart *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); + disconnectChangeConnections(); } 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); + setUpChangeConnections(); return(true); } return(false); } +bool LineEditor::setParts(QList parts) +{ + if (parts.isEmpty()) + return false; + + if (!setPart(parts.first())) + return false; + return style_->setParts(parts); +} + /** @return la primitive actuellement editee, ou 0 si ce widget n'en edite pas */ @@ -173,12 +188,17 @@ void LineEditor::updateLineEndType1() 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); - } + for (auto part: style_->currentParts()) { + + PartLine* line = static_cast(part); + + if (end != line->property("end1")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(line, "end1", line->property("end1"), end); + undo->setText(tr("Modifier une ligne")); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } @@ -189,13 +209,18 @@ void LineEditor::updateLineEndLength1() 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); - } + for (auto part: style_->currentParts()) { + + PartLine* line = static_cast(part); + + if (length != line->property("length1")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(line, "length1", line->property("length1"), length); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } @@ -206,12 +231,17 @@ void LineEditor::updateLineEndType2() 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); - } + for (auto part: style_->currentParts()) { + + PartLine* line = static_cast(part); + + if (end != line->property("end2")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(line, "end2", line->property("end2"), end); + undo->setText(tr("Modifier une ligne")); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } @@ -222,32 +252,121 @@ void LineEditor::updateLineEndLength2() 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); - } + for (auto part: style_->currentParts()) { + + PartLine* line = static_cast(part); + + if (length != line->property("length2")) + { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(line, "length2", line->property("length2"), length); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } -void LineEditor::lineEditingFinished() +void LineEditor::lineEditingFinishedX1() { 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); - } + for (auto part: style_->currentParts()) { + + PartLine* l = static_cast(part); + QLineF line = l->property("line").toLineF(); + + QPointF p1 = l->mapFromScene(x1->value(), y1->value()); + + if (p1.x() != line.p1().x()) + { + p1.setY(line.p1().y()); // restore old y value + line.setP1(p1); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(l, "line", l->property("line"), line); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } m_locked = false; } +void LineEditor::lineEditingFinishedY1() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartLine* l = static_cast(part); + QLineF line = l->property("line").toLineF(); + + QPointF p1 = l->mapFromScene(x1->value(), y1->value()); + + if (p1.y() != line.p1().y()) + { + p1.setX(line.p1().x()); // restore old x value + line.setP1(p1); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(l, "line", l->property("line"), line); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + m_locked = false; +} + +void LineEditor::lineEditingFinishedX2() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartLine* l = static_cast(part); + QLineF line = l->property("line").toLineF(); + + QPointF p2 = l->mapFromScene(x2->value(), y2->value()); + + if (p2.x() != line.p1().x()) + { + p2.setY(line.p2().y()); // restore old y value + line.setP2(p2); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(l, "line", l->property("line"), line); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + m_locked = false; +} + +void LineEditor::lineEditingFinishedY2() +{ + if (m_locked) return; + m_locked = true; + + for (auto part: style_->currentParts()) { + + PartLine* l = static_cast(part); + QLineF line = l->property("line").toLineF(); + + QPointF p2 = l->mapFromScene(x2->value(), y2->value()); + + if (p2.y() != line.p1().y()) + { + p2.setX(line.p2().x()); // restore old y value + line.setP2(p2); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(l, "line", l->property("line"), line); + undo->setText(tr("Modifier une ligne")); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + m_locked = false; +} + /** * @brief LineEditor::updateForm * Update the value of the widgets @@ -279,10 +398,10 @@ 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(x1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedX1())); + connect(y1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedY1())); + connect(x2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedX2())); + connect(y2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedY2())); 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())); @@ -290,10 +409,10 @@ void LineEditor::activeConnections(bool active) } 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(x1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedX1())); + disconnect(y1, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedY1())); + disconnect(x2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedX2())); + disconnect(y2, SIGNAL(editingFinished()), this, SLOT(lineEditingFinishedY2())); 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 39e80b848..0863d6434 100644 --- a/sources/editor/lineeditor.h +++ b/sources/editor/lineeditor.h @@ -46,10 +46,12 @@ class LineEditor : public ElementItemEditor QComboBox *end1_type, *end2_type; QDoubleSpinBox*end1_length, *end2_length; bool m_locked; + QList m_change_connections; // methods public: bool setPart(CustomElementPart *) override; + bool setParts(QList parts) override; CustomElementPart *currentPart() const override; QList currentParts() const override; QPointF editedP1() const; @@ -60,10 +62,19 @@ class LineEditor : public ElementItemEditor void updateLineEndLength1(); void updateLineEndType2(); void updateLineEndLength2(); - void lineEditingFinished(); + void lineEditingFinishedX1(); + void lineEditingFinishedY1(); + void lineEditingFinishedX2(); + void lineEditingFinishedY2(); void updateForm() override; private: void activeConnections(bool); + /*! + * \brief setUpChangeConnections + * Setup the connection from the line(s) to the widget, to update it when the line(s) are changed (moved ...) + */ + void setUpChangeConnections(); + void disconnectChangeConnections(); }; #endif diff --git a/sources/editor/qetelementeditor.cpp b/sources/editor/qetelementeditor.cpp index 887a679b9..c380a38a8 100644 --- a/sources/editor/qetelementeditor.cpp +++ b/sources/editor/qetelementeditor.cpp @@ -642,7 +642,11 @@ void QETElementEditor::slot_updateInformations() if (same_xml_name) { if (selection_xml_name == "terminal" || selection_xml_name == "text" || - selection_xml_name == "dynamic_text") { + selection_xml_name == "dynamic_text" || + selection_xml_name == "line" || + selection_xml_name == "rect" || + selection_xml_name == "ellipse" || + selection_xml_name == "arc") { clearToolsDock(); //We add the editor widget ElementItemEditor *editor = static_cast(m_editors[selection_xml_name]); @@ -684,7 +688,36 @@ void QETElementEditor::slot_updateInformations() } } return; - } + } else if (selection_xml_name == "polygon" && cep_list.length() == 1) { + // multi edit for polygons makes no sense + // TODO: maybe allowing multipart edit when number of points is the same? + //We add the editor widget + clearToolsDock(); + ElementItemEditor *editor = static_cast(m_editors[selection_xml_name]); + CustomElementPart* part = editor->currentPart(); + bool equal = part == cep_list.first(); + + if (editor) + { + bool success = true; + if (equal == false) { + success = editor->setPart(cep_list.first()); + } + if (success) + { + m_tools_dock_stack->insertWidget(1, editor); + m_tools_dock_stack -> setCurrentIndex(1); + } + else + { + qDebug() << "Editor refused part."; + } + } + return; + + } else { + qDebug() << "Multiedit not supported for: " << cep_list.first()->xmlName(); + } } diff --git a/sources/editor/ui/polygoneditor.cpp b/sources/editor/ui/polygoneditor.cpp index 17a6523fd..b3baf2051 100644 --- a/sources/editor/ui/polygoneditor.cpp +++ b/sources/editor/ui/polygoneditor.cpp @@ -50,6 +50,22 @@ PolygonEditor::~PolygonEditor() { delete ui; } +void PolygonEditor::setUpChangeConnections() +{ + m_change_connections << connect(m_part, &PartPolygon::polygonChanged, this, &PolygonEditor::updateForm); + m_change_connections << connect(m_part, &PartPolygon::closedChange, this, &PolygonEditor::updateForm); + m_change_connections << connect(m_part, &PartPolygon::xChanged, this, &PolygonEditor::updateForm); + m_change_connections << connect(m_part, &PartPolygon::yChanged, this, &PolygonEditor::updateForm); +} + +void PolygonEditor::disconnectChangeConnections() +{ + for (QMetaObject::Connection c : m_change_connections) { + disconnect(c); + } + m_change_connections.clear(); +} + /** * @brief PolygonEditor::setPart * @param new_part @@ -61,8 +77,7 @@ bool PolygonEditor::setPart(CustomElementPart *new_part) { if (m_part) { - disconnect(m_part, &PartPolygon::polygonChanged, this, &PolygonEditor::updateForm); - disconnect(m_part, &PartPolygon::closedChange, this, &PolygonEditor::updateForm); + disconnectChangeConnections(); } m_part = nullptr; m_style -> setPart(nullptr); @@ -73,18 +88,12 @@ bool PolygonEditor::setPart(CustomElementPart *new_part) if (m_part == part_polygon) return true; if (m_part) { - disconnect(m_part, &PartPolygon::polygonChanged, this, &PolygonEditor::updateForm); - disconnect(m_part, &PartPolygon::closedChange, this, &PolygonEditor::updateForm); - disconnect(m_part, &PartPolygon::xChanged, this, &PolygonEditor::updateForm); - disconnect(m_part, &PartPolygon::yChanged, this, &PolygonEditor::updateForm); + disconnectChangeConnections(); } m_part = part_polygon; m_style -> setPart(m_part); updateForm(); - connect(m_part, &PartPolygon::polygonChanged, this, &PolygonEditor::updateForm); - connect(m_part, &PartPolygon::closedChange, this, &PolygonEditor::updateForm); - connect(m_part, &PartPolygon::xChanged, this, &PolygonEditor::updateForm); - connect(m_part, &PartPolygon::yChanged, this, &PolygonEditor::updateForm); + setUpChangeConnections(); return(true); } return(false); diff --git a/sources/editor/ui/polygoneditor.h b/sources/editor/ui/polygoneditor.h index 254596f16..edb5ffae1 100644 --- a/sources/editor/ui/polygoneditor.h +++ b/sources/editor/ui/polygoneditor.h @@ -50,10 +50,19 @@ class PolygonEditor : public ElementItemEditor void on_m_add_point_action_triggered(); void on_m_remove_point_action_triggered(); +private: + /*! + * \brief setUpChangeConnections + * Setup the connection from the line(s) to the widget, to update it when the line(s) are changed (moved ...) + */ + void setUpChangeConnections(); + void disconnectChangeConnections(); + private: Ui::PolygonEditor *ui; StyleEditor *m_style = nullptr; PartPolygon *m_part = nullptr; + QList m_change_connections; }; #endif // POLYGONEDITOR_H diff --git a/sources/editor/ui/rectangleeditor.cpp b/sources/editor/ui/rectangleeditor.cpp index d8b22d797..4628a2626 100644 --- a/sources/editor/ui/rectangleeditor.cpp +++ b/sources/editor/ui/rectangleeditor.cpp @@ -46,6 +46,23 @@ RectangleEditor::~RectangleEditor() { delete ui; } +void RectangleEditor::setUpChangeConnections() +{ + m_change_connections << connect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); + m_change_connections << connect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); + m_change_connections << connect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); + m_change_connections << connect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); + m_change_connections << connect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); +} + +void RectangleEditor::disconnectChangeConnections() +{ + for (QMetaObject::Connection c : m_change_connections) { + disconnect(c); + } + m_change_connections.clear(); +} + /** * @brief RectangleEditor::setPart * @param part @@ -57,11 +74,7 @@ bool RectangleEditor::setPart(CustomElementPart *part) { if (m_part) { - disconnect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); + disconnectChangeConnections(); } m_part = nullptr; m_style->setPart(nullptr); @@ -75,26 +88,28 @@ bool RectangleEditor::setPart(CustomElementPart *part) } if (m_part) { - disconnect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); - disconnect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); + disconnectChangeConnections(); } m_part = part_rectangle; m_style->setPart(m_part); updateForm(); - connect(m_part, &PartRectangle::rectChanged, this, &RectangleEditor::updateForm); - connect(m_part, &PartRectangle::XRadiusChanged, this, &RectangleEditor::updateForm); - connect(m_part, &PartRectangle::YRadiusChanged, this, &RectangleEditor::updateForm); - connect(m_part, &PartRectangle::xChanged, this, &RectangleEditor::updateForm); - connect(m_part, &PartRectangle::yChanged, this, &RectangleEditor::updateForm); + setUpChangeConnections(); return(true); } return(false); } +bool RectangleEditor::setParts(QList parts) +{ + if (parts.isEmpty()) + return false; + + if (!setPart(parts.first())) + return false; + return m_style->setParts(parts); +} + /** * @brief RectangleEditor::currentPart * @return @@ -175,6 +190,157 @@ void RectangleEditor::editingFinished() m_locked = false; } +void RectangleEditor::xPosChanged() +{ + if (m_locked) { + return; + } + m_locked = true; + + for (auto part: m_style->currentParts()) { + + PartRectangle* rec = static_cast(part); + + QRectF rect = rec->rect(); + + QPointF p = rec->mapFromScene(ui->m_x_sb->value(), ui->m_y_sb->value()); + + if (rect.x() != p.x()) { + rect.moveLeft(p.x()); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(rec, "rect", rec->rect(), rect); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void RectangleEditor::yPosChanged() +{ + if (m_locked) { + return; + } + m_locked = true; + + for (auto part: m_style->currentParts()) { + + PartRectangle* rec = static_cast(part); + + QRectF rect = rec->rect(); + + QPointF p = rec->mapFromScene(ui->m_x_sb->value(), ui->m_y_sb->value()); + + if (rect.y() != p.y()) { + rect.moveTop(p.y()); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(rec, "rect", rec->rect(), rect); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void RectangleEditor::widthChanged() +{ + if (m_locked) { + return; + } + m_locked = true; + + double width = ui->m_width_sb->value(); + + for (auto part: m_style->currentParts()) { + + PartRectangle* rec = static_cast(part); + + QRectF rect = rec->rect(); + + if (rect.width() != width) { + rect.setWidth(width); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(rec, "rect", rec->rect(), rect); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void RectangleEditor::heightChanged() +{ + if (m_locked) { + return; + } + m_locked = true; + + double height = ui->m_height_sb->value(); + + for (auto part: m_style->currentParts()) { + + PartRectangle* rec = static_cast(part); + + QRectF rect = rec->rect(); + + if (rect.height() != height) { + rect.setHeight(height); + QPropertyUndoCommand *undo = new QPropertyUndoCommand(rec, "rect", rec->rect(), rect); + undo->enableAnimation(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void RectangleEditor::xRadiusChanged() +{ + if (m_locked) { + return; + } + m_locked = true; + + double radius = ui->m_rx_sb->value(); + + for (auto part: m_style->currentParts()) { + + PartRectangle* rec = static_cast(part); + + if (rec->XRadius() != radius) { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(rec, "xRadius", rec->XRadius(), radius); + undo->setAnimated(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + +void RectangleEditor::yRadiusChanged() +{ + if (m_locked) { + return; + } + m_locked = true; + + double radius = ui->m_ry_sb->value(); + + for (auto part: m_style->currentParts()) { + + PartRectangle* rec = static_cast(part); + + if (rec->YRadius() != radius) { + QPropertyUndoCommand *undo = new QPropertyUndoCommand(rec, "yRadius", rec->YRadius(), radius); + undo->setAnimated(); + elementScene()->undoStack().push(undo); + } + } + + m_locked = false; +} + + /** * @brief RectangleEditor::activeConnections * Enable/disable connection between editor widget and slot editingFinished @@ -185,20 +351,20 @@ void RectangleEditor::activeConnections(bool active) { if (active) { - connect(ui->m_x_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(ui->m_y_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(ui->m_width_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(ui->m_height_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(ui->m_rx_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - connect(ui->m_ry_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + connect(ui->m_x_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::xPosChanged); + connect(ui->m_y_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::yPosChanged); + connect(ui->m_width_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::widthChanged); + connect(ui->m_height_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::heightChanged); + connect(ui->m_rx_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::xRadiusChanged); + connect(ui->m_ry_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::yRadiusChanged); } else { - disconnect(ui->m_x_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(ui->m_y_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(ui->m_width_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(ui->m_height_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(ui->m_rx_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); - disconnect(ui->m_ry_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::editingFinished); + disconnect(ui->m_x_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::xPosChanged); + disconnect(ui->m_y_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::yPosChanged); + disconnect(ui->m_width_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::widthChanged); + disconnect(ui->m_height_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::heightChanged); + disconnect(ui->m_rx_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::xRadiusChanged); + disconnect(ui->m_ry_sb, &QDoubleSpinBox::editingFinished, this, &RectangleEditor::yRadiusChanged); } } diff --git a/sources/editor/ui/rectangleeditor.h b/sources/editor/ui/rectangleeditor.h index 6dfce0274..6e056c762 100644 --- a/sources/editor/ui/rectangleeditor.h +++ b/sources/editor/ui/rectangleeditor.h @@ -41,6 +41,7 @@ class RectangleEditor : public ElementItemEditor ~RectangleEditor() override; bool setPart(CustomElementPart *part) override; + bool setParts(QList parts) override; CustomElementPart *currentPart() const override; QList currentParts() const override; QPointF editedTopLeft () const; @@ -50,12 +51,25 @@ class RectangleEditor : public ElementItemEditor private: void editingFinished(); void activeConnections(bool active); + void xPosChanged(); + void yPosChanged(); + void widthChanged(); + void heightChanged(); + void xRadiusChanged(); + void yRadiusChanged(); + /*! + * \brief setUpChangeConnections + * Setup the connection from the rectangles(s) to the widget, to update it when the rectangles(s) are changed (moved ...) + */ + void setUpChangeConnections(); + void disconnectChangeConnections(); private: bool m_locked = false; StyleEditor *m_style; PartRectangle *m_part; Ui::RectangleEditor *ui; + QList m_change_connections; }; #endif // RECTANGLEEDITOR_H