diff --git a/sources/conductorautonumerotation.cpp b/sources/conductorautonumerotation.cpp index 4aae6a0dc..a1b782aa6 100644 --- a/sources/conductorautonumerotation.cpp +++ b/sources/conductorautonumerotation.cpp @@ -25,13 +25,20 @@ #include "qet.h" /** - *Constructor - * @param c the conductor to apply automatic numerotation + * @brief ConductorAutoNumerotation::ConductorAutoNumerotation + * Constructor of autonum, after create a class, call numerate to apply the autonum. + * When autonum is applyed, they do with an undo command added to the stack of diagram. + * If you give a parent_undo at constructor, the undo command create in this class have parent_undo for parent, + * and wasn't added to the stack of diagram (it's the responsabillty of the parent_undo) + * @param conductor : the conductor to apply automatic numerotation + * @param diagram : the diagram of conductor + * @param parent_undo : parent undo command */ -ConductorAutoNumerotation::ConductorAutoNumerotation(Conductor *c) : - m_diagram (c -> diagram()), - conductor_ (c), - conductor_list (c -> relatedPotentialConductors()) +ConductorAutoNumerotation::ConductorAutoNumerotation(Conductor *conductor, Diagram *diagram, QUndoCommand *parent_undo) : + m_diagram (diagram), + conductor_ (conductor), + conductor_list (conductor -> relatedPotentialConductors()), + m_parent_undo (parent_undo) {} /** @@ -63,7 +70,7 @@ void ConductorAutoNumerotation::checkPotential(Conductor *conductor) { if (!QET::eachStrIsEqual(strl)) { PotentialTextsDialog ptd(conductor, conductor->diagramEditor()); if ( ptd.exec() == QDialog::Accepted ) { - ConductorAutoNumerotation can(conductor); + ConductorAutoNumerotation can(conductor, conductor -> diagram()); can.applyText(ptd.selectedText()); } } @@ -75,32 +82,39 @@ void ConductorAutoNumerotation::checkPotential(Conductor *conductor) { */ void ConductorAutoNumerotation::applyText(QString t) { if (!conductor_) return; - if (conductor_list.empty()) { - //initialize the corresponding UndoCommand object - ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand (conductor_); + + if (conductor_list.empty()) + { + //initialize the corresponding UndoCommand object + ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand (conductor_, m_parent_undo); ccpc -> setOldSettings (conductor_ -> properties()); ConductorProperties cp = conductor_ -> properties(); cp.text = t; ccpc -> setNewSettings(cp); - m_diagram -> undoStack().push(ccpc); + if (!m_parent_undo) + m_diagram -> undoStack().push(ccpc); } - else { + else + { QList clist = conductor_list.toList(); clist << conductor_; QList old_properties, new_properties; ConductorProperties cp; - foreach (Conductor *c, clist) { + foreach (Conductor *c, clist) + { old_properties << c -> properties(); cp = c -> properties(); cp.text = t; new_properties << cp; } - //initialize the corresponding UndoCommand object - ChangeSeveralConductorsPropertiesCommand *cscpc = new ChangeSeveralConductorsPropertiesCommand(clist); + + //initialize the corresponding UndoCommand object + ChangeSeveralConductorsPropertiesCommand *cscpc = new ChangeSeveralConductorsPropertiesCommand(clist, m_parent_undo); cscpc -> setOldSettings(old_properties); cscpc -> setNewSettings(new_properties); - m_diagram -> undoStack().push(cscpc); + if (!m_parent_undo) + m_diagram -> undoStack().push(cscpc); } } diff --git a/sources/conductorautonumerotation.h b/sources/conductorautonumerotation.h index 6a711516b..ea9e9a57c 100644 --- a/sources/conductorautonumerotation.h +++ b/sources/conductorautonumerotation.h @@ -22,26 +22,29 @@ class Diagram; class Conductor; +class QUndoCommand; -class ConductorAutoNumerotation { +class ConductorAutoNumerotation +{ public: - //constructors & destructor - ConductorAutoNumerotation (Conductor *); + //constructors & destructor + ConductorAutoNumerotation (Conductor *conductor, Diagram *diagram, QUndoCommand *undo_parent = nullptr); - //methods - void numerate(); - static void checkPotential(Conductor *); - void applyText(QString); + //methods + void numerate (); + static void checkPotential (Conductor *); + void applyText (QString); private: - //methods - void numeratePotential (); - void numerateNewConductor (); + //methods + void numeratePotential (); + void numerateNewConductor (); - //attributes - Diagram *m_diagram; - Conductor *conductor_; - QSet conductor_list; + //attributes + Diagram *m_diagram; + Conductor *conductor_; + QSet conductor_list; + QUndoCommand *m_parent_undo; }; #endif // CONDUCTORAUTONUMEROTATION_H diff --git a/sources/diagramcommands.cpp b/sources/diagramcommands.cpp index c3bd88e2d..64ee577b5 100644 --- a/sources/diagramcommands.cpp +++ b/sources/diagramcommands.cpp @@ -297,12 +297,12 @@ MoveElementsCommand::MoveElementsCommand( const QPointF &m, QUndoCommand *parent ) : - QUndoCommand(parent), - diagram(dia), - content_to_move(diagram_content), - movement(m), - m_anim_group(nullptr), - first_redo(true) + QUndoCommand (parent), + diagram (dia), + content_to_move (diagram_content), + movement (m), + m_anim_group (nullptr), + first_redo (true) { QString moved_content_sentence = content_to_move.sentence( DiagramContent::Elements | @@ -336,8 +336,9 @@ MoveElementsCommand::~MoveElementsCommand() { */ void MoveElementsCommand::undo() { diagram -> showMe(); - m_anim_group->setDirection(QAnimationGroup::Forward); - m_anim_group->start(); + m_anim_group->setDirection(QAnimationGroup::Forward); + m_anim_group->start(); + QUndoCommand::undo(); } /** @@ -353,6 +354,7 @@ void MoveElementsCommand::redo() { m_anim_group->setDirection(QAnimationGroup::Backward); m_anim_group->start(); } + QUndoCommand::redo(); } /** @@ -924,8 +926,7 @@ ChangeConductorPropertiesCommand::ChangeConductorPropertiesCommand(Conductor *c, QUndoCommand(QObject::tr("modifier les propri\351t\351s d'un conducteur", "undo caption"), parent), conductor(c), old_settings_set(false), - new_settings_set(false), - diagram(c->diagram()) + new_settings_set(false) { } @@ -950,7 +951,7 @@ void ChangeConductorPropertiesCommand::setNewSettings(const ConductorProperties doivent avoir ete definis a l'aide de setNewSettings et setOldSettings */ void ChangeConductorPropertiesCommand::undo() { - diagram -> showMe(); + if (conductor -> diagram()) conductor -> diagram() -> showMe(); if (old_settings_set && new_settings_set) { conductor -> setProperties(old_properties); conductor -> update(); @@ -962,7 +963,7 @@ void ChangeConductorPropertiesCommand::undo() { doivent avoir ete definis a l'aide de setNewSettings et setOldSettings */ void ChangeConductorPropertiesCommand::redo() { - diagram -> showMe(); + if (conductor -> diagram()) conductor -> diagram() -> showMe(); if (old_settings_set && new_settings_set) { conductor -> setProperties(new_properties); conductor -> update(); @@ -978,8 +979,7 @@ ChangeSeveralConductorsPropertiesCommand::ChangeSeveralConductorsPropertiesComma QUndoCommand(QObject::tr("modifier les propri\351t\351s de plusieurs conducteurs", "undo caption"), parent), conductors(c), old_settings_set(false), - new_settings_set(false), - diagram(c.first()->diagram()) + new_settings_set(false) { } @@ -1015,7 +1015,7 @@ void ChangeSeveralConductorsPropertiesCommand::setNewSettings(const ConductorPro doivent avoir ete definis a l'aide de setNewSettings et setOldSettings */ void ChangeSeveralConductorsPropertiesCommand::undo() { - //diagram -> showMe(); + if (conductors.first() -> diagram()) conductors.first() -> diagram() -> showMe(); if (old_settings_set && new_settings_set) { int i=0; foreach(Conductor *c, conductors) { @@ -1031,7 +1031,7 @@ void ChangeSeveralConductorsPropertiesCommand::undo() { doivent avoir ete definis a l'aide de setNewSettings et setOldSettings */ void ChangeSeveralConductorsPropertiesCommand::redo() { - //diagram -> showMe(); + if (conductors.first() -> diagram()) conductors.first() -> diagram() -> showMe(); if (old_settings_set && new_settings_set) { //new propertie are the same for each conductor diff --git a/sources/diagramcommands.h b/sources/diagramcommands.h index 02d1e9ed8..fd70320f6 100644 --- a/sources/diagramcommands.h +++ b/sources/diagramcommands.h @@ -60,12 +60,14 @@ class AddItemCommand : public QUndoCommand { virtual void undo() { m_diagram -> showMe(); m_diagram -> removeItem(m_item); + QUndoCommand::undo(); } virtual void redo() { m_diagram -> showMe(); m_diagram -> addItem(m_item); m_item -> setPos(m_pos); + QUndoCommand::redo(); } private: @@ -149,21 +151,21 @@ class CutDiagramCommand : public DeleteElementsCommand { This command moves some content on a particular diagram. */ class MoveElementsCommand : public QUndoCommand { - // constructors, destructor + // constructors, destructor public: - MoveElementsCommand(Diagram *, const DiagramContent &, const QPointF &m, QUndoCommand * = 0); - virtual ~MoveElementsCommand(); + MoveElementsCommand(Diagram *, const DiagramContent &, const QPointF &m, QUndoCommand * = 0); + virtual ~MoveElementsCommand(); private: - MoveElementsCommand(const MoveElementsCommand &); + MoveElementsCommand(const MoveElementsCommand &); - // methods + // methods public: - virtual void undo(); - virtual void redo(); - virtual void move(const QPointF &); + virtual void undo(); + virtual void redo(); + virtual void move(const QPointF &); private: - void setupAnimation (QObject * target, const QByteArray &propertyName, const QVariant start, const QVariant end); + void setupAnimation (QObject * target, const QByteArray &propertyName, const QVariant start, const QVariant end); // attributes private: @@ -471,7 +473,6 @@ class ChangeConductorPropertiesCommand : public QUndoCommand { bool old_settings_set; /// track whether post-change properties were set bool new_settings_set; - Diagram *diagram; }; /** @@ -507,7 +508,6 @@ class ChangeSeveralConductorsPropertiesCommand : public QUndoCommand { bool old_settings_set; /// track whether post-change properties were set bool new_settings_set; - Diagram *diagram; }; class ItemResizerCommand : public QUndoCommand { diff --git a/sources/elementsmover.cpp b/sources/elementsmover.cpp index e3a7f5ebf..38e6ef0f6 100644 --- a/sources/elementsmover.cpp +++ b/sources/elementsmover.cpp @@ -24,6 +24,7 @@ #include "independenttextitem.h" #include "diagramimageitem.h" #include "elementtextitem.h" +#include "conductorautonumerotation.h" /** * @brief ElementsMover::ElementsMover Constructor @@ -116,23 +117,47 @@ void ElementsMover::continueMovement(const QPointF &movement) { /** * @brief ElementsMover::endMovement * Ended the current movement by creating an undo added to the undostack of the diagram. + * If there is only one element moved, we try to auto-connect new conductor from this element + * and other possible element. */ -void ElementsMover::endMovement() { - // A movement must be inited +void ElementsMover::endMovement() +{ + // A movement must be inited if (!movement_running_) return; - // No need of an undo command if the movement is NULL + // No need of an undo command if the movement is NULL if (!current_movement_.isNull()) { - // Create an undo object for this new movement + // Create an undo object for this new movement MoveElementsCommand *undo_object = new MoveElementsCommand( diagram_, moved_content_, current_movement_ ); + + //There is only one element moved, we try auto connection of conductor; + typedef DiagramContent dc; + if (moved_content_.items(dc::TextFields | dc::Images | dc::Shapes).size() == 0 && + moved_content_.items(dc::Elements).size() == 1) + { + Element *elmt = moved_content_.elements.toList().first(); + + while (!elmt -> AlignedFreeTerminals().isEmpty()) + { + QPair pair = elmt->AlignedFreeTerminals().takeFirst(); + + Conductor *conductor = new Conductor(pair.first, pair.second); + conductor -> setProperties(diagram_ -> defaultConductorProperties); + //Create an undo object for each new auto conductor, with undo_object for parent; + new AddItemCommand(conductor, diagram_, QPointF(), undo_object); + //Autonum the new conductor, the undo command associated for this, have for parent undo_object + ConductorAutoNumerotation can (conductor, diagram_, undo_object); + can.numerate(); + }; + } diagram_ -> undoStack().push(undo_object); } - // There is no movement in progress now + // There is no movement in progress now movement_running_ = false; } diff --git a/sources/qetgraphicsitem/conductor.cpp b/sources/qetgraphicsitem/conductor.cpp index c1a768373..be101ff1d 100644 --- a/sources/qetgraphicsitem/conductor.cpp +++ b/sources/qetgraphicsitem/conductor.cpp @@ -1380,15 +1380,6 @@ void Conductor::setHighlighted(Conductor::Highlight hl) { update(); } -/** - * @brief Conductor::autoText - *lance l'autoNumerotation sur ce conducteur - */ -void Conductor::autoText() { - ConductorAutoNumerotation can(this); - can.numerate(); -} - /** Met a jour les proprietes du conducteur apres modification du champ de texte affiche */ @@ -1396,21 +1387,26 @@ void Conductor::displayedTextChanged() { // verifie que le texte a reellement change if (text_item -> toPlainText() == properties_.text) return; - if (Diagram *my_diagram = diagram()) { + if (Diagram *my_diagram = diagram()) + { int qmbreturn=0; - //if conductor isn't alone at this potential - //ask user to apply text on every conductors of this potential - if (relatedPotentialConductors().size() >= 1){ + //if conductor isn't alone at this potential + //ask user to apply text on every conductors of this potential + if (relatedPotentialConductors().size() >= 1) + { qmbreturn = QMessageBox::question(diagramEditor(), tr("Textes de conducteurs"), tr("Voulez-vous appliquer le nouveau texte \n" "\340 l'ensemble des conducteurs de ce potentiel ?"), QMessageBox::No| QMessageBox::Yes, QMessageBox::Yes); - if (qmbreturn == QMessageBox::Yes){ - ConductorAutoNumerotation can(this); + if (qmbreturn == QMessageBox::Yes) + { + ConductorAutoNumerotation can(this, my_diagram); can.applyText(text_item -> toPlainText()); } } - if (qmbreturn == 0 || qmbreturn == QMessageBox::No) { + + if (qmbreturn == 0 || qmbreturn == QMessageBox::No) + { // initialise l'objet UndoCommand correspondant ConductorProperties new_properties(properties_); new_properties.text = text_item -> toPlainText(); diff --git a/sources/qetgraphicsitem/conductor.h b/sources/qetgraphicsitem/conductor.h index 9b12d9d80..e3e105f21 100644 --- a/sources/qetgraphicsitem/conductor.h +++ b/sources/qetgraphicsitem/conductor.h @@ -112,7 +112,6 @@ class Conductor : public QObject, public QGraphicsPathItem { void calculateTextItemPosition(); virtual Highlight highlight() const; virtual void setHighlighted(Highlight); - void autoText(); QSet relatedPotentialConductors(const bool all_diagram = true, QList *t_list=0); QETDiagramEditor* diagramEditor() const; void editProperty (); diff --git a/sources/qetgraphicsitem/element.cpp b/sources/qetgraphicsitem/element.cpp index 7498be891..395d87fd1 100644 --- a/sources/qetgraphicsitem/element.cpp +++ b/sources/qetgraphicsitem/element.cpp @@ -494,6 +494,31 @@ QDomElement Element::toXml(QDomDocument &document, QHash &table return(element); } +/** + * @brief Element::AlignedFreeTerminals + * @return a list of terminal (owned by this element) aligned to other terminal (from other element) + * The first Terminal of QPair is a Terminal owned by this element, + * this terminal haven't got any conductor docked. + * The second Terminal of QPair is a Terminal owned by an other element, + * which is aligned with the first Terminal. The second Terminal can have or not docked conductors. + */ +QList > Element::AlignedFreeTerminals() const +{ + QList > list; + + foreach (Terminal *terminal, terminals()) + { + if (terminal->conductors().isEmpty()) + { + Terminal *other_terminal = terminal -> alignedWithTerminal(); + if (other_terminal) + list << qMakePair(terminal, other_terminal); + } + } + + return list; +} + /** * @brief Element::initLink * Initialise the link between this element and other elements. @@ -549,6 +574,10 @@ bool comparPos(const Element *elmt1, const Element *elmt2) { return elmt1->pos().x() <= elmt2->pos().x(); } +/** + * @brief Element::mouseMoveEvent + * @param event + */ void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QetGraphicsItem::mouseMoveEvent(event); @@ -558,6 +587,10 @@ void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } } +/** + * @brief Element::mouseReleaseEvent + * @param event + */ void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { QetGraphicsItem::mouseReleaseEvent(event); diff --git a/sources/qetgraphicsitem/element.h b/sources/qetgraphicsitem/element.h index 8803cb7d4..63f9be08a 100644 --- a/sources/qetgraphicsitem/element.h +++ b/sources/qetgraphicsitem/element.h @@ -94,6 +94,7 @@ class Element : public QetGraphicsItem { /// @return the maximum number of terminals for this element virtual int maxTerminalsCount() const = 0; + QList > AlignedFreeTerminals () const; /** *related method and attributes, @@ -121,7 +122,7 @@ class Element : public QetGraphicsItem { signals: void elementInfoChange(DiagramContext old_info, DiagramContext new_info); - //METHODS related to information + //METHODS related to information public: DiagramContext elementInformations ()const {return element_informations_;} DiagramContext& rElementInformations () {return element_informations_;} diff --git a/sources/qetgraphicsitem/terminal.cpp b/sources/qetgraphicsitem/terminal.cpp index 64565bd16..3843bf950 100644 --- a/sources/qetgraphicsitem/terminal.cpp +++ b/sources/qetgraphicsitem/terminal.cpp @@ -21,6 +21,7 @@ #include "qetgraphicsitem/conductor.h" #include "diagramcommands.h" #include "qetapp.h" +#include "conductorautonumerotation.h" QColor Terminal::neutralColor = QColor(Qt::blue); QColor Terminal::allowedColor = QColor(Qt::darkGreen); @@ -527,35 +528,44 @@ void Terminal::mouseMoveEvent(QGraphicsSceneMouseEvent *e) { other_terminal -> update(); } + /** - Gere le fait qu'on relache la souris sur la Borne. - @param e L'evenement souris correspondant -*/ -void Terminal::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { - //setCursor(Qt::ArrowCursor); + * @brief Terminal::mouseReleaseEvent + * @param e + */ +void Terminal::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) +{ previous_terminal_ = 0; - hovered_color_ = neutralColor; - // verifie que la scene est bien un Diagram - if (Diagram *d = diagram()) { - // on arrete de dessiner l'apercu du conducteur + hovered_color_ = neutralColor; + + if (Diagram *d = diagram()) + { + //Stop conductor preview d -> setConductor(false); - // on recupere l'element sous le pointeur lors du MouseReleaseEvent + + //Get item under cursor QGraphicsItem *qgi = d -> itemAt(e -> scenePos()); - // s'il n'y a rien, on arrete la if (!qgi) return; - // idem si l'element obtenu n'est pas une borne + + //Element must be a terminal Terminal *other_terminal = qgraphicsitem_cast(qgi); if (!other_terminal) return; - // on remet la couleur de hover a sa valeur par defaut + other_terminal -> hovered_color_ = neutralColor; - other_terminal -> hovered_ = false; - // on s'arrete la s'il n'est pas possible de relier les bornes + other_terminal -> hovered_ = false; + + //We stop her if we can't link this terminal with other terminal if (!canBeLinkedTo(other_terminal)) return; - // autrement, on pose un conducteur + + //Create conductor Conductor *new_conductor = new Conductor(this, other_terminal); new_conductor -> setProperties(d -> defaultConductorProperties); - d -> undoStack().push(new AddItemCommand(new_conductor, d)); - new_conductor -> autoText(); + QUndoCommand *undo = new AddItemCommand(new_conductor, d); + //Autonum it + ConductorAutoNumerotation can (new_conductor, d, undo); + can.numerate(); + //Add undo command to the parent diagram + d -> undoStack().push(undo); } }