diff --git a/qelectrotech.pro b/qelectrotech.pro index 6fbf358b3..bd12cb14b 100644 --- a/qelectrotech.pro +++ b/qelectrotech.pro @@ -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,8 +147,9 @@ 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 diff --git a/sources/diagramview.cpp b/sources/diagramview.cpp index 67559df92..09fac160a 100644 --- a/sources/diagramview.cpp +++ b/sources/diagramview.cpp @@ -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); diff --git a/sources/ui/potentialselectordialog.cpp b/sources/ui/potentialselectordialog.cpp index fe044a149..2d20f082d 100644 --- a/sources/ui/potentialselectordialog.cpp +++ b/sources/ui/potentialselectordialog.cpp @@ -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 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 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 diff --git a/sources/ui/potentialselectordialog.h b/sources/ui/potentialselectordialog.h index a3fe36c86..86b0ef0bd 100644 --- a/sources/ui/potentialselectordialog.h +++ b/sources/ui/potentialselectordialog.h @@ -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,15 +53,22 @@ 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 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(); diff --git a/sources/utils/conductorcreator.cpp b/sources/utils/conductorcreator.cpp new file mode 100644 index 000000000..2b09ba61b --- /dev/null +++ b/sources/utils/conductorcreator.cpp @@ -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 . +*/ +#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 + +/** + * @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 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 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(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 t_list; + + for (QGraphicsItem *item : d->items(polygon)) + { + if (item->type() == Terminal::Type) { + t_list.append(qgraphicsitem_cast(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 potentials = existingPotential(); + + //There is an existing potential + //we get one of them + if (!potentials.isEmpty()) + { + if (potentials.size() >= 2) + { + QList 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 ConductorCreator::existingPotential() +{ + QList c_list; + QList 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; +} diff --git a/sources/utils/conductorcreator.h b/sources/utils/conductorcreator.h new file mode 100644 index 000000000..fe547fded --- /dev/null +++ b/sources/utils/conductorcreator.h @@ -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 . +*/ +#ifndef CONDUCTORCREATOR_H +#define CONDUCTORCREATOR_H + +class Diagram; +class QPolygonF; +class Terminal; +class Conductor; + +#include "conductorproperties.h" +#include "conductorproperties.h" +#include "assignvariables.h" + +#include + + +/** + * @brief The ConductorCreator class + * This class create one or several or several conductors + * in a given context + */ +class ConductorCreator +{ + public: + ConductorCreator(Diagram *d, QList terminals_list); + static void create(Diagram *d, const QPolygonF &polygon); + + private: + void setUpPropertieToUse(); + QList existingPotential(); + Terminal *hubTerminal(); + + + QList m_terminals_list; + ConductorProperties m_properties; + autonum::sequentialNumbers m_sequential_number; + +}; + +#endif // CONDUCTORCREATOR_H