Ameliorations internes : les classes Conducer et Element ont desormais des methodes fromXml() et toXml()

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@67 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet 2007-02-24 18:37:07 +00:00
parent d9176b5cbf
commit cbc12b8aef
9 changed files with 175 additions and 162 deletions

View File

@ -739,10 +739,14 @@ bool Conducer::fromXml(QDomElement &e) {
return(true); return(true);
} }
void Conducer::toXml(QDomDocument &d, QDomElement &e) { QDomElement Conducer::toXml(QDomDocument &d, QHash<Terminal *, int> &table_adr_id) const {
QDomElement e = d.createElement("conducteur");
e.setAttribute("borne1", table_adr_id.value(terminal1));
e.setAttribute("borne2", table_adr_id.value(terminal2));
// on n'exporte les segments du conducteur que si ceux-ci ont // on n'exporte les segments du conducteur que si ceux-ci ont
// ete modifies par l'utilisateur // ete modifies par l'utilisateur
if (!modified_path) return; if (!modified_path) return(e);
// parcours et export des segments // parcours et export des segments
ConducerSegment *segment = segments; ConducerSegment *segment = segments;
@ -758,4 +762,5 @@ void Conducer::toXml(QDomDocument &d, QDomElement &e) {
current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical"); current_segment.setAttribute("orientation", segment -> isHorizontal() ? "horizontal" : "vertical");
current_segment.setAttribute("length", segment -> length()); current_segment.setAttribute("length", segment -> length());
e.appendChild(current_segment); e.appendChild(current_segment);
return(e);
} }

View File

@ -23,7 +23,7 @@
virtual QPainterPath shape() const; virtual QPainterPath shape() const;
static bool valideXml(QDomElement &); static bool valideXml(QDomElement &);
bool fromXml(QDomElement &); bool fromXml(QDomElement &);
void toXml(QDomDocument &, QDomElement &); QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
///Premiere borne a laquelle le fil est rattache ///Premiere borne a laquelle le fil est rattache
Terminal *terminal1; Terminal *terminal1;

View File

@ -7,11 +7,11 @@
CustomElement(QString &, QGraphicsItem * = 0, Diagram * = 0, int * = NULL); CustomElement(QString &, QGraphicsItem * = 0, Diagram * = 0, int * = NULL);
virtual int nbTerminals() const; virtual int nbTerminals() const;
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *); virtual void paint(QPainter *, const QStyleOptionGraphicsItem *);
inline QString typeId() { return(nomfichier); } inline QString typeId() const { return(nomfichier); }
inline QString fichier() { return(nomfichier); } inline QString fichier() const { return(nomfichier); }
inline bool isNull() { return(elmt_etat != 0); } inline bool isNull() const { return(elmt_etat != 0); }
inline int etat() { return(elmt_etat); } inline int etat() const { return(elmt_etat); }
inline QString nom() { return(priv_nom); } inline QString nom() const { return(priv_nom); }
private: private:
int elmt_etat; // contient le code d'erreur si l'instanciation a echoue ou 0 si l'instanciation s'est bien passe int elmt_etat; // contient le code d'erreur si l'instanciation a echoue ou 0 si l'instanciation s'est bien passe

View File

