diff --git a/diagram.cpp b/diagram.cpp index 0c4bf76ed..2660dea04 100644 --- a/diagram.cpp +++ b/diagram.cpp @@ -4,6 +4,7 @@ #include "customelement.h" #include "diagram.h" #include "exportdialog.h" +#include "diagramcommands.h" /** Constructeur @@ -99,7 +100,25 @@ void Diagram::keyPressEvent(QKeyEvent *e) { } void Diagram::keyReleaseEvent(QKeyEvent *e) { - invalidateMovedElements(); + // detecte le relachement d'une touche de direction ( = deplacement d'elements) + if ( + (e -> key() == Qt::Key_Left || e -> key() == Qt::Key_Right ||\ + e -> key() == Qt::Key_Up || e -> key() == Qt::Key_Down) &&\ + !current_movement.isNull() && !e -> isAutoRepeat() + ) { + // cree un object d'annulation pour le mouvement qui vient de se finir + undoStack().push( + new MoveElementsCommand( + this, + elementsToMove(), + conducersToMove(), + conducersToUpdate(), + current_movement + ) + ); + invalidateMovedElements(); + current_movement = QPointF(); + } QGraphicsScene::keyReleaseEvent(e); } diff --git a/diagram.h b/diagram.h index b814dd9c5..b0cbc41c9 100644 --- a/diagram.h +++ b/diagram.h @@ -26,6 +26,7 @@ class Diagram : public QGraphicsScene { public: enum BorderOptions { EmptyBorder, Inset, Columns }; BorderInset border_and_inset; + QPointF current_movement; private: QGraphicsLineItem *conducer_setter; diff --git a/diagramcommands.cpp b/diagramcommands.cpp index c5f76890c..c66ce87d5 100644 --- a/diagramcommands.cpp +++ b/diagramcommands.cpp @@ -218,3 +218,64 @@ CutDiagramCommand::CutDiagramCommand( /// Destructeur CutDiagramCommand::~CutDiagramCommand() { } + +/** + Constructeur + @param +*/ +MoveElementsCommand::MoveElementsCommand( + Diagram *dia, + const QSet &move_elements, + const QSet &move_conducers, + const QHash &modify_conducers, + const QPointF &m, + QUndoCommand *parent +) : + QUndoCommand(parent), + diagram(dia), + elements_to_move(move_elements), + conducers_to_move(move_conducers), + conducers_to_update(modify_conducers), + movement(m) +{ + setText(QObject::tr("d\351placer ") + QET::ElementsAndConducersSentence(elements_to_move.count(), conducers_to_move.count())); + foreach(QGraphicsItem *qgi, elements_to_move) diagram -> qgiManager().manage(qgi); + foreach(QGraphicsItem *qgi, conducers_to_move) diagram -> qgiManager().manage(qgi); + foreach(QGraphicsItem *qgi, conducers_to_update) diagram -> qgiManager().manage(qgi); +} + +/// Destructeur +MoveElementsCommand::~MoveElementsCommand() { + foreach(QGraphicsItem *qgi, elements_to_move) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, conducers_to_move) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, conducers_to_update) diagram -> qgiManager().release(qgi); +} + +/// annule le deplacement +void MoveElementsCommand::undo() { + move(-movement); +} + +/// refait le deplacement +void MoveElementsCommand::redo() { + if (first_redo) first_redo = false; + else move(movement); +} + +/// +void MoveElementsCommand::move(const QPointF &actual_movement) { + // deplace les elements + foreach(Element *element, elements_to_move) { + element -> setPos(element -> pos() + actual_movement); + } + + // deplace certains conducteurs + foreach(Conducer *conducer, conducers_to_move) { + conducer -> setPos(conducer -> pos() + actual_movement); + } + + // recalcule les autres conducteurs + foreach(Conducer *conducer, conducers_to_update.keys()) { + conducer -> updateWithNewPos(QRectF(), conducers_to_update[conducer], conducers_to_update[conducer] -> amarrageConducer()); + } +} diff --git a/diagramcommands.h b/diagramcommands.h index e9344876b..279894101 100644 --- a/diagramcommands.h +++ b/diagramcommands.h @@ -14,6 +14,7 @@ class AddElementCommand : public QUndoCommand { AddElementCommand(const AddElementCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -39,6 +40,7 @@ class AddConducerCommand : public QUndoCommand { AddConducerCommand(const AddConducerCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -63,6 +65,7 @@ class DeleteElementsCommand : public QUndoCommand { DeleteElementsCommand(const DeleteElementsCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -88,6 +91,7 @@ class PasteDiagramCommand : public QUndoCommand { PasteDiagramCommand(const PasteDiagramCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -116,4 +120,37 @@ class CutDiagramCommand : public DeleteElementsCommand { CutDiagramCommand(const CutDiagramCommand &); }; +/** + Cette classe represente l'action de deplacer des elements et des + conducteurs sur un schema +*/ +class MoveElementsCommand : public QUndoCommand { + // constructeurs, destructeur + public: + MoveElementsCommand(Diagram *, const QSet &, const QSet &, const QHash &, const QPointF &m, QUndoCommand * = 0); + virtual ~MoveElementsCommand(); + private: + MoveElementsCommand(const MoveElementsCommand &); + + // methodes + public: + virtual void undo(); + virtual void redo(); + virtual void move(const QPointF &); + + // attributs + private: + /// Schema sur lequel on deplace les elements + Diagram *diagram; + /// Elements a deplacer + QSet elements_to_move; + /// Conducteurs a deplacer + QSet conducers_to_move; + /// Conducteurs a actualiser + QHash conducers_to_update; + /// mouvement effectue + QPointF movement; + /// booleen pour ne pas executer le premier redo() + bool first_redo; +}; #endif diff --git a/editor/editorcommands.h b/editor/editorcommands.h index c53f469dc..6627ea345 100644 --- a/editor/editorcommands.h +++ b/editor/editorcommands.h @@ -18,6 +18,7 @@ class DeletePartsCommand : public QUndoCommand { DeletePartsCommand(const DeletePartsCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -42,6 +43,7 @@ class MovePartsCommand : public QUndoCommand { MovePartsCommand(const MovePartsCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -70,6 +72,7 @@ class AddPartCommand : public QUndoCommand { AddPartCommand(const AddPartCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -96,6 +99,7 @@ class ChangePartCommand : public QUndoCommand { ChangePartCommand(const ChangePartCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -123,6 +127,7 @@ class ChangePolygonPointsCommand : public QUndoCommand { ChangePolygonPointsCommand(const ChangePolygonPointsCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -181,6 +186,7 @@ class ChangeNamesCommand : public QUndoCommand { ChangeNamesCommand(const ChangeNamesCommand &); // methodes + public: virtual void undo(); virtual void redo(); @@ -206,6 +212,7 @@ class ChangeOrientationsCommand : public QUndoCommand { ChangeOrientationsCommand(const ChangeOrientationsCommand &); // methodes + public: virtual void undo(); virtual void redo(); diff --git a/element.cpp b/element.cpp index cb97d6251..d6692785b 100644 --- a/element.cpp +++ b/element.cpp @@ -3,6 +3,7 @@ #include "diagram.h" #include "conducer.h" #include "elementtextitem.h" +#include "diagramcommands.h" #include /** @@ -238,32 +239,43 @@ void Element::moveOtherElements(const QPointF &diff) { if (diff.isNull()) return; // recupere le schema parent - if (!scene()) return; - Diagram *diagram = qobject_cast(scene()); - if (!diagram) return; + Diagram *diagram_ptr = diagram(); + if (!diagram_ptr) return; + + diagram_ptr -> current_movement += diff; // deplace les elements selectionnes - foreach(Element *element, diagram -> elementsToMove()) { + foreach(Element *element, diagram_ptr -> elementsToMove()) { if (element == this) continue; element -> setPos(element -> pos() + diff); - }; + } // deplace certains conducteurs - foreach(Conducer *conducer, diagram -> conducersToMove()) { + foreach(Conducer *conducer, diagram_ptr -> conducersToMove()) { conducer -> setPos(conducer -> pos() + diff); } // recalcule les autres conducteurs - const QHash &conducers_modify = diagram -> conducersToUpdate(); + const QHash &conducers_modify = diagram_ptr -> conducersToUpdate(); foreach(Conducer *conducer, conducers_modify.keys()) { conducer -> updateWithNewPos(QRectF(), conducers_modify[conducer], conducers_modify[conducer] -> amarrageConducer()); } } void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) { - if (scene()) { - Diagram *diagram = qobject_cast(scene()); - if (diagram) diagram -> invalidateMovedElements(); + Diagram *diagram_ptr = diagram(); + if (diagram_ptr && !diagram_ptr -> current_movement.isNull()) { + diagram_ptr -> undoStack().push( + new MoveElementsCommand( + diagram_ptr, + diagram_ptr -> elementsToMove(), + diagram_ptr -> conducersToMove(), + diagram_ptr -> conducersToUpdate(), + diagram_ptr -> current_movement + ) + ); + diagram_ptr -> invalidateMovedElements(); + diagram_ptr -> current_movement = QPointF(); } QGraphicsItem::mouseReleaseEvent(e); }