mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2025-12-19 06:20:53 +01:00
Debut du support des annulations dans l'editeur d'elements
git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@102 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
@@ -143,6 +143,14 @@ void CustomElementEditor::setupMenus() {
|
||||
file_menu -> addSeparator();
|
||||
file_menu -> addAction(quit);
|
||||
|
||||
QAction *undo = ce_scene -> undoStack().createUndoAction(this, tr("Annuler"));
|
||||
QAction *redo = ce_scene -> undoStack().createRedoAction(this, tr("Refaire"));
|
||||
undo -> setShortcuts(QKeySequence::Undo);
|
||||
redo -> setShortcuts(QKeySequence::Redo);
|
||||
|
||||
edit_menu -> addAction(undo);
|
||||
edit_menu -> addAction(redo);
|
||||
edit_menu -> addSeparator();
|
||||
edit_menu -> addAction(selectall);
|
||||
edit_menu -> addAction(deselectall);
|
||||
edit_menu -> addAction(inv_select);
|
||||
@@ -181,7 +189,7 @@ void CustomElementEditor::setupInterface() {
|
||||
// widget par defaut dans le QDockWidget
|
||||
default_informations = new QLabel();
|
||||
|
||||
// panel sur le cote
|
||||
// panel sur le cote pour editer les parties
|
||||
tools_dock = new QDockWidget(tr("Informations"), this);
|
||||
tools_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
tools_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
@@ -190,6 +198,15 @@ void CustomElementEditor::setupInterface() {
|
||||
QWidget *info_widget = new QWidget();
|
||||
info_widget -> setLayout(new QVBoxLayout(info_widget));
|
||||
tools_dock -> setWidget(info_widget);
|
||||
|
||||
// panel sur le cote pour les annulations
|
||||
undo_dock = new QDockWidget(tr("Annulations"), this);
|
||||
undo_dock -> setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||||
undo_dock -> setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||
undo_dock -> setMinimumWidth(285);
|
||||
addDockWidget(Qt::RightDockWidgetArea, undo_dock);
|
||||
undo_dock -> setWidget(new QUndoView(&(ce_scene -> undoStack()), this));
|
||||
|
||||
slot_updateInformations();
|
||||
|
||||
// barre d'etat
|
||||
|
||||
@@ -25,6 +25,8 @@ class CustomElementEditor : public QMainWindow {
|
||||
EditorScene *ce_scene;
|
||||
/// container pour les widgets d'edition des parties
|
||||
QDockWidget *tools_dock;
|
||||
/// container pour la liste des annulations
|
||||
QDockWidget *undo_dock;
|
||||
/// actions du menu fichier
|
||||
QAction *new_element, *open, *save, *save_as, *quit;
|
||||
/// actions du menu edition
|
||||
|
||||
125
editor/editorcommands.cpp
Normal file
125
editor/editorcommands.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "editorcommands.h"
|
||||
|
||||
/*** DeletePartsCommand ***/
|
||||
/**
|
||||
Constructeur
|
||||
@param scene EditorScene concernee
|
||||
@param parts Liste des parties supprimees
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
DeletePartsCommand::DeletePartsCommand(
|
||||
EditorScene *scene,
|
||||
const QList<QGraphicsItem *> parts,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("suppression"), parent),
|
||||
deleted_parts(parts),
|
||||
editor_scene(scene)
|
||||
{
|
||||
foreach(QGraphicsItem *qgi, deleted_parts) {
|
||||
editor_scene -> qgiManager().manage(qgi);
|
||||
}
|
||||
}
|
||||
|
||||
/// Destructeur : detruit egalement les parties supprimees
|
||||
DeletePartsCommand::~DeletePartsCommand() {
|
||||
foreach(QGraphicsItem *qgi, deleted_parts) {
|
||||
editor_scene -> qgiManager().release(qgi);
|
||||
}
|
||||
}
|
||||
|
||||
/// Restaure les parties supprimees
|
||||
void DeletePartsCommand::undo() {
|
||||
foreach(QGraphicsItem *qgi, deleted_parts) {
|
||||
editor_scene -> addItem(qgi);
|
||||
}
|
||||
}
|
||||
|
||||
/// Supprime les parties
|
||||
void DeletePartsCommand::redo() {
|
||||
foreach(QGraphicsItem *qgi, deleted_parts) {
|
||||
editor_scene -> removeItem(qgi);
|
||||
}
|
||||
}
|
||||
|
||||
/*** MovePartsCommand ***/
|
||||
/**
|
||||
Constructeur
|
||||
@param m Mouvement sous forme de QPointF
|
||||
@param scene EditorScene concernee
|
||||
@param parts Liste des parties deplacees
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
MovePartsCommand::MovePartsCommand(
|
||||
const QPointF &m,
|
||||
EditorScene *scene,
|
||||
const QList<QGraphicsItem *> parts,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("d\351placement"), parent),
|
||||
movement(m),
|
||||
first_redo(true)
|
||||
{
|
||||
moved_parts = parts;
|
||||
editor_scene = scene;
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
MovePartsCommand::~MovePartsCommand() {
|
||||
}
|
||||
|
||||
/// Annule le deplacement
|
||||
void MovePartsCommand::undo() {
|
||||
foreach(QGraphicsItem *qgi, moved_parts) qgi -> moveBy(-movement.x(), -movement.y());
|
||||
}
|
||||
|
||||
/// Refait le deplacement
|
||||
void MovePartsCommand::redo() {
|
||||
// le premier appel a redo, lors de la construction de l'objet, ne doit pas se faire
|
||||
if (first_redo) {
|
||||
first_redo = false;
|
||||
return;
|
||||
}
|
||||
foreach(QGraphicsItem *qgi, moved_parts) qgi -> moveBy(movement.x(), movement.y());
|
||||
}
|
||||
|
||||
/*** AddPartCommand ***/
|
||||
/**
|
||||
Constructeur
|
||||
@param name Nom de la partie ajoutee
|
||||
@param parts Liste des parties deplacees
|
||||
@param parent QUndoCommand parent
|
||||
*/
|
||||
AddPartCommand::AddPartCommand(
|
||||
const QString &name,
|
||||
EditorScene *scene,
|
||||
QGraphicsItem *p,
|
||||
QUndoCommand *parent
|
||||
) :
|
||||
QUndoCommand(QObject::tr("ajout ") + name, parent),
|
||||
part(p),
|
||||
editor_scene(scene),
|
||||
first_redo(true)
|
||||
{
|
||||
editor_scene -> qgiManager().manage(part);
|
||||
}
|
||||
|
||||
/// Destructeur
|
||||
AddPartCommand::~AddPartCommand() {
|
||||
editor_scene -> qgiManager().release(part);
|
||||
}
|
||||
|
||||
/// Annule le deplacement
|
||||
void AddPartCommand::undo() {
|
||||
editor_scene -> removeItem(part);
|
||||
}
|
||||
|
||||
/// Refait le deplacement
|
||||
void AddPartCommand::redo() {
|
||||
// le premier appel a redo, lors de la construction de l'objet, ne doit pas se faire
|
||||
if (first_redo) {
|
||||
first_redo = false;
|
||||
return;
|
||||
}
|
||||
editor_scene -> addItem(part);
|
||||
}
|
||||
85
editor/editorcommands.h
Normal file
85
editor/editorcommands.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef EDITOR_COMMANDS_H
|
||||
#define EDITOR_COMMANDS_H
|
||||
#include "customelementpart.h"
|
||||
#include "editorscene.h"
|
||||
#include "qgimanager.h"
|
||||
#include <QtGui>
|
||||
/**
|
||||
Cette classe represente l'action de supprimer une ou plusieurs
|
||||
parties lors de l'edition d'un element
|
||||
*/
|
||||
class DeletePartsCommand : public QUndoCommand {
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
DeletePartsCommand(EditorScene *, const QList<QGraphicsItem *>, QUndoCommand * = 0);
|
||||
virtual ~DeletePartsCommand();
|
||||
private:
|
||||
DeletePartsCommand(const DeletePartsCommand &);
|
||||
|
||||
// methodes
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
// attributs
|
||||
private:
|
||||
/// Liste des parties supprimees
|
||||
QList<QGraphicsItem *> deleted_parts;
|
||||
/// scene sur laquelle se produisent les actions
|
||||
EditorScene *editor_scene;
|
||||
};
|
||||
|
||||
/**
|
||||
Cette classe represente l'action de deplacer une ou plusieurs
|
||||
parties lors de l'edition d'un element
|
||||
*/
|
||||
class MovePartsCommand : public QUndoCommand {
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
MovePartsCommand(const QPointF &, EditorScene *, const QList<QGraphicsItem *>, QUndoCommand * = 0);
|
||||
virtual ~MovePartsCommand();
|
||||
private:
|
||||
MovePartsCommand(const MovePartsCommand &);
|
||||
|
||||
// methodes
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
// attributs
|
||||
private:
|
||||
/// Liste des parties supprimees
|
||||
QList<QGraphicsItem *> moved_parts;
|
||||
/// scene sur laquelle se produisent les actions
|
||||
EditorScene *editor_scene;
|
||||
/// translation appliquee
|
||||
QPointF movement;
|
||||
/// booleen pour eviter d'appeler redo() lors de la construction de l'objet
|
||||
bool first_redo;
|
||||
};
|
||||
|
||||
/**
|
||||
Cette classe represente l'action de deplacer une ou plusieurs
|
||||
parties lors de l'edition d'un element
|
||||
*/
|
||||
class AddPartCommand : public QUndoCommand {
|
||||
// constructeurs, destructeur
|
||||
public:
|
||||
AddPartCommand(const QString &, EditorScene *, QGraphicsItem *, QUndoCommand * = 0);
|
||||
virtual ~AddPartCommand();
|
||||
private:
|
||||
AddPartCommand(const AddPartCommand &);
|
||||
|
||||
// methodes
|
||||
virtual void undo();
|
||||
virtual void redo();
|
||||
|
||||
// attributs
|
||||
private:
|
||||
/// Liste des parties supprimees
|
||||
QGraphicsItem *part;
|
||||
/// scene sur laquelle se produisent les actions
|
||||
EditorScene *editor_scene;
|
||||
/// booleen pour eviter d'appeler redo() lors de la construction de l'objet
|
||||
bool first_redo;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "parttextfield.h"
|
||||
#include "partarc.h"
|
||||
#include "hotspoteditor.h"
|
||||
#include "editorcommands.h"
|
||||
#define GRILLE_X 10
|
||||
#define GRILLE_Y 10
|
||||
|
||||
@@ -16,7 +17,8 @@ EditorScene::EditorScene(QObject *parent) :
|
||||
QGraphicsScene(parent),
|
||||
_width(3),
|
||||
_height(7),
|
||||
_hotspot(15, 35)
|
||||
_hotspot(15, 35),
|
||||
qgi_manager(this)
|
||||
{
|
||||
current_polygon = NULL;
|
||||
connect(this, SIGNAL(changed(const QList<QRectF> &)), this, SLOT(slot_checkSelectionChanged()));
|
||||
@@ -161,38 +163,51 @@ void EditorScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
|
||||
if (behavior != Polygon && current_polygon != NULL) current_polygon = NULL;
|
||||
if (e -> button() & Qt::LeftButton) {
|
||||
switch(behavior) {
|
||||
case Normal:
|
||||
QGraphicsScene::mouseReleaseEvent(e);
|
||||
break;
|
||||
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(0, this);
|
||||
terminal -> setPos(e -> scenePos());
|
||||
undo_stack.push(new AddPartCommand(tr("borne"), this, terminal));
|
||||
break;
|
||||
case Text:
|
||||
text = new PartText(0, this);
|
||||
text -> setPos(e -> scenePos());
|
||||
undo_stack.push(new AddPartCommand(tr("texte"), this, text));
|
||||
break;
|
||||
case TextField:
|
||||
textfield = new PartTextField(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 = e -> scenePos() - e -> buttonDownScenePos(Qt::LeftButton);
|
||||
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);
|
||||
@@ -367,6 +382,14 @@ void EditorScene::fromXml(const QDomDocument &xml_document) {
|
||||
}
|
||||
}
|
||||
|
||||
QUndoStack &EditorScene::undoStack() {
|
||||
return(undo_stack);
|
||||
}
|
||||
|
||||
QGIManager &EditorScene::qgiManager() {
|
||||
return(qgi_manager);
|
||||
}
|
||||
|
||||
void EditorScene::slot_checkSelectionChanged() {
|
||||
static QList<QGraphicsItem *> cache_selecteditems = QList<QGraphicsItem *>();
|
||||
QList<QGraphicsItem *> selecteditems = selectedItems();
|
||||
@@ -392,10 +415,7 @@ void EditorScene::slot_delete() {
|
||||
if (selected_items.isEmpty()) return;
|
||||
|
||||
// efface tout ce qui est selectionne
|
||||
foreach(QGraphicsItem *qgi, selected_items) {
|
||||
removeItem(qgi);
|
||||
delete qgi;
|
||||
}
|
||||
undo_stack.push(new DeletePartsCommand(this, selected_items));
|
||||
}
|
||||
|
||||
void EditorScene::slot_editSizeHotSpot() {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <QtXml>
|
||||
#include "nameslistwidget.h"
|
||||
#include "orientationsetwidget.h"
|
||||
#include "qgimanager.h"
|
||||
class PartLine;
|
||||
class PartEllipse;
|
||||
class PartCircle;
|
||||
@@ -35,6 +36,10 @@ class EditorScene : public QGraphicsScene {
|
||||
NamesList _names;
|
||||
/// Liste des orientations de l'element
|
||||
OrientationSet ori;
|
||||
/// Pile des actions annulables
|
||||
QUndoStack undo_stack;
|
||||
/// Gestionnaire de QGraphicsItem
|
||||
QGIManager qgi_manager;
|
||||
|
||||
/// Variables relatives a la gestion du dessin des parties sur la scene
|
||||
Behavior behavior;
|
||||
@@ -58,6 +63,8 @@ class EditorScene : public QGraphicsScene {
|
||||
void setOrientations(const OrientationSet &);
|
||||
virtual const QDomDocument toXml() const;
|
||||
virtual void fromXml(const QDomDocument &);
|
||||
QUndoStack &undoStack();
|
||||
QGIManager &qgiManager();
|
||||
|
||||
protected:
|
||||
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
|
||||
|
||||
@@ -54,7 +54,9 @@ HEADERS += aboutqet.h \
|
||||
editor/arceditor.h \
|
||||
editor/parttextfield.h \
|
||||
editor/textfieldeditor.h \
|
||||
hotspoteditor.h
|
||||
hotspoteditor.h \
|
||||
editor/editorcommands.h \
|
||||
qgimanager.h
|
||||
SOURCES += aboutqet.cpp \
|
||||
borderinset.cpp \
|
||||
conducer.cpp \
|
||||
@@ -102,7 +104,9 @@ SOURCES += aboutqet.cpp \
|
||||
editor/arceditor.cpp \
|
||||
editor/parttextfield.cpp \
|
||||
editor/textfieldeditor.cpp \
|
||||
hotspoteditor.cpp
|
||||
hotspoteditor.cpp \
|
||||
editor/editorcommands.cpp \
|
||||
qgimanager.cpp
|
||||
RESOURCES += qelectrotech.qrc
|
||||
TRANSLATIONS += lang/qet_en.ts lang/qt_fr.ts
|
||||
QT += xml
|
||||
|
||||
54
qgimanager.cpp
Normal file
54
qgimanager.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "qgimanager.h"
|
||||
|
||||
/**
|
||||
Constructeur
|
||||
@param sc QGraphicsScene a utiliser pour gerer au mieux les QGraphicsItem
|
||||
*/
|
||||
QGIManager::QGIManager(QGraphicsScene *sc) :
|
||||
scene(sc),
|
||||
destroy_qgi_on_delete(true)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
Destructeur
|
||||
Lors de sa destruction, le QGI Manager detruit les QGraphicsItem restants
|
||||
si ceux-ci n'appartiennent pas a la scene ; ce comportement peut etre
|
||||
change avec la methode setDestroyQGIOnDelete
|
||||
@see setDestroyQGIOnDelete
|
||||
*/
|
||||
QGIManager::~QGIManager(){
|
||||
if (!destroy_qgi_on_delete) return;
|
||||
foreach(QGraphicsItem *qgi, qgi_manager.keys()) {
|
||||
if (!scene -> items().contains(qgi)) delete qgi;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Demande au QGIManager de gerer un QGI
|
||||
@param qgi QGraphicsItem a gerer
|
||||
*/
|
||||
void QGIManager::manage(QGraphicsItem *qgi) {
|
||||
if (qgi_manager.contains(qgi)) ++ qgi_manager[qgi];
|
||||
else qgi_manager.insert(qgi, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
Indique au QGIManager qu'une reference vers un QGI a ete detruite
|
||||
S'il n'y a plus de references vers ce QGI et que celui-ci n'est pas present
|
||||
sur la scene de ce QGIManager, alors il sera detruit.
|
||||
@param qgi QGraphicsItem a ne plus gerer
|
||||
*/
|
||||
void QGIManager::release(QGraphicsItem *qgi) {
|
||||
if (!qgi_manager.contains(qgi)) return;
|
||||
-- qgi_manager[qgi];
|
||||
if (!qgi_manager[qgi] && !(scene -> items().contains(qgi))) delete qgi;
|
||||
}
|
||||
|
||||
/**
|
||||
Indique au QGIManager de detruire les QGraphicsItem restants lors de sa
|
||||
destruction si ceux-ci n'appartiennent pas a la scene
|
||||
*/
|
||||
void QGIManager::setDestroyQGIOnDelete(bool b) {
|
||||
destroy_qgi_on_delete = b;
|
||||
}
|
||||
26
qgimanager.h
Normal file
26
qgimanager.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef QGI_MANAGER_H
|
||||
#define QGI_MANAGER_H
|
||||
#include <QtCore>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsItem>
|
||||
class QGIManager {
|
||||
// constructeurs, destructeurs
|
||||
public:
|
||||
QGIManager(QGraphicsScene *);
|
||||
virtual ~QGIManager();
|
||||
private:
|
||||
QGIManager(const QGIManager &);
|
||||
|
||||
// attributs
|
||||
private:
|
||||
QGraphicsScene *scene;
|
||||
QHash<QGraphicsItem *, int> qgi_manager;
|
||||
bool destroy_qgi_on_delete;
|
||||
|
||||
//methodes
|
||||
public:
|
||||
void manage(QGraphicsItem *);
|
||||
void release(QGraphicsItem *);
|
||||
void setDestroyQGIOnDelete(bool);
|
||||
};
|
||||
#endif
|
||||
Reference in New Issue
Block a user