diff --git a/diagram.cpp b/diagram.cpp index d291eb0c2..0c4bf76ed 100644 --- a/diagram.cpp +++ b/diagram.cpp @@ -252,10 +252,16 @@ QDomDocument Diagram::toXml(bool diagram) { (le bounding rect) soit a cette position. @param document Le document XML a analyser @param position La position du diagram importe - @param consider_informations Si vrai, les informations complementaires (auteur, titre, ...) seront prises en compte + @param consider_informations Si vrai, les informations complementaires + (auteur, titre, ...) seront prises en compte + @param added_elements si ce pointeur vers une liste d'elements n'est pas + NULL, il sera rempli avec les elements ajoutes au schema par le fromXml + @param added_elements si ce pointeur vers une liste de conducteurs n'est + pas NULL, il sera rempli avec les conducteurs ajoutes au schema par le + fromXml @return true si l'import a reussi, false sinon */ -bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_informations) { +bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_informations, QList *added_elements, QList *added_conducers) { QDomElement racine = document.documentElement(); // le premier element doit etre un schema if (racine.tagName() != "diagram") return(false); @@ -322,6 +328,8 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in } } + if (added_elements) (*added_elements) << elements_ajoutes; + // aucun Element n'a ete ajoute - inutile de chercher des conducteurs - le chargement est fini if (!elements_ajoutes.size()) return(true); @@ -374,6 +382,7 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in if (peut_poser_conducer) { Conducer *c = new Conducer(table_adr_id.value(id_p1), table_adr_id.value(id_p2), 0, this); c -> fromXml(f); + if (added_conducers) (*added_conducers) << c; } } } else qDebug() << "Le chargement du conducer" << id_p1 << id_p2 << "a echoue"; diff --git a/diagram.h b/diagram.h index 0c5fae12c..b814dd9c5 100644 --- a/diagram.h +++ b/diagram.h @@ -52,7 +52,7 @@ class Diagram : public QGraphicsScene { // fonctions relatives a l'import / export XML QDomDocument toXml(bool = true); - bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true); + bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, QList * = NULL, QList * = NULL); // fonctions relatives aux options graphiques void setDisplayGrid(bool); diff --git a/diagramcommands.cpp b/diagramcommands.cpp index 2a6abdbd8..c5f76890c 100644 --- a/diagramcommands.cpp +++ b/diagramcommands.cpp @@ -15,7 +15,7 @@ AddElementCommand::AddElementCommand( const QPointF &p, QUndoCommand *parent ) : - QUndoCommand(QObject::tr("ajout ") + elmt -> nom(), parent), + QUndoCommand(QObject::tr("ajouter 1 ") + elmt -> nom(), parent), element(elmt), diagram(d), position(p) @@ -52,7 +52,7 @@ AddConducerCommand::AddConducerCommand( Conducer *c, QUndoCommand *parent ) : - QUndoCommand(QObject::tr("ajout conducteur"), parent), + QUndoCommand(QObject::tr("ajouter un conducteur"), parent), conducer(c), diagram(d) { @@ -79,6 +79,10 @@ void AddConducerCommand::redo() { /** Constructeur + @param dia Schema dont on supprime des elements et conducteurs + @param elements Elements supprimes + @param conducers Conducteurs supprimes + @param parent QUndoCommand parent */ DeleteElementsCommand::DeleteElementsCommand( Diagram *dia, @@ -91,6 +95,7 @@ DeleteElementsCommand::DeleteElementsCommand( removed_conducers(conducers), diagram(dia) { + setText(QObject::tr("supprimer ") + QET::ElementsAndConducersSentence(removed_elements.count(), removed_conducers.count())); foreach(QGraphicsItem *qgi, removed_elements) diagram -> qgiManager().manage(qgi); foreach(QGraphicsItem *qgi, removed_conducers) diagram -> qgiManager().manage(qgi); } @@ -130,3 +135,86 @@ void DeleteElementsCommand::redo() { diagram -> removeItem(e); } } + +/** + Constructeur + @param dia Schema sur lequel on colle les elements et conducteurs + @param e Elements colles sur le schema + @param c Conducteurs colles sur le schema + @param parent QUndoCommand parent +*/ +PasteDiagramCommand::PasteDiagramCommand( + Diagram *dia, + const QList &e, + const QList &c, + QUndoCommand *parent +) : + QUndoCommand(parent), + elements(e), + conducers(c), + diagram(dia), + first_redo(true) +{ + setText(QObject::tr("coller ") + QET::ElementsAndConducersSentence(elements.count(), conducers.count())); + foreach(QGraphicsItem *qgi, elements) diagram -> qgiManager().manage(qgi); + foreach(QGraphicsItem *qgi, conducers) diagram -> qgiManager().manage(qgi); +} + +/// Destructeur +PasteDiagramCommand::~PasteDiagramCommand() { + foreach(QGraphicsItem *qgi, elements) diagram -> qgiManager().release(qgi); + foreach(QGraphicsItem *qgi, conducers) diagram -> qgiManager().release(qgi); +} + +/// annule le coller +void PasteDiagramCommand::undo() { + // enleve les conducteurs + foreach(Conducer *c, conducers) { + c -> terminal1 -> removeConducer(c); + c -> terminal2 -> removeConducer(c); + diagram -> removeItem(c); + } + + // enleve les elements + foreach(Element *e, elements) diagram -> removeItem(e); +} + +/// refait le coller +void PasteDiagramCommand::redo() { + if (first_redo) first_redo = false; + else { + // pose les elements + foreach(Element *e, elements) diagram -> addItem(e); + + // pose les conducteurs + foreach(Conducer *c, conducers) { + diagram -> addItem(c); + c -> terminal1 -> addConducer(c); + c -> terminal2 -> addConducer(c); + } + } + foreach(Element *e, elements) e -> setSelected(true); + foreach(Conducer *c, conducers) c -> setSelected(true); +} + +/** + Constructeur + @param dia Schema dont on supprime des elements et conducteurs + @param elements Elements supprimes + @param conducers Conducteurs supprimes + @param parent QUndoCommand parent +*/ +CutDiagramCommand::CutDiagramCommand( + Diagram *dia, + QSet elements, + QSet conducers, + QUndoCommand *parent +) : + DeleteElementsCommand(dia, elements, conducers, parent) +{ + setText(QObject::tr("couper ") + QET::ElementsAndConducersSentence(elements.count(), conducers.count())); +} + +/// Destructeur +CutDiagramCommand::~CutDiagramCommand() { +} diff --git a/diagramcommands.h b/diagramcommands.h index e4b212fbd..e9344876b 100644 --- a/diagramcommands.h +++ b/diagramcommands.h @@ -76,4 +76,44 @@ class DeleteElementsCommand : public QUndoCommand { Diagram *diagram; }; +/** + Cette classe represente l'action de coller quelque chose sur un schema +*/ +class PasteDiagramCommand : public QUndoCommand { + // constructeurs, destructeur + public: + PasteDiagramCommand(Diagram *, const QList &, const QList &, QUndoCommand * = 0); + virtual ~PasteDiagramCommand(); + private: + PasteDiagramCommand(const PasteDiagramCommand &); + + // methodes + virtual void undo(); + virtual void redo(); + + // attributs + private: + /// Elements ajoutes + QList elements; + /// conducteurs ajoutes + QList conducers; + /// schema sur lequel on colle les elements et conducteurs + Diagram *diagram; + /// booleen pour empecher le premier appel a redo + bool first_redo; +}; + +/** + Cette classe represente l'action de supprimer des elements et / ou + conducteurs d'un schema +*/ +class CutDiagramCommand : public DeleteElementsCommand { + // constructeurs, destructeur + public: + CutDiagramCommand(Diagram *, QSet, QSet, QUndoCommand * = 0); + virtual ~CutDiagramCommand(); + private: + CutDiagramCommand(const CutDiagramCommand &); +}; + #endif diff --git a/diagramview.cpp b/diagramview.cpp index 82ef08b40..65949f83c 100644 --- a/diagramview.cpp +++ b/diagramview.cpp @@ -213,7 +213,23 @@ void DiagramView::zoomReset() { */ void DiagramView::couper() { copier(); - supprimer(); + QSet cut_elmt; + QSet cut_conducers; + + // creation de deux listes : une pour les conducteurs, une pour les elements + foreach (QGraphicsItem *qgi, scene -> selectedItems()) { + // pour chaque qgi selectionne, il s'agit soit d'un element soit d'un conducteur + if (Conducer * c = qgraphicsitem_cast(qgi)) { + // s'il s'agit d'un conducteur, on le met dans la liste des conducteurs + cut_conducers << c; + } else if (Element *e = qgraphicsitem_cast(qgi)) { + cut_elmt << e; + // s'il s'agit d'un element, on veille a enlever ses conducteurs + cut_conducers += e -> conducers().toSet(); + } + } + scene -> clearSelection(); + scene -> undoStack().push(new CutDiagramCommand(scene, cut_elmt, cut_conducers)); } /** @@ -234,7 +250,17 @@ void DiagramView::coller() { QDomDocument document_xml; if ((texte_presse_papier = QApplication::clipboard() -> text()) == QString()) return; if (!document_xml.setContent(texte_presse_papier)) return; - scene -> fromXml(document_xml, QPointF(), false); + + // listes pour recupere les elements et conducteurs ajoutes au schema par le coller + QList elements_pasted; + QList conducers_pasted; + scene -> fromXml(document_xml, QPointF(), false, &elements_pasted, &conducers_pasted); + + // si quelque chose a effectivement ete ajoute au schema, on cree + if (elements_pasted.count() || conducers_pasted.count()) { + scene -> clearSelection(); + scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conducers_pasted)); + } } /** @@ -246,9 +272,20 @@ void DiagramView::mousePressEvent(QMouseEvent *e) { QDomDocument document_xml; if ((texte_presse_papier = QApplication::clipboard() -> text(QClipboard::Selection)) == QString()) return; if (!document_xml.setContent(texte_presse_papier)) return; - scene -> fromXml(document_xml, mapToScene(e -> pos()), false); + + // listes pour recupere les elements et conducteurs ajoutes au schema par le coller + QList elements_pasted; + QList conducers_pasted; + scene -> fromXml(document_xml, mapToScene(e -> pos()), false, &elements_pasted, &conducers_pasted); + + // si quelque chose a effectivement ete ajoute au schema, on cree + if (elements_pasted.count() || conducers_pasted.count()) { + scene -> clearSelection(); + scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conducers_pasted)); + } + } else { + QGraphicsView::mousePressEvent(e); } - QGraphicsView::mousePressEvent(e); } /** diff --git a/editor/qet.cpp b/editor/qet.cpp index 88563119c..264560262 100644 --- a/editor/qet.cpp +++ b/editor/qet.cpp @@ -123,3 +123,23 @@ bool QET::attributeIsAReal(const QDomElement &e, QString nom_attribut, double *r if (reel != NULL) *reel = tmp; return(true); } + +/** + Permet de composer rapidement la proposition "x elements et y conducteurs" + @param elements_count nombre d élements + @param conducers_count nombre de conducteurs + @return la proposition decrivant le nombre d'elements et de conducteurs +*/ +QString QET::ElementsAndConducersSentence(int elements_count, int conducers_count) { + QString text; + if (elements_count) { + text += QString::number(elements_count) + " "; + text += elements_count > 1 ? QObject::tr("\351l\351ments") : QObject::tr("\351l\351ment"); + if (conducers_count) text += QObject::tr(" et "); + } + if (conducers_count) { + text += QString::number(conducers_count) + " "; + text += conducers_count > 1 ? QObject::tr("conducteurs") : QObject::tr("conducteur"); + } + return(text); +} diff --git a/qet.h b/qet.h index 29fe8980f..338532698 100644 --- a/qet.h +++ b/qet.h @@ -18,5 +18,6 @@ namespace QET { bool estVerticale(QET::Orientation); bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL); bool attributeIsAReal(const QDomElement &, QString , double * = NULL); + QString ElementsAndConducersSentence(int, int); } #endif