@ -140,7 +140,7 @@ QSize Diagram::imageSize() const {
/** /**
Exporte tout ou partie du schema Exporte tout ou partie du schema
@param schema Booleen (a vrai par defaut) indiquant si le XML genere doit @param diagram Booleen (a vrai par defaut) indiquant si le XML genere doit
representer tout le schema ou seulement les elements selectionnes representer tout le schema ou seulement les elements selectionnes
@return Un Document XML (QDomDocument) @return Un Document XML (QDomDocument)
*/ */
@ -168,7 +168,6 @@ QDomDocument Diagram::toXml(bool diagram) {
QList<Element *> liste_elements; QList<Element *> liste_elements;
QList<Conducer *> liste_conducers; QList<Conducer *> liste_conducers;
// Determine les elements a « XMLiser » // Determine les elements a « XMLiser »
foreach(QGraphicsItem *qgi, items()) { foreach(QGraphicsItem *qgi, items()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) { if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
@ -182,59 +181,22 @@ QDomDocument Diagram::toXml(bool diagram) {
} }
} }
// enregistrement des elements
if (liste_elements.isEmpty()) return(document);
int id_terminal = 0;
// table de correspondance entre les adresses des bornes et leurs ids // table de correspondance entre les adresses des bornes et leurs ids
QHash<Terminal *, int> table_adr_id; QHash<Terminal *, int> table_adr_id;
// enregistrement des elements
if (liste_elements.isEmpty()) return(document);
QDomElement elements = document.createElement("elements"); QDomElement elements = document.createElement("elements");
QDir dossier_elmts_persos = QDir(QETApp::customElementsDir());
foreach(Element *elmt, liste_elements) { foreach(Element *elmt, liste_elements) {
QDomElement element = document.createElement("element"); elements.appendChild(elmt -> toXml(document, table_adr_id));
// type
QString chemin_elmt = elmt -> typeId();
QString type_elmt = QETApp::symbolicPath(chemin_elmt);
element.setAttribute("type", type_elmt);
// position, selection et orientation
element.setAttribute("x", elmt -> pos().x());
element.setAttribute("y", elmt -> pos().y());
if (elmt -> isSelected()) element.setAttribute("selected", "selected");
element.setAttribute("sens", QString("%1").arg(elmt -> orientation()));
// enregistrements des bornes de chaque appareil
QDomElement terminals = document.createElement("bornes");
// pour chaque enfant de l'element
foreach(QGraphicsItem *child, elmt -> children()) {
// si cet enfant est une borne
if (Terminal *p = qgraphicsitem_cast<Terminal *>(child)) {
// alors on enregistre la borne
QDomElement terminal = p -> toXml(document);
terminal.setAttribute("id", id_terminal);
table_adr_id.insert(p, id_terminal ++);
terminals.appendChild(terminal);
}
}
element.appendChild(terminals);
/**
@todo appeler une methode virtuelle de la classe Element qui permettra
aux developpeurs d'elements de personnaliser l'enregistrement des elements
*/
elements.appendChild(element);
} }
racine.appendChild(elements); racine.appendChild(elements);
// enregistrement des conducteurs // enregistrement des conducteurs
if (liste_conducers.isEmpty()) return(document); if (liste_conducers.isEmpty()) return(document);
QDomElement conducers = document.createElement("conducteurs"); QDomElement conducers = document.createElement("conducteurs");
foreach(Conducer *f, liste_conducers) { foreach(Conducer *cond, liste_conducers) {
QDomElement conducer = document.createElement("conducteur"); conducers.appendChild(cond -> toXml(document, table_adr_id));
conducer.setAttribute("borne1", table_adr_id.value(f -> terminal1));
conducer.setAttribute("borne2", table_adr_id.value(f -> terminal2));
f -> toXml(document, conducer);
conducers.appendChild(conducer);
} }
racine.appendChild(conducers); racine.appendChild(conducers);
@ -272,7 +234,6 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
// chargement de tous les Elements du fichier XML // chargement de tous les Elements du fichier XML
QList<Element *> elements_ajoutes; QList<Element *> elements_ajoutes;
//uint nb_elements = 0;
QHash< int, Terminal *> table_adr_id; QHash< int, Terminal *> table_adr_id;
QHash< int, Terminal *> &ref_table_adr_id = table_adr_id; QHash< int, Terminal *> &ref_table_adr_id = table_adr_id;
for (QDomNode node = racine.firstChild() ; !node.isNull() ; node = node.nextSibling()) { for (QDomNode node = racine.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
@ -284,9 +245,27 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
// on s'interesse a l'element XML "element" (elements eux-memes) // on s'interesse a l'element XML "element" (elements eux-memes)
QDomElement e = n.toElement(); QDomElement e = n.toElement();
if (e.isNull() || !Element::valideXml(e)) continue; if (e.isNull() || !Element::valideXml(e)) continue;
Element *element_ajoute;
if ((element_ajoute = elementFromXml(e, ref_table_adr_id)) != NULL) elements_ajoutes << element_ajoute; // cree un element dont le type correspond à l'id type
else qDebug("Le chargement d'un element a echoue"); QString type_id = e.attribute("type");
QString chemin_fichier = QETApp::realPath(type_id);
CustomElement *nvel_elmt = new CustomElement(chemin_fichier);
if (nvel_elmt -> isNull()) {
QString debug_message = QString("Le chargement de la description de l'element %1 a echoue avec le code d'erreur %2").arg(chemin_fichier).arg(nvel_elmt -> etat());
delete nvel_elmt;
qDebug(debug_message.toLatin1().data());
continue;
}
// charge les caracteristiques de l'element
if (nvel_elmt -> fromXml(e, ref_table_adr_id)) {
// ajout de l'element au schema et a la liste des elements ajoutes
addItem(nvel_elmt);
elements_ajoutes << nvel_elmt;
} else {
delete nvel_elmt;
qDebug("Le chargement des parametres d'un element a echoue");
}
} }
} }
@ -350,38 +329,6 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
return(true); return(true);
} }
/**
Ajoute au schema l'Element correspondant au QDomElement passe en parametre
@param e QDomElement a analyser
@param table_id_adr Table de correspondance entre les entiers et les bornes
@return true si l'ajout a parfaitement reussi, false sinon
*/
Element *Diagram::elementFromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
// cree un element dont le type correspond à l'id type
QString type = e.attribute("type");
QString chemin_fichier = QETApp::realPath(type);
int etat;
Element *nvel_elmt = new CustomElement(chemin_fichier, 0, 0, &etat);
if (etat != 0) return(false);
// charge les caracteristiques de l'element
bool retour = nvel_elmt -> fromXml(e, table_id_adr);
if (!retour) {
delete nvel_elmt;
} else {
// ajout de l'element au schema
addItem(nvel_elmt);
nvel_elmt -> setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
nvel_elmt -> setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
bool conv_ok;
int read_ori = e.attribute("sens").toInt(&conv_ok);
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = nvel_elmt -> defaultOrientation();
nvel_elmt -> setOrientation((Terminal::Orientation)read_ori);
nvel_elmt -> setSelected(e.attribute("selected") == "selected");
}
return(retour ? nvel_elmt : NULL);
}
/** /**
Verifie si la liste des elements selectionnes a change. Si oui, le signal Verifie si la liste des elements selectionnes a change. Si oui, le signal
selectionChanged() est emis. selectionChanged() est emis.

View File

@ -58,8 +58,6 @@
bool draw_grid; bool draw_grid;
bool use_border; bool use_border;
Element *elementFromXml(QDomElement &, QHash<int, Terminal *> &);
private slots: private slots:
void slot_checkSelectionChange(); void slot_checkSelectionChange();

View File

@ -279,3 +279,130 @@ bool Element::valideXml(QDomElement &e) {
if (!conv_ok) return(false); if (!conv_ok) return(false);
return(true); return(true);
} }
/**
Methode d'import XML. Cette methode est appelee lors de l'import de contenu
XML (coller, import, ouverture de fichier...) afin que l'element puisse
gerer lui-meme l'importation de ses bornes. Ici, comme cette classe est
caracterisee par un nombre fixe de bornes, l'implementation exige de
retrouver exactement ses bornes dans le fichier XML.
@param e L'element XML a analyser.
@param table_id_adr Reference vers la table de correspondance entre les IDs
du fichier XML et les adresses en memoire. Si l'import reussit, il faut y
ajouter les bons couples (id, adresse).
@return true si l'import a reussi, false sinon
*/
bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
/*
les bornes vont maintenant etre recensees pour associer leurs id à leur adresse reelle
ce recensement servira lors de la mise en place des fils
*/
QList<QDomElement> liste_terminals;
// parcours des enfants de l'element
for (QDomNode enfant = e.firstChild() ; !enfant.isNull() ; enfant = enfant.nextSibling()) {
// on s'interesse a l'element XML "bornes"
QDomElement terminals = enfant.toElement();
if (terminals.isNull() || terminals.tagName() != "bornes") continue;
// parcours des enfants de l'element XML "bornes"
for (QDomNode node_terminal = terminals.firstChild() ; !node_terminal.isNull() ; node_terminal = node_terminal.nextSibling()) {
// on s'interesse a l'element XML "borne"
QDomElement terminal = node_terminal.toElement();
if (!terminal.isNull() && Terminal::valideXml(terminal)) liste_terminals.append(terminal);
}
}
QHash<int, Terminal *> priv_id_adr;
int terminals_non_trouvees = 0;
foreach(QGraphicsItem *qgi, children()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
bool terminal_trouvee = false;
foreach(QDomElement qde, liste_terminals) {
if (p -> fromXml(qde)) {
priv_id_adr.insert(qde.attribute("id").toInt(), p);
terminal_trouvee = true;
break;
}
}
if (!terminal_trouvee) ++ terminals_non_trouvees;
}
}
if (terminals_non_trouvees > 0) {
return(false);
} else {
// verifie que les associations id / adr n'entrent pas en conflit avec table_id_adr
foreach(int id_trouve, priv_id_adr.keys()) {
if (table_id_adr.contains(id_trouve)) {
// cet element possede un id qui est deja reference (= conflit)
return(false);
}
}
// copie des associations id / adr
foreach(int id_trouve, priv_id_adr.keys()) {
table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve));
}
}
// position, selection et orientation
setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
bool conv_ok;
int read_ori = e.attribute("sens").toInt(&conv_ok);
if (!conv_ok || read_ori < 0 || read_ori > 3) read_ori = defaultOrientation();
setOrientation((Terminal::Orientation)read_ori);
setSelected(e.attribute("selected") == "selected");
return(true);
}
/**
Permet d'exporter l'element en XML
@param document Document XML a utiliser
@param table_adr_id Table de correspondance entre les adresses des bornes
et leur id dans la representation XML ; cette table completee par cette
methode
@return L'element XML representant cet element electrique
*/
QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table_adr_id) const {
QDomElement element = document.createElement("element");
// type
QString chemin_elmt = typeId();
QString type_elmt = QETApp::symbolicPath(chemin_elmt);
element.setAttribute("type", type_elmt);
// position, selection et orientation
element.setAttribute("x", pos().x());
element.setAttribute("y", pos().y());
if (isSelected()) element.setAttribute("selected", "selected");
element.setAttribute("sens", QString("%1").arg(orientation()));
/* recupere le premier id a utiliser pour les bornes de cet element */
int id_terminal = 0;
if (!table_adr_id.isEmpty()) {
// trouve le plus grand id
int max_id_t = -1;
foreach (int id_t, table_adr_id.values()) {
if (id_t > max_id_t) max_id_t = id_t;
}
id_terminal = max_id_t + 1;
}
// enregistrement des bornes de l'appareil
QDomElement terminals = document.createElement("bornes");
// pour chaque enfant de l'element
foreach(QGraphicsItem *child, children()) {
// si cet enfant est une borne
if (Terminal *t = qgraphicsitem_cast<Terminal *>(child)) {
// alors on enregistre la borne
QDomElement terminal = t -> toXml(document);
terminal.setAttribute("id", id_terminal);
table_adr_id.insert(t, id_terminal ++);
terminals.appendChild(terminal);
}
}
element.appendChild(terminals);
return(element);
}

