Fix bug 203

https://qelectrotech.org/bugtracker/view.php?id=203
Take advantage of this bugfix, to recode the widget with Qt designer.
This commit is contained in:
Claveau Joshua 2020-10-10 16:58:02 +02:00
parent 419585f97e
commit e878082b79
4 changed files with 345 additions and 310 deletions

View File

@ -1,271 +0,0 @@
/*
Copyright 2006-2020 The QElectroTech Team
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/>.
*/
#include "ellipseeditor.h"
#include "styleeditor.h"
#include "partellipse.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
/**
Constructeur
@param editor L'editeur d'element concerne
@param ellipse L'ellipse a editer
@param parent le Widget parent
*/
EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *ellipse, QWidget *parent) :
ElementItemEditor(editor, parent),
part(ellipse),
m_locked(false)
{
style_ = new StyleEditor(editor);
x = new QDoubleSpinBox();
y = new QDoubleSpinBox();
h = new QDoubleSpinBox();
v = new QDoubleSpinBox();
x->setRange(-5000, 5000);
y->setRange(-5000, 5000);
h->setRange(-5000, 5000);
v->setRange(-5000, 5000);
QVBoxLayout *v_layout = new QVBoxLayout(this);
QGridLayout *grid = new QGridLayout();
grid -> addWidget(new QLabel(tr("Centre : ")), 0, 0);
grid -> addWidget(new QLabel("x"), 1, 0, Qt::AlignRight);
grid -> addWidget(x, 1, 1);
grid -> addWidget(new QLabel("y"), 1, 2);
grid -> addWidget(y, 1, 3);
grid -> addWidget(new QLabel(tr("Diamètres : ")), 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);
v_layout -> addWidget(style_);
v_layout -> addLayout(grid);
v_layout->addStretch();
activeConnections(true);
updateForm();
}
/// Destructeur
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.
L'editeur d'ellipse acceptera d'editer la primitive new_part s'il s'agit
d'un objet de la classe PartEllipse.
@param new_part Nouvelle primitive a editer
@return true si l'editeur a accepter d'editer la primitive, false sinon
*/
bool EllipseEditor::setPart(CustomElementPart *new_part)
{
if (!new_part)
{
if (part)
disconnectChangeConnections();
part = nullptr;
return(true);
}
if (PartEllipse *part_ellipse = dynamic_cast<PartEllipse *>(new_part))
{
if (part == part_ellipse) return true;
if (part)
disconnectChangeConnections();
part = part_ellipse;
updateForm();
setUpChangeConnections();
return(true);
}
return(false);
}
bool EllipseEditor::setParts(QList <CustomElementPart *> 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
*/
CustomElementPart *EllipseEditor::currentPart() const
{
return(part);
}
QList<CustomElementPart*> EllipseEditor::currentParts() const
{
return style_->currentParts();
}
void EllipseEditor::editingFinishedX()
{
if (m_locked) return;
m_locked = true;
for (auto part: style_->currentParts()) {
PartEllipse* ell = static_cast<PartEllipse*>(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<PartEllipse*>(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<PartEllipse*>(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<PartEllipse*>(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;
}
/**
Met a jour le formulaire d'edition
*/
void EllipseEditor::updateForm()
{
if (!part) return;
activeConnections(false);
QRectF rect = part->property("rect").toRectF();
x->setValue(part->mapToScene(rect.topLeft()).x() + (rect.width()/2));
y->setValue(part->mapToScene(rect.topLeft()).y() + (rect.height()/2));
h->setValue(rect.width());
v->setValue(rect.height());
activeConnections(true);
}
/**
Active ou desactive les connexionx signaux/slots entre les widgets internes.
@param active true pour activer les connexions, false pour les desactiver
*/
void EllipseEditor::activeConnections(bool active)
{
if (active)
{
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(editingFinishedX()));
disconnect(y, SIGNAL(editingFinished()), this, SLOT(editingFinishedY()));
disconnect(h, SIGNAL(editingFinished()), this, SLOT(editingFinishedH()));
disconnect(v, SIGNAL(editingFinished()), this, SLOT(editingFinishedV()));
}
}

View File

@ -0,0 +1,177 @@
/*
Copyright 2006-2020 The QElectroTech Team
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/>.
*/
#include "ellipseeditor.h"
#include "ui_ellipseeditor.h"
#include "partellipse.h"
#include "styleeditor.h"
#include "QPropertyUndoCommand/qpropertyundocommand.h"
#include "elementscene.h"
/**
* @brief EllipseEditor::EllipseEditor
* @param editor
* @param part
* @param parent
*/
EllipseEditor::EllipseEditor(QETElementEditor *editor, PartEllipse *part, QWidget *parent) :
ElementItemEditor(editor, parent),
ui(new Ui::EllipseEditor),
m_part(part)
{
ui->setupUi(this);
m_style = new StyleEditor(editor);
ui->m_main_layout->insertWidget(0, m_style);
updateForm();
}
/**
* @brief EllipseEditor::~EllipseEditor
*/
EllipseEditor::~EllipseEditor()
{
delete ui;
}
/**
* @brief EllipseEditor::setPart
* @param part
* @return
*/
bool EllipseEditor::setPart(CustomElementPart *part)
{
disconnectChangeConnections();
if (!part)
{
m_part = nullptr;
return true;
}
if (PartEllipse *part_ellipse = dynamic_cast<PartEllipse *>(part))
{
if (m_part == part_ellipse) {
return true;
}
m_part = part_ellipse;
setUpChangeConnections();
updateForm();
return true;
}
return false;
}
/**
* @brief EllipseEditor::setParts
* @param parts
* @return
*/
bool EllipseEditor::setParts(QList<CustomElementPart *> parts)
{
if (parts.isEmpty()) {
return false;
}
if (!setPart(parts.first())) {
return false;
}
return m_style->setParts(parts);
}
/**
* @brief EllipseEditor::currentPart
* @return
*/
CustomElementPart *EllipseEditor::currentPart() const {
return m_part;
}
/**
* @brief EllipseEditor::currentParts
* @return
*/
QList<CustomElementPart *> EllipseEditor::currentParts() const {
return m_style->currentParts();
}
/**
* @brief EllipseEditor::updateForm
*/
void EllipseEditor::updateForm()
{
if (!m_part) {
return;
}
QRectF rect = m_part->property("rect").toRectF();
ui->m_x_sb->setValue(m_part->mapToScene(rect.topLeft()).x() + (rect.width()/2));
ui->m_y_sb->setValue(m_part->mapToScene(rect.topLeft()).y() + (rect.height()/2));
ui->m_horizontal_diameter_sb->setValue(rect.width());
ui->m_vertical_diameter_sb->setValue(rect.height());
}
void EllipseEditor::on_m_x_sb_editingFinished() { updateRect(); }
void EllipseEditor::on_m_y_sb_editingFinished() { updateRect(); }
void EllipseEditor::on_m_horizontal_diameter_sb_editingFinished() { updateRect(); }
void EllipseEditor::on_m_vertical_diameter_sb_editingFinished() { updateRect(); }
/**
* @brief EllipseEditor::updateRect
*/
void EllipseEditor::updateRect()
{
QRectF rect;
auto pos_ = m_part->mapFromScene(QPointF(ui->m_x_sb->value(), ui->m_y_sb->value()));
rect.setX(pos_.x() - ui->m_horizontal_diameter_sb->value()/2);
rect.setY(pos_.y() - ui->m_vertical_diameter_sb->value()/2);
rect.setWidth(ui->m_horizontal_diameter_sb->value());
rect.setHeight(ui->m_vertical_diameter_sb->value());
for (auto part: m_style->currentParts())
{
auto ellipse = static_cast<PartEllipse*>(part);
if (rect != part->property("rect"))
{
auto undo= new QPropertyUndoCommand(ellipse, "rect", ellipse->property("rect"), rect);
undo->setText("Modifier un arc");
undo->enableAnimation();
elementScene()->undoStack().push(undo);
}
}
}
/**
* @brief EllipseEditor::setUpChangeConnections
*/
void EllipseEditor::setUpChangeConnections()
{
m_change_connections << connect(m_part, &PartEllipse::xChanged, this, &EllipseEditor::updateForm);
m_change_connections << connect(m_part, &PartEllipse::yChanged, this, &EllipseEditor::updateForm);
m_change_connections << connect(m_part, &PartEllipse::rectChanged, this, &EllipseEditor::updateForm);
}
/**
* @brief EllipseEditor::disconnectChangeConnections
*/
void EllipseEditor::disconnectChangeConnections()
{
for (QMetaObject::Connection c : m_change_connections) {
disconnect(c);
}
m_change_connections.clear();
}

View File

@ -1,72 +1,67 @@
/* /*
Copyright 2006-2020 The QElectroTech Team Copyright 2006-2020 The QElectroTech Team
This file is part of QElectroTech. This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify QElectroTech is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
QElectroTech is distributed in the hope that it will be useful, QElectroTech is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>. along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef ELLIPSE_EDITOR_H #ifndef ELLIPSEEDITOR_H
#define ELLIPSE_EDITOR_H #define ELLIPSEEDITOR_H
#include "elementitemeditor.h" #include "elementitemeditor.h"
namespace Ui {
class EllipseEditor;
}
class PartEllipse; class PartEllipse;
class StyleEditor; class StyleEditor;
class QDoubleSpinBox;
/** /**
This class provides a widget to edit ellipses within the element editor. * @brief The EllipseEditor class
*/ * This class provide a widget used to edit the properties of a @PartEllipse
*/
class EllipseEditor : public ElementItemEditor class EllipseEditor : public ElementItemEditor
{ {
Q_OBJECT Q_OBJECT
// constructors, destructor
public: public:
EllipseEditor(QETElementEditor *, PartEllipse * = nullptr, QWidget * = nullptr); explicit EllipseEditor (QETElementEditor *editor, PartEllipse *part = nullptr, QWidget *parent = nullptr);
~EllipseEditor() override; ~EllipseEditor() override;
private:
EllipseEditor(const EllipseEditor &); bool setPart(CustomElementPart *part) override;
bool setParts(QList<CustomElementPart *> parts) override;
// attributes
private:
PartEllipse *part;
StyleEditor *style_;
QDoubleSpinBox *x, *y, *h, *v;
bool m_locked;
QList <QMetaObject::Connection> m_change_connections;
// methods
public:
bool setPart(CustomElementPart *) override;
bool setParts(QList <CustomElementPart *> parts) override;
CustomElementPart *currentPart() const override; CustomElementPart *currentPart() const override;
QList<CustomElementPart*> currentParts() const override; QList<CustomElementPart*> currentParts() const override;
public slots:
void editingFinishedX();
void editingFinishedY();
void editingFinishedH();
void editingFinishedV();
void updateForm() override; void updateForm() override;
private slots:
void on_m_x_sb_editingFinished();
void on_m_y_sb_editingFinished();
void on_m_horizontal_diameter_sb_editingFinished();
void on_m_vertical_diameter_sb_editingFinished();
private: private:
void activeConnections(bool); void updateRect();
/**
@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 setUpChangeConnections();
void disconnectChangeConnections(); void disconnectChangeConnections();
private:
Ui::EllipseEditor *ui;
PartEllipse *m_part = nullptr;
StyleEditor *m_style = nullptr;
QList <QMetaObject::Connection> m_change_connections;
}; };
#endif
#endif // ELLIPSEEDITOR_H

View File

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EllipseEditor</class>
<widget class="QWidget" name="EllipseEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>314</width>
<height>173</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="m_main_layout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QGridLayout" name="m_geometry_widget">
<item row="0" column="0" colspan="5">
<widget class="QLabel" name="label">
<property name="text">
<string>Centre :</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Y</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="m_vertical_diameter_sb">
<property name="minimum">
<double>-10000.000000000000000</double>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QDoubleSpinBox" name="m_y_sb">
<property name="minimum">
<double>-10000.000000000000000</double>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>X</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Vertical :</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="m_x_sb">
<property name="minimum">
<double>-10000.000000000000000</double>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Horizontal :</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="m_horizontal_diameter_sb">
<property name="minimum">
<double>-10000.000000000000000</double>
</property>
<property name="maximum">
<double>10000.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="4">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Diamètres :</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>