diff --git a/editor/editorcommands.cpp b/editor/editorcommands.cpp index cfc2b6ea0..e61df3e58 100644 --- a/editor/editorcommands.cpp +++ b/editor/editorcommands.cpp @@ -335,3 +335,126 @@ void ChangeOrientationsCommand::redo() { element -> setOrientations(ori_after); } +/** + Constructeur + @param element ElementScene concernee + @param o Option decrivant le type de traitement applique aux zValues des parties de l'element + @param parent QUndoCommand parent +*/ +ChangeZValueCommand::ChangeZValueCommand( + ElementScene *elmt, + ChangeZValueCommand::Option o, + QUndoCommand *parent +) : + QUndoCommand(parent), + element(elmt), + option(o) +{ + // recupere les parties de l'elements, sauf les bornes + QList items_list = element -> zItems(); + + // prend un snapshot des zValues + foreach(QGraphicsItem *qgi, items_list) undo_hash.insert(qgi, qgi -> zValue()); + + // choisit le nom en fonction du traitement + if (option == BringForward) { + setText(QObject::tr("amener au premier plan")); + applyBringForward(items_list); + } else if (option == Raise) { + setText(QObject::tr("rapprocher")); + applyRaise(items_list); + } else if (option == Lower) { + setText(QObject::tr("\351loigner")); + applyLower(items_list); + } else if (option == SendBackward) { + setText(QObject::tr("envoyer au fond")); + applySendBackward(items_list); + } +} + +/// Destructeur +ChangeZValueCommand::~ChangeZValueCommand() { +} + +/// Annule les changements de zValue +void ChangeZValueCommand::undo() { + foreach(QGraphicsItem *qgi, undo_hash.keys()) qgi -> setZValue(undo_hash[qgi]); +} + +/// Refait les changements de zValue +void ChangeZValueCommand::redo() { + foreach(QGraphicsItem *qgi, redo_hash.keys()) qgi -> setZValue(redo_hash[qgi]); +} + +/** + Amene les elements selectionnes au premier plan + @param items_list Liste des elements (selectionnes et non selectionnes) +*/ +void ChangeZValueCommand::applyBringForward(const QList &items_list) { + QList non_selected_items = items_list; + QList selected_items; + foreach(QGraphicsItem *qgi, non_selected_items) { + if (qgi -> isSelected()) { + selected_items << qgi; + non_selected_items.removeAt(non_selected_items.indexOf(qgi)); + } + } + int z = 1; + foreach(QGraphicsItem *qgi, non_selected_items) redo_hash.insert(qgi, z ++); + foreach(QGraphicsItem *qgi, selected_items) redo_hash.insert(qgi, z ++); +} + +/** + Remonte les elements selectionnes d'un plan + @param items_list Liste des elements (selectionnes et non selectionnes) +*/ +void ChangeZValueCommand::applyRaise(const QList &items_list) { + QList my_items_list = items_list; + + for (int i = my_items_list.count() - 2 ; i >= 0 ; -- i) { + if (my_items_list[i] -> isSelected()) { + if (!my_items_list[i +1] -> isSelected()) { + my_items_list.swap(i, i + 1); + } + } + } + int z = 1; + foreach(QGraphicsItem *qgi, my_items_list) redo_hash.insert(qgi, z ++); +} + +/** + Descend les elements selectionnes d'un plan + @param items_list Liste des elements (selectionnes et non selectionnes) +*/ +void ChangeZValueCommand::applyLower(const QList &items_list) { + QList my_items_list = items_list; + + for (int i = 1 ; i < my_items_list.count() ; ++ i) { + if (my_items_list[i] -> isSelected()) { + if (!my_items_list[i - 1] -> isSelected()) { + my_items_list.swap(i, i - 1); + } + } + } + + int z = 1; + foreach(QGraphicsItem *qgi, my_items_list) redo_hash.insert(qgi, z ++); +} + +/** + Envoie les elements selectionnes au fond + @param items_list Liste des elements (selectionnes et non selectionnes) +*/ +void ChangeZValueCommand::applySendBackward(const QList &items_list) { + QList non_selected_items = items_list; + QList selected_items; + foreach(QGraphicsItem *qgi, non_selected_items) { + if (qgi -> isSelected()) { + selected_items << qgi; + non_selected_items.removeAt(non_selected_items.indexOf(qgi)); + } + } + int z = 1; + foreach(QGraphicsItem *qgi, selected_items) redo_hash.insert(qgi, z ++); + foreach(QGraphicsItem *qgi, non_selected_items) redo_hash.insert(qgi, z ++); +} diff --git a/editor/editorcommands.h b/editor/editorcommands.h index 6627ea345..c29bb7a9f 100644 --- a/editor/editorcommands.h +++ b/editor/editorcommands.h @@ -225,4 +225,39 @@ class ChangeOrientationsCommand : public QUndoCommand { /// Element edite auquel il faut appliquer les modifications ElementScene *element; }; + +/** + Cette classe represente l'action de changer les noms d'un element +*/ +class ChangeZValueCommand : public QUndoCommand { + // constructeurs, destructeur + public: + enum Option { BringForward, Raise, Lower, SendBackward }; + ChangeZValueCommand(ElementScene *, Option, QUndoCommand * = 0); + virtual ~ChangeZValueCommand(); + private: + ChangeZValueCommand(const ChangeZValueCommand &); + + // methodes + public: + virtual void undo(); + virtual void redo(); + + private: + void applyBringForward(const QList &); + void applyRaise(const QList &); + void applyLower(const QList &); + void applySendBackward(const QList &); + + // attributs + private: + /// zValues avant changement + QHash undo_hash; + /// zValues apres changement + QHash redo_hash; + /// Element edite auquel il faut appliquer les modifications + ElementScene *element; + /// type de traitement + Option option; +}; #endif diff --git a/editor/elementscene.cpp b/editor/elementscene.cpp index 48fd98d72..60b66e6ce 100644 --- a/editor/elementscene.cpp +++ b/editor/elementscene.cpp @@ -300,7 +300,7 @@ const QDomDocument ElementScene::toXml() const { QDomElement description = xml_document.createElement("description"); // description de l'element - foreach(QGraphicsItem *qgi, items()) { + foreach(QGraphicsItem *qgi, zItems(true)) { if (CustomElementPart *ce = dynamic_cast(qgi)) { description.appendChild(ce -> toXml(xml_document)); } @@ -535,3 +535,58 @@ void ElementScene::slot_editNames() { } } +/** + Amene les elements selectionnes au premier plan +*/ +void ElementScene::slot_bringForward() { + undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::BringForward)); +} + +/** + Remonte les elements selectionnes d'un plan +*/ +void ElementScene::slot_raise() { + undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::Raise)); +} + +/** + Descend les elements selectionnes d'un plan +*/ +void ElementScene::slot_lower() { + undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::Lower)); +} + +/** + Envoie les elements selectionnes au fond +*/ +void ElementScene::slot_sendBackward() { + undoStack().push(new ChangeZValueCommand(this, ChangeZValueCommand::SendBackward)); +} + +/** + @param include_terminals true pour inclure les bornes, false sinon + @return les parties de l'element ordonnes par zValue croissante +*/ +QList ElementScene::zItems(bool include_terminals) const { + // recupere les elements + QList all_items_list(items()); + + // enleve les bornes + QList terminals; + foreach(QGraphicsItem *qgi, all_items_list) { + if (qgraphicsitem_cast(qgi)) { + all_items_list.removeAt(all_items_list.indexOf(qgi)); + terminals << qgi; + } + } + + // ordonne les parties par leur zValue + QMultiMap mm; + foreach(QGraphicsItem *qgi, all_items_list) mm.insert(qgi -> zValue(), qgi); + all_items_list.clear(); + foreach(qreal z, mm.keys()) all_items_list += mm.values(z); + + // rajoute eventuellement les bornes + if (include_terminals) all_items_list += terminals; + return(all_items_list); +} diff --git a/editor/elementscene.h b/editor/elementscene.h index 48d392a74..8a7eb55d0 100644 --- a/editor/elementscene.h +++ b/editor/elementscene.h @@ -67,6 +67,7 @@ class ElementScene : public QGraphicsScene { void setOrientations(const OrientationSet &); virtual const QDomDocument toXml() const; virtual void fromXml(const QDomDocument &); + virtual QList zItems(bool = false) const; QRectF sceneContent() const; QUndoStack &undoStack(); QGIManager &qgiManager(); @@ -96,6 +97,10 @@ class ElementScene : public QGraphicsScene { void slot_editSizeHotSpot(); void slot_editNames(); void slot_editOrientations(); + void slot_bringForward(); + void slot_raise(); + void slot_lower(); + void slot_sendBackward(); signals: void selectionChanged(); diff --git a/editor/partarc.h b/editor/partarc.h index dce580d0f..bbd5880c6 100644 --- a/editor/partarc.h +++ b/editor/partarc.h @@ -20,6 +20,8 @@ class PartArc : public QGraphicsEllipseItem, public CustomElementGraphicPart { // methodes public: + enum { Type = UserType + 1101 }; + virtual int type() const { return Type; } virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0); virtual const QDomElement toXml(QDomDocument &) const; virtual void fromXml(const QDomElement &); diff --git a/editor/partcircle.h b/editor/partcircle.h index c9dce8078..891b4056e 100644 --- a/editor/partcircle.h +++ b/editor/partcircle.h @@ -18,6 +18,8 @@ class PartCircle : public QGraphicsEllipseItem, public CustomElementGraphicPart // methodes public: + enum { Type = UserType + 1102 }; + virtual int type() const { return Type; } virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0); virtual const QDomElement toXml(QDomDocument &) const; virtual void fromXml(const QDomElement &); diff --git a/editor/partellipse.h b/editor/partellipse.h index e6cc24300..45e7241b1 100644 --- a/editor/partellipse.h +++ b/editor/partellipse.h @@ -18,6 +18,8 @@ class PartEllipse : public QGraphicsEllipseItem, public CustomElementGraphicPart // methodes public: + enum { Type = UserType + 1103 }; + virtual int type() const { return Type; } virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0); virtual const QDomElement toXml(QDomDocument &) const; virtual void fromXml(const QDomElement &); diff --git a/editor/partline.h b/editor/partline.h index 456d63075..6599b9ee5 100644 --- a/editor/partline.h +++ b/editor/partline.h @@ -18,6 +18,8 @@ class PartLine : public QGraphicsLineItem, public CustomElementGraphicPart { // methodes public: + enum { Type = UserType + 1104 }; + virtual int type() const { return Type; } virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget * = 0); virtual const QDomElement toXml(QDomDocument &) const; virtual void fromXml(const QDomElement &); diff --git a/editor/partpolygon.h b/editor/partpolygon.h index 1cf824f18..1d8776e78 100644 --- a/editor/partpolygon.h +++ b/editor/partpolygon.h @@ -31,6 +31,8 @@ class PartPolygon : public QGraphicsPolygonItem, public CustomElementGraphicPart */ // methodes public: + enum { Type = UserType + 1105 }; + virtual int type() const { return Type; } void fromXml(const QDomElement &); const QDomElement toXml(QDomDocument &) const; void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); diff --git a/editor/partterminal.h b/editor/partterminal.h index 7615939ed..19865f58a 100644 --- a/editor/partterminal.h +++ b/editor/partterminal.h @@ -21,6 +21,8 @@ class PartTerminal : public CustomElementPart, public QGraphicsItem { // methodes public: + enum { Type = UserType + 1106 }; + virtual int type() const { return Type; } virtual void fromXml(const QDomElement &); virtual const QDomElement toXml(QDomDocument &) const; virtual QWidget *elementInformations(); diff --git a/editor/parttext.h b/editor/parttext.h index fae588032..aefe56366 100644 --- a/editor/parttext.h +++ b/editor/parttext.h @@ -17,6 +17,8 @@ class PartText : public QGraphicsTextItem, public CustomElementPart { // methodes public: + enum { Type = UserType + 1107 }; + virtual int type() const { return Type; } void fromXml(const QDomElement &); const QDomElement toXml(QDomDocument &) const; QWidget *elementInformations(); diff --git a/editor/parttextfield.h b/editor/parttextfield.h index 33331339e..7194fdf24 100644 --- a/editor/parttextfield.h +++ b/editor/parttextfield.h @@ -19,6 +19,8 @@ class PartTextField : public QGraphicsTextItem, public CustomElementPart { // methodes public: + enum { Type = UserType + 1108 }; + virtual int type() const { return Type; } void fromXml(const QDomElement &); const QDomElement toXml(QDomDocument &) const; QWidget *elementInformations(); diff --git a/editor/qetelementeditor.cpp b/editor/qetelementeditor.cpp index a215bb028..d367fb922 100644 --- a/editor/qetelementeditor.cpp +++ b/editor/qetelementeditor.cpp @@ -36,6 +36,10 @@ void QETElementEditor::setupActions() { edit_size_hs = new QAction( tr("\311diter la taille et le point de saisie"), this); edit_names = new QAction( tr("\311diter les noms"), this); edit_ori = new QAction(QIcon(":/ico/orientations.png"), tr("\311diter les orientations"), this); + edit_raise = new QAction(QIcon(":/ico/raise.png"), tr("Rapprocher"), this); + edit_lower = new QAction(QIcon(":/ico/lower.png"), tr("\311loigner"), this); + edit_backward = new QAction(QIcon(":/ico/send_backward.png"),tr("Envoyer au fond"), this); + edit_forward = new QAction(QIcon(":/ico/bring_forward.png"),tr("Amener au premier plan"), this); move = new QAction(QIcon(":/ico/select.png"), tr("D\351placer un objet"), this); add_line = new QAction(QIcon(":/ico/line.png"), tr("Ajouter une ligne"), this); add_ellipse = new QAction(QIcon(":/ico/ellipse.png"), tr("Ajouter une ellipse"), this); @@ -65,6 +69,11 @@ void QETElementEditor::setupActions() { edit_size_hs -> setShortcut(QKeySequence(tr("Ctrl+R"))); edit_ori -> setShortcut(QKeySequence(tr("Ctrl+T"))); + edit_raise -> setShortcut(QKeySequence(tr("Ctrl+Shift+Up"))); + edit_lower -> setShortcut(QKeySequence(tr("Ctrl+Shift+Down"))); + edit_backward -> setShortcut(QKeySequence(tr("Ctrl+Shift+End"))); + edit_forward -> setShortcut(QKeySequence(tr("Ctrl+Shift+Home"))); + connect(new_element, SIGNAL(triggered()), this, SLOT(slot_new())); connect(open, SIGNAL(triggered()), this, SLOT(slot_open())); connect(save, SIGNAL(triggered()), this, SLOT(slot_save())); @@ -77,6 +86,10 @@ void QETElementEditor::setupActions() { connect(edit_size_hs, SIGNAL(triggered()), ce_scene, SLOT(slot_editSizeHotSpot())); connect(edit_names, SIGNAL(triggered()), ce_scene, SLOT(slot_editNames())); connect(edit_ori, SIGNAL(triggered()), ce_scene, SLOT(slot_editOrientations())); + connect(edit_forward, SIGNAL(triggered()), ce_scene, SLOT(slot_bringForward())); + connect(edit_raise, SIGNAL(triggered()), ce_scene, SLOT(slot_raise())); + connect(edit_lower, SIGNAL(triggered()), ce_scene, SLOT(slot_lower())); + connect(edit_backward, SIGNAL(triggered()), ce_scene, SLOT(slot_sendBackward())); connect(move, SIGNAL(triggered()), ce_scene, SLOT(slot_move())); connect(add_line, SIGNAL(triggered()), ce_scene, SLOT(slot_addLine())); connect(add_ellipse, SIGNAL(triggered()), ce_scene, SLOT(slot_addEllipse())); @@ -127,9 +140,11 @@ void QETElementEditor::setupActions() { move -> setChecked(true); parts_toolbar -> setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); + /* QAction *xml_preview = new QAction(QIcon(":/ico/info.png"), tr("XML"), this); connect(xml_preview, SIGNAL(triggered()), this, SLOT(xmlPreview())); parts_toolbar -> addAction(xml_preview); + */ addToolBar(Qt::LeftToolBarArea, parts_toolbar); @@ -171,6 +186,11 @@ void QETElementEditor::setupMenus() { edit_menu -> addAction(edit_names); edit_menu -> addAction(edit_size_hs); edit_menu -> addAction(edit_ori); + edit_menu -> addSeparator(); + edit_menu -> addAction(edit_forward); + edit_menu -> addAction(edit_raise); + edit_menu -> addAction(edit_lower); + edit_menu -> addAction(edit_backward); // menu Affichage > Afficher QMenu *display_toolbars = createPopupMenu(); @@ -189,7 +209,12 @@ void QETElementEditor::setupMenus() { } void QETElementEditor::slot_updateMenus() { - edit_delete -> setEnabled(!ce_scene -> selectedItems().isEmpty()); + bool selected_items = !ce_scene -> selectedItems().isEmpty(); + edit_delete -> setEnabled(selected_items); + edit_forward -> setEnabled(selected_items); + edit_raise -> setEnabled(selected_items); + edit_lower -> setEnabled(selected_items); + edit_backward -> setEnabled(selected_items); save -> setEnabled(!ce_scene -> undoStack().isClean()); } diff --git a/editor/qetelementeditor.h b/editor/qetelementeditor.h index acabc032e..6e357461a 100644 --- a/editor/qetelementeditor.h +++ b/editor/qetelementeditor.h @@ -34,6 +34,7 @@ class QETElementEditor : public QMainWindow { QAction *selectall, *deselectall, *inv_select; QAction *undo, *redo; QAction *edit_delete, *edit_size_hs, *edit_names, *edit_ori; + QAction *edit_raise, *edit_lower, *edit_backward, *edit_forward; /// barre d'outils QToolBar *parts_toolbar; /// actions de la barre d'outils diff --git a/qelectrotech.qrc b/qelectrotech.qrc index b5127ff52..df4a291d2 100644 --- a/qelectrotech.qrc +++ b/qelectrotech.qrc @@ -6,6 +6,7 @@ ico/allowed.png ico/add_col.png ico/arc.png + ico/bring_forward.png ico/button_cancel.png ico/button_ok.png ico/category_delete.png @@ -31,6 +32,7 @@ ico/import.png ico/info.png ico/line.png + ico/lower.png ico/masquer.png ico/move.png ico/neutral.png @@ -44,6 +46,7 @@ ico/polygon.png ico/print.png ico/qt.png + ico/raise.png ico/redo.png ico/reload.png ico/remove_col.png @@ -51,6 +54,7 @@ ico/saveas.png ico/save.png ico/select.png + ico/send_backward.png ico/sortir_fs.png ico/south.png ico/terminal.png