mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-20 16:20:52 +01:00
Implementation partielle de l'alignement des conducteurs sur la grille. Lors de la modification manuelle des conducteurs, les segments se fixent sur la grille. L'ancien comportement peut etre obtenu en maintenant la touche Shift enfoncee. Optimisation des fonctions "Selectionner tout" et "Deselectionner tout" Remplacement des #define par des attributs static const git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@168 bfdf4180-ca20-0410-9c96-a3a8aa849046
594 lines
19 KiB
C++
594 lines
19 KiB
C++
#include "elementscene.h"
|
|
#include "qetelementeditor.h"
|
|
#include <cmath>
|
|
#include "partline.h"
|
|
#include "partellipse.h"
|
|
#include "partcircle.h"
|
|
#include "partpolygon.h"
|
|
#include "partterminal.h"
|
|
#include "parttext.h"
|
|
#include "parttextfield.h"
|
|
#include "partarc.h"
|
|
#include "hotspoteditor.h"
|
|
#include "editorcommands.h"
|
|
|
|
const int ElementScene::xGrid = 10;
|
|
const int ElementScene::yGrid = 10;
|
|
|
|
ElementScene::ElementScene(QETElementEditor *editor, QObject *parent) :
|
|
QGraphicsScene(parent),
|
|
_width(3),
|
|
_height(7),
|
|
_hotspot(15, 35),
|
|
qgi_manager(this),
|
|
element_editor(editor)
|
|
{
|
|
current_polygon = NULL;
|
|
undo_stack.setClean();
|
|
connect(this, SIGNAL(changed(const QList<QRectF> &)), this, SLOT(slot_checkSelectionChanged()));
|
|
}
|
|
|
|
ElementScene::~ElementScene() {
|
|
}
|
|
|
|
void ElementScene::slot_move() {
|
|
behavior = Normal;
|
|
}
|
|
|
|
void ElementScene::slot_addLine() {
|
|
behavior = Line;
|
|
}
|
|
|
|
void ElementScene::slot_addCircle() {
|
|
behavior = Circle;
|
|
}
|
|
|
|
void ElementScene::slot_addEllipse() {
|
|
behavior = Ellipse;
|
|
}
|
|
|
|
void ElementScene::slot_addPolygon() {
|
|
behavior = Polygon;
|
|
}
|
|
|
|
void ElementScene::slot_addText() {
|
|
behavior = Text;
|
|
}
|
|
|
|
void ElementScene::slot_addTerminal() {
|
|
behavior = Terminal;
|
|
}
|
|
|
|
void ElementScene::slot_addArc() {
|
|
behavior = Arc;
|
|
}
|
|
|
|
void ElementScene::slot_addTextField() {
|
|
behavior = TextField;
|
|
}
|
|
|
|
void ElementScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
|
|
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
|
QRectF temp_rect;
|
|
qreal radius;
|
|
QPointF temp_point;
|
|
QPolygonF temp_polygon;
|
|
if (e -> buttons() & Qt::LeftButton) {
|
|
switch(behavior) {
|
|
case Line:
|
|
current_line -> setLine(QLineF(current_line -> line().p1(), e -> scenePos()));
|
|
break;
|
|
case Ellipse:
|
|
temp_rect = current_ellipse -> rect();
|
|
temp_rect.setBottomRight(e -> scenePos());
|
|
current_ellipse -> setRect(temp_rect);
|
|
break;
|
|
case Arc:
|
|
temp_rect = current_arc -> rect();
|
|
temp_rect.setBottomRight(e -> scenePos());
|
|
current_arc -> setRect(temp_rect);
|
|
break;
|
|
case Circle:
|
|
temp_rect = current_circle -> rect();
|
|
temp_point = e -> scenePos() - current_circle -> mapToScene(temp_rect.center());
|
|
radius = sqrt(pow(temp_point.x(), 2) + pow(temp_point.y(), 2));
|
|
temp_rect = QRectF(
|
|
temp_rect.center() - QPointF(radius, radius),
|
|
QSizeF(2.0 * radius, 2.0 * radius)
|
|
);
|
|
current_circle -> setRect(temp_rect);
|
|
break;
|
|
case Polygon:
|
|
if (current_polygon == NULL) break;
|
|
temp_polygon = current_polygon -> polygon();
|
|
temp_polygon.pop_back();
|
|
temp_polygon << e -> scenePos();
|
|
current_polygon -> setPolygon(temp_polygon);
|
|
break;
|
|
case Normal:
|
|
default:
|
|
QGraphicsScene::mouseMoveEvent(e);
|
|
}
|
|
} else if (behavior == Polygon && current_polygon != NULL) {
|
|
temp_polygon = current_polygon -> polygon();
|
|
temp_polygon.pop_back();
|
|
temp_polygon << e -> scenePos();
|
|
current_polygon -> setPolygon(temp_polygon);
|
|
} else QGraphicsScene::mouseMoveEvent(e);
|
|
}
|
|
|
|
void ElementScene::mousePressEvent(QGraphicsSceneMouseEvent *e) {
|
|
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
|
QPolygonF temp_polygon;
|
|
if (e -> button() & Qt::LeftButton) {
|
|
switch(behavior) {
|
|
case Line:
|
|
current_line = new PartLine(element_editor, 0, this);
|
|
current_line -> setLine(QLineF(e -> scenePos(), e -> scenePos()));
|
|
break;
|
|
case Ellipse:
|
|
current_ellipse = new PartEllipse(element_editor, 0, this);
|
|
current_ellipse -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
|
current_ellipse -> setProperty("antialias", true);
|
|
break;
|
|
case Arc:
|
|
current_arc = new PartArc(element_editor, 0, this);
|
|
current_arc -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
|
current_arc -> setProperty("antialias", true);
|
|
break;
|
|
case Circle:
|
|
current_circle = new PartCircle(element_editor, 0, this);
|
|
current_circle -> setRect(QRectF(e -> scenePos(), QSizeF(0.0, 0.0)));
|
|
current_circle -> setProperty("antialias", true);
|
|
break;
|
|
case Polygon:
|
|
if (current_polygon == NULL) {
|
|
current_polygon = new PartPolygon(element_editor, 0, this);
|
|
temp_polygon = QPolygonF(0);
|
|
} else temp_polygon = current_polygon -> polygon();
|
|
// au debut, on insere deux points
|
|
if (!temp_polygon.count()) temp_polygon << e -> scenePos();
|
|
temp_polygon << e -> scenePos();
|
|
current_polygon -> setPolygon(temp_polygon);
|
|
break;
|
|
case Normal:
|
|
default:
|
|
QGraphicsScene::mousePressEvent(e);
|
|
if (!selectedItems().isEmpty()) fsi_pos = selectedItems().first() -> scenePos();
|
|
}
|
|
} else QGraphicsScene::mousePressEvent(e);
|
|
}
|
|
|
|
void ElementScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
|
|
PartTerminal *terminal;
|
|
PartText *text;
|
|
PartTextField *textfield;
|
|
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
|
if (e -> button() & Qt::LeftButton) {
|
|
switch(behavior) {
|
|
case Line:
|
|
undo_stack.push(new AddPartCommand(tr("ligne"), this, current_line));
|
|
break;
|
|
case Ellipse:
|
|
current_ellipse -> setRect(current_ellipse -> rect().normalized());
|
|
undo_stack.push(new AddPartCommand(tr("ellipse"), this, current_ellipse));
|
|
break;
|
|
case Arc:
|
|
current_arc-> setRect(current_arc -> rect().normalized());
|
|
undo_stack.push(new AddPartCommand(tr("arc"), this, current_arc));
|
|
break;
|
|
case Circle:
|
|
current_circle -> setRect(current_circle -> rect().normalized());
|
|
undo_stack.push(new AddPartCommand(tr("cercle"), this, current_circle));
|
|
break;
|
|
case Terminal:
|
|
terminal = new PartTerminal(element_editor, 0, this);
|
|
terminal -> setPos(e -> scenePos());
|
|
undo_stack.push(new AddPartCommand(tr("borne"), this, terminal));
|
|
break;
|
|
case Text:
|
|
text = new PartText(element_editor, 0, this);
|
|
text -> setPos(e -> scenePos());
|
|
undo_stack.push(new AddPartCommand(tr("texte"), this, text));
|
|
break;
|
|
case TextField:
|
|
textfield = new PartTextField(element_editor, 0, this);
|
|
textfield -> setPos(e -> scenePos());
|
|
undo_stack.push(new AddPartCommand(tr("champ de texte"), this, textfield));
|
|
break;
|
|
case Normal:
|
|
default:
|
|
QGraphicsScene::mouseReleaseEvent(e);
|
|
// detecte les deplacements de parties
|
|
if (!selectedItems().isEmpty()) {
|
|
QPointF movement = selectedItems().first() -> scenePos() - fsi_pos;
|
|
if (!movement.isNull()) {
|
|
undo_stack.push(new MovePartsCommand(movement, this, selectedItems()));
|
|
}
|
|
}
|
|
}
|
|
} else if (e -> button() & Qt::RightButton) {
|
|
if (behavior == Polygon) {
|
|
behavior = Normal;
|
|
undo_stack.push(new AddPartCommand(tr("polygone"), this, current_polygon));
|
|
current_polygon = NULL;
|
|
emit(needNormalMode());
|
|
} else QGraphicsScene::mouseReleaseEvent(e);
|
|
} else QGraphicsScene::mouseReleaseEvent(e);
|
|
}
|
|
|
|
/**
|
|
Dessine l'arriere-plan de l'editeur, cad la grille.
|
|
@param p Le QPainter a utiliser pour dessiner
|
|
@param r Le rectangle de la zone a dessiner
|
|
*/
|
|
void ElementScene::drawBackground(QPainter *p, const QRectF &r) {
|
|
p -> save();
|
|
|
|
// desactive tout antialiasing, sauf pour le texte
|
|
p -> setRenderHint(QPainter::Antialiasing, false);
|
|
p -> setRenderHint(QPainter::TextAntialiasing, true);
|
|
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
|
|
|
// dessine un fond blanc
|
|
p -> setPen(Qt::NoPen);
|
|
p -> setBrush(Qt::white);
|
|
p -> drawRect(r);
|
|
|
|
// encadre la zone dessinable de l'element
|
|
QRectF drawable_area(-_hotspot.x(), -_hotspot.y(), width(), height());
|
|
p -> setPen(Qt::black);
|
|
p -> setBrush(Qt::NoBrush);
|
|
p -> drawRect(drawable_area);
|
|
|
|
if (r.width() < 2500 && r.height() < 2500) {
|
|
// dessine les points de la grille
|
|
p -> setPen(Qt::black);
|
|
p -> setBrush(Qt::NoBrush);
|
|
qreal limite_x = r.x() + r.width();
|
|
qreal limite_y = r.y() + r.height();
|
|
|
|
int g_x = (int)ceil(r.x());
|
|
while (g_x % xGrid) ++ g_x;
|
|
int g_y = (int)ceil(r.y());
|
|
while (g_y % yGrid) ++ g_y;
|
|
|
|
for (int gx = g_x ; gx < limite_x ; gx += xGrid) {
|
|
for (int gy = g_y ; gy < limite_y ; gy += yGrid) {
|
|
p -> drawPoint(gx, gy);
|
|
}
|
|
}
|
|
}
|
|
p -> restore();
|
|
}
|
|
|
|
/**
|
|
Dessine l'arriere-plan de l'editeur, cad l'indicateur de hotspotó.
|
|
@param p Le QPainter a utiliser pour dessiner
|
|
@param r Le rectangle de la zone a dessiner
|
|
*/
|
|
void ElementScene::drawForeground(QPainter *p, const QRectF &) {
|
|
p -> save();
|
|
|
|
// desactive tout antialiasing, sauf pour le texte
|
|
p -> setRenderHint(QPainter::Antialiasing, false);
|
|
p -> setRenderHint(QPainter::TextAntialiasing, true);
|
|
p -> setRenderHint(QPainter::SmoothPixmapTransform, false);
|
|
|
|
p -> setPen(Qt::red);
|
|
p -> setBrush(Qt::NoBrush);
|
|
p -> drawLine(QLineF(0.0, -_hotspot.y(), 0.0, height() - _hotspot.y()));
|
|
p -> drawLine(QLineF(-_hotspot.x(), 0.0, width() - _hotspot.x(), 0.0));
|
|
p -> restore();
|
|
}
|
|
|
|
const QDomDocument ElementScene::toXml() const {
|
|
// document XML
|
|
QDomDocument xml_document;
|
|
|
|
// racine du document XML
|
|
QDomElement root = xml_document.createElement("definition");
|
|
root.setAttribute("type", "element");
|
|
root.setAttribute("width", QString("%1").arg(_width * 10));
|
|
root.setAttribute("height", QString("%1").arg(_height * 10));
|
|
root.setAttribute("hotspot_x", QString("%1").arg(_hotspot.x()));
|
|
root.setAttribute("hotspot_y", QString("%1").arg(_hotspot.y()));
|
|
root.setAttribute("orientation", ori.toString());
|
|
root.setAttribute("version", QET::version);
|
|
|
|
// noms de l'element
|
|
root.appendChild(_names.toXml(xml_document));
|
|
|
|
QDomElement description = xml_document.createElement("description");
|
|
// description de l'element
|
|
foreach(QGraphicsItem *qgi, zItems(true)) {
|
|
if (CustomElementPart *ce = dynamic_cast<CustomElementPart *>(qgi)) {
|
|
description.appendChild(ce -> toXml(xml_document));
|
|
}
|
|
}
|
|
root.appendChild(description);
|
|
|
|
xml_document.appendChild(root);
|
|
return(xml_document);
|
|
}
|
|
|
|
void ElementScene::fromXml(const QDomDocument &xml_document) {
|
|
|
|
QString error_message;
|
|
bool state = true;
|
|
|
|
// la racine est supposee etre une definition d'element
|
|
QDomElement root = xml_document.documentElement();
|
|
if (root.tagName() != "definition" || root.attribute("type") != "element") {
|
|
state = false;
|
|
error_message = tr("Ce document XML n'est pas une definition d'\351l\351ment.");
|
|
}
|
|
|
|
// dimensions et hotspot
|
|
if (state) {
|
|
// ces attributs doivent etre presents et valides
|
|
int w, h, hot_x, hot_y;
|
|
if (
|
|
!QET::attributeIsAnInteger(root, QString("width"), &w) ||\
|
|
!QET::attributeIsAnInteger(root, QString("height"), &h) ||\
|
|
!QET::attributeIsAnInteger(root, QString("hotspot_x"), &hot_x) ||\
|
|
!QET::attributeIsAnInteger(root, QString("hotspot_y"), &hot_y)
|
|
) {
|
|
state = false;
|
|
error_message = tr("Les dimensions ou le point de saisie ne sont pas valides.");
|
|
} else {
|
|
setWidth(w);
|
|
setHeight(h);
|
|
setHotspot(QPoint(hot_x, hot_y));
|
|
}
|
|
}
|
|
|
|
// orientations
|
|
if (state) {
|
|
if (!ori.fromString(root.attribute("orientation"))) {
|
|
state = false;
|
|
error_message = tr("Les orientations ne sont pas valides.");
|
|
}
|
|
}
|
|
|
|
// extrait les noms de la definition XML
|
|
if (state) {
|
|
_names.fromXml(root);
|
|
}
|
|
|
|
// parcours des enfants de la definition : parties de l'element
|
|
if (state) {
|
|
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
|
|
QDomElement elmts = node.toElement();
|
|
if (elmts.isNull()) continue;
|
|
if (elmts.tagName() == "description") {
|
|
// gestion de la description graphique de l'element
|
|
// = parcours des differentes parties du dessin
|
|
int z = 1;
|
|
for (QDomNode n = node.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
|
|
QDomElement qde = n.toElement();
|
|
if (qde.isNull()) continue;
|
|
CustomElementPart *cep;
|
|
if (qde.tagName() == "line") cep = new PartLine (element_editor, 0, this);
|
|
else if (qde.tagName() == "ellipse") cep = new PartEllipse (element_editor, 0, this);
|
|
else if (qde.tagName() == "circle") cep = new PartCircle (element_editor, 0, this);
|
|
else if (qde.tagName() == "polygon") cep = new PartPolygon (element_editor, 0, this);
|
|
else if (qde.tagName() == "terminal") cep = new PartTerminal (element_editor, 0, this);
|
|
else if (qde.tagName() == "text") cep = new PartText (element_editor, 0, this);
|
|
else if (qde.tagName() == "input") cep = new PartTextField(element_editor, 0, this);
|
|
else if (qde.tagName() == "arc") cep = new PartArc (element_editor, 0, this);
|
|
else continue;
|
|
if (QGraphicsItem *qgi = dynamic_cast<QGraphicsItem *>(cep)) qgi -> setZValue(z++);
|
|
cep -> fromXml(qde);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
QRectF ElementScene::sceneContent() const {
|
|
return(itemsBoundingRect().unite(QRectF(-_hotspot, QSizeF(width(), height()))));
|
|
}
|
|
|
|
QUndoStack &ElementScene::undoStack() {
|
|
return(undo_stack);
|
|
}
|
|
|
|
QGIManager &ElementScene::qgiManager() {
|
|
return(qgi_manager);
|
|
}
|
|
|
|
void ElementScene::slot_checkSelectionChanged() {
|
|
static QList<QGraphicsItem *> cache_selecteditems = QList<QGraphicsItem *>();
|
|
QList<QGraphicsItem *> selecteditems = selectedItems();
|
|
if (cache_selecteditems != selecteditems) emit(selectionChanged());
|
|
cache_selecteditems = selecteditems;
|
|
}
|
|
|
|
void ElementScene::slot_selectAll() {
|
|
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(true);
|
|
}
|
|
|
|
void ElementScene::slot_deselectAll() {
|
|
clearSelection();
|
|
}
|
|
|
|
void ElementScene::slot_invertSelection() {
|
|
foreach(QGraphicsItem *qgi, items()) qgi -> setSelected(!qgi -> isSelected());
|
|
}
|
|
|
|
void ElementScene::slot_delete() {
|
|
// si un item a le focus et que ce slot est appele, c'est sans doute parce
|
|
// que la touche suppr a ete enfoncee pour effacer une lettre et non la
|
|
// selection
|
|
if (focusItem()) return;
|
|
|
|
// verifie qu'il y a qqc de selectionne
|
|
QList<QGraphicsItem *> selected_items = selectedItems();
|
|
if (selected_items.isEmpty()) return;
|
|
|
|
// efface tout ce qui est selectionne
|
|
undo_stack.push(new DeletePartsCommand(this, selected_items));
|
|
}
|
|
|
|
void ElementScene::slot_editSizeHotSpot() {
|
|
// cree un dialogue
|
|
QDialog dialog_sh;
|
|
dialog_sh.setModal(true);
|
|
dialog_sh.setMinimumSize(400, 230);
|
|
dialog_sh.setWindowTitle(tr("\311diter la taille et le point de saisie"));
|
|
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_sh);
|
|
|
|
// ajoute un HotspotEditor au dialogue
|
|
HotspotEditor *hotspot_editor = new HotspotEditor();
|
|
hotspot_editor -> setElementWidth(static_cast<uint>(width() / 10));
|
|
hotspot_editor -> setElementHeight(static_cast<uint>(height() / 10));
|
|
hotspot_editor -> setHotspot(hotspot());
|
|
hotspot_editor -> setOldHotspot(hotspot());
|
|
hotspot_editor -> setPartsRect(itemsBoundingRect());
|
|
hotspot_editor -> setPartsRectEnabled(true);
|
|
dialog_layout -> addWidget(hotspot_editor);
|
|
|
|
// ajoute deux boutons au dialogue
|
|
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
|
dialog_layout -> addWidget(dialog_buttons);
|
|
connect(dialog_buttons, SIGNAL(accepted()), &dialog_sh, SLOT(accept()));
|
|
connect(dialog_buttons, SIGNAL(rejected()), &dialog_sh, SLOT(reject()));
|
|
|
|
// lance le dialogue
|
|
if (dialog_sh.exec() != QDialog::Accepted) return;
|
|
QSize new_size(hotspot_editor -> elementSize());
|
|
QSize old_size(width(), height());
|
|
QPoint new_hotspot(hotspot_editor -> hotspot());
|
|
QPoint old_hotspot(_hotspot);
|
|
|
|
if (new_size != old_size || new_hotspot != old_hotspot) {
|
|
undo_stack.push(new ChangeHotspotCommand(this, old_size, new_size, old_hotspot, new_hotspot, hotspot_editor -> offsetParts()));
|
|
}
|
|
}
|
|
|
|
void ElementScene::slot_editOrientations() {
|
|
|
|
// cree un dialogue
|
|
QDialog dialog_ori;
|
|
dialog_ori.setModal(true);
|
|
dialog_ori.setFixedSize(400, 230);
|
|
dialog_ori.setWindowTitle(tr("\311diter les orientations"));
|
|
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog_ori);
|
|
|
|
// ajoute un champ explicatif au dialogue
|
|
QLabel *information_label = new QLabel(tr("L'orientation par d\351faut est l'orientation dans laquelle s'effectue la cr\351ation de l'\351l\351ment."));
|
|
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
|
information_label -> setWordWrap(true);
|
|
dialog_layout -> addWidget(information_label);
|
|
|
|
// ajoute un OrientationSetWidget au dialogue
|
|
OrientationSetWidget *ori_widget = new OrientationSetWidget();
|
|
ori_widget -> setOrientationSet(ori);
|
|
dialog_layout -> addWidget(ori_widget);
|
|
|
|
// ajoute deux boutons au dialogue
|
|
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
|
dialog_layout -> addWidget(dialog_buttons);
|
|
connect(dialog_buttons, SIGNAL(accepted()), &dialog_ori, SLOT(accept()));
|
|
connect(dialog_buttons, SIGNAL(rejected()), &dialog_ori, SLOT(reject()));
|
|
|
|
// lance le dialogue
|
|
if (dialog_ori.exec() == QDialog::Accepted) {
|
|
OrientationSet new_ori = ori_widget -> orientationSet();
|
|
if (new_ori != ori) {
|
|
undoStack().push(new ChangeOrientationsCommand(this, ori, new_ori));
|
|
}
|
|
}
|
|
}
|
|
|
|
void ElementScene::slot_editNames() {
|
|
|
|
// cree un dialogue
|
|
QDialog dialog;
|
|
dialog.setModal(true);
|
|
dialog.setFixedSize(400, 330);
|
|
dialog.setWindowTitle(tr("\311diter les noms"));
|
|
QVBoxLayout *dialog_layout = new QVBoxLayout(&dialog);
|
|
|
|
// ajoute un champ explicatif au dialogue
|
|
QLabel *information_label = new QLabel(tr("Vous pouvez sp\351cifier le nom de l'\351l\351ment dans plusieurs langues."));
|
|
information_label -> setAlignment(Qt::AlignJustify | Qt::AlignVCenter);
|
|
information_label -> setWordWrap(true);
|
|
dialog_layout -> addWidget(information_label);
|
|
|
|
// ajoute un NamesListWidget au dialogue
|
|
NamesListWidget *names_widget = new NamesListWidget();
|
|
names_widget -> setNames(_names);
|
|
dialog_layout -> addWidget(names_widget);
|
|
|
|
// ajoute deux boutons au dialogue
|
|
QDialogButtonBox *dialog_buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
|
dialog_layout -> addWidget(dialog_buttons);
|
|
connect(dialog_buttons, SIGNAL(accepted()), names_widget, SLOT(check()));
|
|
connect(names_widget, SIGNAL(inputChecked()), &dialog, SLOT(accept()));
|
|
connect(dialog_buttons, SIGNAL(rejected()), &dialog, SLOT(reject()));
|
|
|
|
// lance le dialogue
|
|
if (dialog.exec() == QDialog::Accepted) {
|
|
NamesList new_names(names_widget -> names());
|
|
if (new_names != _names) undoStack().push(new ChangeNamesCommand(this, _names, new_names));
|
|
}
|
|
}
|
|
|
|
/**
|
|
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<QGraphicsItem *> ElementScene::zItems(bool include_terminals) const {
|
|
// recupere les elements
|
|
QList<QGraphicsItem *> all_items_list(items());
|
|
|
|
// enleve les bornes
|
|
QList<QGraphicsItem *> terminals;
|
|
foreach(QGraphicsItem *qgi, all_items_list) {
|
|
if (qgraphicsitem_cast<PartTerminal *>(qgi)) {
|
|
all_items_list.removeAt(all_items_list.indexOf(qgi));
|
|
terminals << qgi;
|
|
}
|
|
}
|
|
|
|
// ordonne les parties par leur zValue
|
|
QMultiMap<qreal, QGraphicsItem *> 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);
|
|
}
|