View File

@ -13,9 +13,9 @@
virtual int nbTerminalsMin() const = 0; virtual int nbTerminalsMin() const = 0;
virtual int nbTerminalsMax() const = 0; virtual int nbTerminalsMax() const = 0;
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0; virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
virtual QString typeId() = 0; virtual QString typeId() const = 0;
virtual QString nom() = 0; virtual QString nom() const = 0;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *);
QRectF boundingRect() const; QRectF boundingRect() const;
QSize setSize(int, int); QSize setSize(int, int);
@ -25,16 +25,15 @@
void deselect(); void deselect();
QPixmap pixmap(); QPixmap pixmap();
QVariant itemChange(GraphicsItemChange, const QVariant &); QVariant itemChange(GraphicsItemChange, const QVariant &);
bool orientation() const;
bool invertOrientation();
void setPos(const QPointF &); void setPos(const QPointF &);
void setPos(qreal, qreal); void setPos(qreal, qreal);
inline bool connexionsInternesAcceptees() { return(peut_relier_ses_propres_terminals); } inline bool connexionsInternesAcceptees() { return(peut_relier_ses_propres_terminals); }
inline void setConnexionsInternesAcceptees(bool cia) { peut_relier_ses_propres_terminals = cia; } inline void setConnexionsInternesAcceptees(bool cia) { peut_relier_ses_propres_terminals = cia; }
static bool valideXml(QDomElement &); static bool valideXml(QDomElement &);
virtual bool fromXml(QDomElement &, QHash<int, Terminal *>&) = 0; virtual bool fromXml(QDomElement &, QHash<int, Terminal *>&);
virtual QDomElement toXml (QDomDocument &, QHash<Terminal *, int>&) const;
// methodes d'acces aux possibilites d'orientation // methodes d'acces aux possibilites d'orientation
inline Terminal::Orientation orientation() { return(ori); } inline Terminal::Orientation orientation() const { return(ori); }
inline bool acceptOrientation(Terminal::Orientation o) { inline bool acceptOrientation(Terminal::Orientation o) {
switch(o) { switch(o) {
case Terminal::Nord: return(ori_n); case Terminal::Nord: return(ori_n);

View File

@ -18,65 +18,3 @@ int FixedElement::nbTerminalsMin() const {
int FixedElement::nbTerminalsMax() const { int FixedElement::nbTerminalsMax() const {
return(nbTerminals()); return(nbTerminals());
} }
/**
Methode d'import XML. Cette methode est appelee lors de l'import de contenu XML (coller, import, ouverture de fichier...) afin que l'element puisse gerer lui-meme l'importation de ses bornes. Ici, comme cette classe est caracterisee par un nombre fixe de bornes, l'implementation exige de retrouver exactement ses bornes dans le fichier XML.
@param e L'element XML a analyser.
@param table_id_adr Reference vers la table de correspondance entre les IDs du fichier XML et les adresses en memoire. Si l'import reussit, il faut y ajouter les bons couples (id, adresse).
@return true si l'import a reussi, false sinon
*/
bool FixedElement::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
/*
les bornes vont maintenant etre recensees pour associer leurs id à leur adresse reelle
ce recensement servira lors de la mise en place des fils
*/
QList<QDomElement> liste_terminals;
// parcours des enfants de l'element
for (QDomNode enfant = e.firstChild() ; !enfant.isNull() ; enfant = enfant.nextSibling()) {
// on s'interesse a l'element XML "bornes"
QDomElement terminals = enfant.toElement();
if (terminals.isNull() || terminals.tagName() != "bornes") continue;
// parcours des enfants de l'element XML "bornes"
for (QDomNode node_terminal = terminals.firstChild() ; !node_terminal.isNull() ; node_terminal = node_terminal.nextSibling()) {
// on s'interesse a l'element XML "borne"
QDomElement terminal = node_terminal.toElement();
if (!terminal.isNull() && Terminal::valideXml(terminal)) liste_terminals.append(terminal);
}
}
QHash<int, Terminal *> priv_id_adr;
int terminals_non_trouvees = 0;
foreach(QGraphicsItem *qgi, children()) {
if (Terminal *p = qgraphicsitem_cast<Terminal *>(qgi)) {
bool terminal_trouvee = false;
foreach(QDomElement qde, liste_terminals) {
if (p -> fromXml(qde)) {
priv_id_adr.insert(qde.attribute("id").toInt(), p);
terminal_trouvee = true;
break;
}
}
if (!terminal_trouvee) ++ terminals_non_trouvees;
}
}
if (terminals_non_trouvees > 0) {
return(false);
} else {
// verifie que les associations id / adr n'entrent pas en conflit avec table_id_adr
foreach(int id_trouve, priv_id_adr.keys()) {
if (table_id_adr.contains(id_trouve)) {
// cet element possede un id qui est deja reference (= conflit)
return(false);
}
}
// copie des associations id / adr
foreach(int id_trouve, priv_id_adr.keys()) {
table_id_adr.insert(id_trouve, priv_id_adr.value(id_trouve));
}
}
return(true);
}

View File

@ -6,10 +6,9 @@
FixedElement(QGraphicsItem * = 0, Diagram * = 0); FixedElement(QGraphicsItem * = 0, Diagram * = 0);
int nbTerminalsMin() const; int nbTerminalsMin() const;
int nbTerminalsMax() const; int nbTerminalsMax() const;
virtual bool fromXml(QDomElement &, QHash<int, Terminal *>&);
virtual int nbTerminals() const = 0; virtual int nbTerminals() const = 0;
virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0; virtual void paint(QPainter *, const QStyleOptionGraphicsItem *) = 0;
virtual QString typeId() = 0; virtual QString typeId() const = 0;
virtual QString nom() = 0; virtual QString nom() const = 0;
}; };
#endif #endif