Free hand selection : at the end of the selection, popup a context menu for create conductors between selected terminal

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@5718 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
blacksun
2019-01-27 17:04:13 +00:00
parent a5b0658293
commit 0db73abd41
6 changed files with 336 additions and 12 deletions

View File

@@ -96,7 +96,8 @@ INCLUDEPATH += sources \
sources/SearchAndReplace \
sources/SearchAndReplace/ui \
sources/NameList \
sources/NameList/ui
sources/NameList/ui \
sources/utils
# Fichiers sources
@@ -121,7 +122,8 @@ HEADERS += $$files(sources/*.h) $$files(sources/ui/*.h) \
$$files(sources/SearchAndReplace/*.h) \
$$files(sources/SearchAndReplace/ui/*.h) \
$$files(sources/NameList/*.h) \
$$files(sources/NameList/ui/*.h)
$$files(sources/NameList/ui/*.h) \
$$files(sources/utils/*.h)
SOURCES += $$files(sources/*.cpp) \
$$files(sources/editor/*.cpp) \
@@ -145,7 +147,8 @@ SOURCES += $$files(sources/*.cpp) \
$$files(sources/SearchAndReplace/*.cpp) \
$$files(sources/SearchAndReplace/ui/*.cpp) \
$$files(sources/NameList/*.cpp) \
$$files(sources/NameList/ui/*.cpp)
$$files(sources/NameList/ui/*.cpp) \
$$files(sources/utils/*.cpp)
# Liste des fichiers qui seront incorpores au binaire en tant que ressources Qt
RESOURCES += qelectrotech.qrc

View File

@@ -44,6 +44,7 @@
#include "dynamicelementtextitem.h"
#include "multipastedialog.h"
#include "changetitleblockcommand.h"
#include "conductorcreator.h"
/**
Constructeur
@@ -448,7 +449,7 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
if (viewportUpdateMode() != QGraphicsView::NoViewportUpdate && !m_free_rubberband.isEmpty())
{
if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate) {
viewport()->update(m_free_rubberband.boundingRect().toRect());
viewport()->update(m_free_rubberband.boundingRect().toRect().adjusted(-10,-10,10,10));
}
else {
update();
@@ -468,7 +469,7 @@ void DiagramView::mouseMoveEvent(QMouseEvent *e)
if (viewportUpdateMode() != QGraphicsView::NoViewportUpdate)
{
if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate) {
viewport()->update(mapFromScene(m_free_rubberband.boundingRect()));
viewport()->update(mapFromScene(m_free_rubberband.boundingRect().adjusted(-10,-10,10,10)));
}
else {
update();
@@ -493,24 +494,43 @@ void DiagramView::mouseReleaseEvent(QMouseEvent *e)
if (m_event_interface && m_event_interface->mouseReleaseEvent(e)) return;
//Stop drag view
if (e -> button() == Qt::MidButton) {
if (e -> button() == Qt::MidButton)
{
viewport()->setCursor(Qt::ArrowCursor);
}
else if (m_free_rubberbanding && !e->buttons())
{
if (viewportUpdateMode() != QGraphicsView::NoViewportUpdate)
{
if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate) {
if (viewportUpdateMode() != QGraphicsView::FullViewportUpdate)
{
QRectF r(mapFromScene(m_free_rubberband).boundingRect());
r.adjust(-5, -5, 5, 5);
r.adjust(-10, -10, 10, 10);
viewport()->update(r.toRect());
} else {
}
else
{
update();
}
}
//Popup a menu with an action to create conductors between
//all selected terminals.
QAction *act = new QAction(tr("Connecter les bornes sélectionné"), this);
QPolygonF polygon_ = m_free_rubberband;
connect(act, &QAction::triggered, [this, polygon_]()
{
ConductorCreator::create(m_diagram, polygon_);
diagram()->clearSelection();
});
QMenu *menu = new QMenu(this);
menu->addAction(act);
menu->popup(e->globalPos());
m_free_rubberbanding = false;
m_free_rubberband = QPolygon();
emit freeRubberBandChanged(m_free_rubberband);
e->accept();
}
else
QGraphicsView::mouseReleaseEvent(e);
@@ -984,6 +1004,11 @@ bool DiagramView::event(QEvent *e) {
return(QGraphicsView::event(e));
}
/**
* @brief DiagramView::paintEvent
* Reimplemented from QGraphicsView
* @param event
*/
void DiagramView::paintEvent(QPaintEvent *event)
{
QGraphicsView::paintEvent(event);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2019 The QElectroTech Team
Copyright 2006-2017 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -165,6 +165,51 @@ class LinkReportPotentialSelector : public AbstractPotentialSelector
//### END PRIVATE CLASS ###//
ConductorProperties PotentialSelectorDialog::chosenProperties(QList<ConductorProperties> list, QWidget *widget)
{
if (list.isEmpty()) {
return ConductorProperties() ;
} else if (list.size() == 1) {
return list.first();
}
QDialog dialog(widget);
QVBoxLayout layout(widget);
dialog.setLayout(&layout);
QLabel label(tr("Veuillez choisir un potentiel électrique de la liste \n"
"à utiliser pour le nouveau potentiel"));
layout.addWidget(&label);
QHash <QRadioButton *, ConductorProperties> H;
for (ConductorProperties cp : list)
{
QString text;
if(!cp.text.isEmpty())
text.append(tr("\nNuméro : %1").arg(cp.text));
if(!cp.m_function.isEmpty())
text.append(tr("\nFonction : %1").arg(cp.m_function));
if(!cp.m_tension_protocol.isEmpty())
text.append(tr("\nTension/protocole : %1").arg(cp.m_tension_protocol));
QRadioButton *b = new QRadioButton(text, &dialog);
layout.addWidget(b);
H.insert(b, cp);
}
QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok, &dialog);
layout.addWidget(button_box);
connect(button_box, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
dialog.exec();
for (QRadioButton *b : H.keys()) {
if(b->isChecked()) {
return H.value(b);
}
}
return ConductorProperties();
}
/**
* @brief PotentialSelectorDialog::PotentialSelectorDialog
* Constructor when we link two potentiels together, with a conductor

View File

@@ -1,5 +1,5 @@
/*
Copyright 2006-2019 The QElectroTech Team
Copyright 2006-2017 The QElectroTech Team
This file is part of QElectroTech.
QElectroTech is free software: you can redistribute it and/or modify
@@ -53,16 +53,23 @@ namespace Ui {
* as parent of the undo command that describe the changes.
* If @parent_undo is null, the created undo-command is push to the undo stack of the parent diagram of a conductor in potential.
* else we apply the change without a QUndoCommand.
*
* the static function chosenProperties, open a dialog who ask user to make a choice between the given
* properties
*/
class PotentialSelectorDialog : public QDialog
{
Q_OBJECT
public:
static ConductorProperties chosenProperties(QList<ConductorProperties> list, QWidget *parent = nullptr);
public:
explicit PotentialSelectorDialog(Conductor *conductor, QUndoCommand *parent_undo = nullptr, QWidget *parent = nullptr);
explicit PotentialSelectorDialog(Element *report, QUndoCommand *parent_undo = nullptr, QWidget *parent = nullptr);
~PotentialSelectorDialog() override;
private slots:
void on_buttonBox_accepted();

View File

@@ -0,0 +1,188 @@
/*
Copyright 2006-2019 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 "conductorcreator.h"
#include "diagram.h"
#include "qgraphicsitem.h"
#include "terminal.h"
#include "conductor.h"
#include "potentialselectordialog.h"
#include "diagramcommands.h"
#include "conductorautonumerotation.h"
#include <QPolygonF>
/**
* @brief ConductorCreator::ConductorCreator
* Create an electrical potential between all terminals of @terminals_list.
* the terminals of the list must be in the same diagram.
* @param terminals_list
*/
ConductorCreator::ConductorCreator(Diagram *d, QList<Terminal *> terminals_list) :
m_terminals_list(terminals_list)
{
if (m_terminals_list.size() <= 1) {
return;
}
m_properties = m_terminals_list.first()->diagram()->defaultConductorProperties;
setUpPropertieToUse();
Terminal *hub_terminal = hubTerminal();
d->undoStack().beginMacro(QObject::tr("Création de conducteurs"));
QList<Conductor *> c_list;
for (Terminal *t : m_terminals_list)
{
if (t == hub_terminal) {
continue;
}
Conductor *cond = new Conductor(hub_terminal, t);
cond->setProperties(m_properties);
cond->setSequenceNum(m_sequential_number);
d->undoStack().push(new AddItemCommand<Conductor *>(cond, d));
c_list.append(cond);
}
d->undoStack().endMacro();
for(Conductor *c : c_list) {
c->refreshText();
}
}
/**
* @brief ConductorCreator::create
* Create an electrical potential between the terminals of the diagram d, contained in the polygon
* @param d
* @param polygon : polygon in diagram coordinate
*/
void ConductorCreator::create(Diagram *d, const QPolygonF &polygon)
{
QList<Terminal *> t_list;
for (QGraphicsItem *item : d->items(polygon))
{
if (item->type() == Terminal::Type) {
t_list.append(qgraphicsitem_cast<Terminal *>(item));
}
}
if (t_list.size() <= 1) {
return;
} else {
ConductorCreator cc(d, t_list);
}
}
/**
* @brief ConductorCreator::propertieToUse
* @return the conductor properties to use for the new conductors.
*/
void ConductorCreator::setUpPropertieToUse()
{
QList<Conductor *> potentials = existingPotential();
//There is an existing potential
//we get one of them
if (!potentials.isEmpty())
{
if (potentials.size() >= 2)
{
QList <ConductorProperties> cp_list;
for(Conductor *c : potentials) {
cp_list.append(c->properties());
}
m_properties = PotentialSelectorDialog::chosenProperties(cp_list);
for (Conductor *c : potentials) {
if (c->properties() == m_properties) {
m_sequential_number = c->sequenceNum();
}
}
}
else if (potentials.size() == 1)
{
m_properties = potentials.first()->properties();
m_sequential_number = potentials.first()->sequenceNum();
}
return;
}
//get a new properties
ConductorAutoNumerotation::newProperties(m_terminals_list.first()->diagram(), m_properties, m_sequential_number);
}
/**
* @brief ConductorCreator::existingPotential
* Return the list of existing potential of
* the terminal list
* @return
*/
QList<Conductor *> ConductorCreator::existingPotential()
{
QList<Conductor *> c_list;
QList<Terminal *> t_exclude;
for (Terminal *t : m_terminals_list)
{
if (t_exclude.contains(t)) {
continue;
}
if (!t->conductors().isEmpty())
{
c_list.append(t->conductors().first());
//We must to check m_terminals_list contain a terminal
//in the same potential of c, and if true, exclude this terminal from the search.
for (Conductor *c : t->conductors().first()->relatedPotentialConductors(false))
{
if (m_terminals_list.contains(c->terminal1)) {
t_exclude.append(c->terminal1);
} else if (m_terminals_list.contains(c->terminal2)) {
t_exclude.append(c->terminal2);
}
}
}
}
return c_list;
}
/**
* @brief ConductorCreator::hubTerminal
* @return
*/
Terminal *ConductorCreator::hubTerminal()
{
Terminal *hub_terminal = m_terminals_list.first();
for (Terminal *tt : m_terminals_list)
{
if (tt->scenePos().x() < hub_terminal->scenePos().x()) {
hub_terminal = tt;
} else if (tt->scenePos().x() == hub_terminal->scenePos().x()) {
if (tt->scenePos().y() < hub_terminal->scenePos().y()) {
hub_terminal = tt;
}
}
}
return hub_terminal;
}

View File

@@ -0,0 +1,56 @@
/*
Copyright 2006-2019 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/>.
*/
#ifndef CONDUCTORCREATOR_H
#define CONDUCTORCREATOR_H
class Diagram;
class QPolygonF;
class Terminal;
class Conductor;
#include "conductorproperties.h"
#include "conductorproperties.h"
#include "assignvariables.h"
#include <QList>
/**
* @brief The ConductorCreator class
* This class create one or several or several conductors
* in a given context
*/
class ConductorCreator
{
public:
ConductorCreator(Diagram *d, QList<Terminal *> terminals_list);
static void create(Diagram *d, const QPolygonF &polygon);
private:
void setUpPropertieToUse();
QList<Conductor *> existingPotential();
Terminal *hubTerminal();
QList<Terminal *> m_terminals_list;
ConductorProperties m_properties;
autonum::sequentialNumbers m_sequential_number;
};
#endif // CONDUCTORCREATOR_H