Les classes Conductor et Element heritent desormais de QObject.

Correction du bug #16 : Mauvaise gestion des modifications du texte d'un conducteur



git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@346 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet 2008-07-09 21:14:30 +00:00
parent 9c6f602439
commit f4b828a3cd
12 changed files with 104 additions and 20 deletions

View File

@ -37,6 +37,7 @@ QBrush Conductor::square_brush = QBrush(Qt::darkGreen);
@param scene QGraphicsScene a laquelle appartient le conducteur
*/
Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene *scene) :
QObject(),
QGraphicsPathItem(parent, scene),
terminal1(p1),
terminal2(p2),
@ -86,6 +87,12 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene
text_item -> previous_text = properties_.text;
calculateTextItemPosition();
text_item -> setParentItem(this);
connect(
text_item,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
this,
SLOT(displayedTextChanged())
);
}
/**
@ -1083,6 +1090,25 @@ void Conductor::readProperties() {
text_item -> setVisible(properties_.type == ConductorProperties::Multi);
}
/**
Met a jour les proprietes du conducteur apres modification du champ de texte affiche
*/
void Conductor::displayedTextChanged() {
// verifie que le texte a reellement change
if (text_item -> toPlainText() == properties_.text) return;
// initialise l'objet UndoCommand correspondant
if (Diagram *my_diagram = diagram()) {
ConductorProperties new_properties(properties_);
new_properties.text = text_item -> toPlainText();
ChangeConductorPropertiesCommand *ccpc = new ChangeConductorPropertiesCommand(this);
ccpc -> setOldSettings(properties_);
ccpc -> setNewSettings(new_properties);
my_diagram -> undoStack().push(ccpc);
}
}
/**
@return les conducteurs avec lesquels ce conducteur partage des bornes
communes

View File

@ -29,7 +29,9 @@ typedef QHash<Qt::Corner, ConductorProfile> ConductorProfilesGroup;
/**
Cette classe represente un conducteur. Un conducteur relie deux bornes d'element.
*/
class Conductor : public QGraphicsPathItem {
class Conductor : public QObject, public QGraphicsPathItem {
Q_OBJECT
// constructeurs, destructeur
public:
@ -81,6 +83,9 @@ class Conductor : public QGraphicsPathItem {
ConductorProfilesGroup profiles() const;
void readProperties();
public slots:
void displayedTextChanged();
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);

View File

@ -461,6 +461,17 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
return(true);
}
/**
Gere le fait qu'un texte du schema ait ete modifie
@param text_item Texte modifie
@param old_text Ancien texte
@param new_text Nouveau texte
*/
void Diagram::diagramTextChanged(DiagramTextItem *text_item, const QString &old_text, const QString &new_text) {
if (!text_item) return;
undo_stack.push(new ChangeDiagramTextCommand(text_item, old_text, new_text));
}
/**
Verifie si la selection est passe d'un etat ou elle est vide a un etat ou
elle ne l'est pas, et inversement. Si c'est le cas, le signal

View File

@ -126,6 +126,9 @@ class Diagram : public QGraphicsScene {
QUndoStack &undoStack();
QGIManager &qgiManager();
public slots:
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
private slots:
void slot_checkSelectionEmptinessChange();

View File

@ -81,11 +81,23 @@ AddTextCommand::~AddTextCommand() {
/// Annule l'ajout
void AddTextCommand::undo() {
QObject::disconnect(
textitem,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
diagram,
SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &))
);
diagram -> removeItem(textitem);
}
/// Refait l'ajour
void AddTextCommand::redo() {
QObject::connect(
textitem,
SIGNAL(diagramTextChanged(DiagramTextItem *, const QString &, const QString &)),
diagram,
SLOT(diagramTextChanged(DiagramTextItem *, const QString &, const QString &))
);
diagram -> addItem(textitem);
textitem -> setPos(position);
}

View File

@ -121,10 +121,13 @@ QString DiagramContent::sentence(int filter) const {
*/
QDebug &operator<<(QDebug d, DiagramContent &c) {
d << "DiagramContent {" << "\n";
/*
FIXME Le double-heritage QObject / QGraphicsItem a casse cet operateur
d << " elements :" << c.elements << "\n";
d << " conductorsToUpdate :" << c.conductorsToUpdate.keys() << "\n";
d << " conductorsToMove :" << c.conductorsToMove << "\n";
d << " otherConductors :" << c.otherConductors << "\n";
d << "}";
*/
return(d.space());
}

View File

@ -63,13 +63,11 @@ Diagram *DiagramTextItem::diagram() const {
*/
void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
QGraphicsTextItem::focusOutEvent(e);
// si le texte a ete modifie
// signale la modification du texte si besoin
if (toPlainText() != previous_text) {
if (Diagram *dia = diagram()) {
dia -> undoStack().push(new ChangeDiagramTextCommand(this, previous_text, toPlainText()));
emit(diagramTextChanged(this, previous_text, toPlainText()));
previous_text = toPlainText();
}
}
// deselectionne le texte
QTextCursor cursor = textCursor();

View File

@ -59,6 +59,8 @@ class DiagramTextItem : public QGraphicsTextItem {
signals:
/// signal emis lorsque le champ de texte perd le focus
void lostFocus();
/// signal emis lorsque le champ de texte a ete modifie
void diagramTextChanged(DiagramTextItem *, const QString &, const QString &);
// slots
public slots:

View File

@ -259,20 +259,17 @@ void DiagramView::pasteHere() {
}
/**
gere les clics et plus particulierement le clic du milieu (= coller pour X11)
Gere les clics et plus particulierement :
* le clic du milieu (= coller pour X11)
* le clic pour ajouter un champ de texte independant
*/
void DiagramView::mousePressEvent(QMouseEvent *e) {
if (e -> buttons() == Qt::MidButton) {
paste(mapToScene(e -> pos()), QClipboard::Selection);
} else {
if (is_adding_text && e -> buttons() == Qt::LeftButton) {
DiagramTextItem *dti = new DiagramTextItem();
dti -> setPlainText("_");
dti -> previous_text = "_";
scene -> undoStack().push(new AddTextCommand(scene, dti, mapToScene(e -> pos())));
adjustSceneRect();
addDiagramTextAtPos(mapToScene(e -> pos()));
is_adding_text = false;
emit(textAdded(false));
}
QGraphicsView::mousePressEvent(e);
}
@ -859,6 +856,28 @@ void DiagramView::addText() {
is_adding_text = true;
}
/**
Cree un nouveau champ de texte et le place a la position pos
en gerant l'annulation ; enfin, le signal textAdded est emis.
@param pos Position du champ de texte ajoute
@return le champ de texte ajoute
*/
DiagramTextItem *DiagramView::addDiagramTextAtPos(const QPointF &pos) {
// cree un nouveau champ de texte
DiagramTextItem *dti = new DiagramTextItem();
dti -> setPlainText("_");
dti -> previous_text = "_";
// le place a la position pos en gerant l'annulation
scene -> undoStack().push(new AddTextCommand(scene, dti, pos));
adjustSceneRect();
// emet le signal textAdded
emit(textAdded(false));
return(dti);
}
/**
Gere le menu contextuel
@param e Evenement decrivant la demande de menu contextuel

View File

@ -19,6 +19,7 @@
#define DIAGRAMVIEW_H
#include <QtGui>
class Diagram;
class DiagramTextItem;
class QETDiagramEditor;
class Conductor;
/**
@ -65,6 +66,7 @@ class DiagramView : public QGraphicsView {
QETDiagramEditor *diagramEditor() const;
bool hasSelectedItems();
void addText();
DiagramTextItem *addDiagramTextAtPos(const QPointF &);
protected:
virtual void mouseDoubleClickEvent(QMouseEvent *);

View File

@ -27,6 +27,7 @@
Constructeur pour un element sans scene ni parent
*/
Element::Element(QGraphicsItem *parent, Diagram *scene) :
QObject(),
QGraphicsItem(parent, scene),
internal_connections(false)
{
@ -155,7 +156,7 @@ bool Element::setOrientation(QET::Orientation o) {
rotate(rotation_value);
ori.setCurrent(o);
update();
foreach(QGraphicsItem *qgi, children()) {
foreach(QGraphicsItem *qgi, childItems()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) p -> updateConductor();
else if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
// applique une rotation contraire si besoin
@ -354,7 +355,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
QHash<int, Terminal *> priv_id_adr;
int terminals_non_trouvees = 0;
foreach(QGraphicsItem *qgi, children()) {
foreach(QGraphicsItem *qgi, childItems()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
bool terminal_trouvee = false;
foreach(QDomElement qde, liste_terminals) {
@ -386,7 +387,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
// importe les valeurs des champs de texte
QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
foreach(QGraphicsItem *qgi, children()) {
foreach(QGraphicsItem *qgi, childItems()) {
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
foreach(QDomElement input, inputs) eti -> fromXml(input);
}
@ -438,7 +439,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
// enregistrement des bornes de l'appareil
QDomElement terminals = document.createElement("terminals");
// pour chaque enfant de l'element
foreach(QGraphicsItem *child, children()) {
foreach(QGraphicsItem *child, childItems()) {
// si cet enfant est une borne
if (Terminal *t = qgraphicsitem_cast<Terminal *>(child)) {
// alors on enregistre la borne
@ -453,7 +454,7 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
// enregistrement des champ de texte de l'appareil
QDomElement inputs = document.createElement("inputs");
// pour chaque enfant de l'element
foreach(QGraphicsItem *child, children()) {
foreach(QGraphicsItem *child, childItems()) {
// si cet enfant est un champ de texte
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(child)) {
// alors on enregistre le champ de texte

View File

@ -24,7 +24,9 @@ class Diagram;
/**
Cette classe abstraite represente un element electrique.
*/
class Element : public QGraphicsItem {
class Element : public QObject, public QGraphicsItem {
Q_OBJECT
// constructeurs, destructeur
public: