Possibilite d'ajouter des champs de texte independants au schema

git-svn-id: svn+ssh://svn.tuxfamily.org/svnroot/qet/qet/trunk@193 bfdf4180-ca20-0410-9c96-a3a8aa849046
This commit is contained in:
xavierqet
2007-10-27 13:18:17 +00:00
parent 20a9a5158c
commit bece0588cb
16 changed files with 534 additions and 214 deletions

View File

@@ -60,6 +60,8 @@ Conductor::Conductor(Terminal *p1, Terminal* p2, Element *parent, QGraphicsScene
// ajout du champ de texte editable
text_item = new DiagramTextItem();
text_item -> setFlag(QGraphicsItem::ItemIsMovable, false);
text_item -> setTextInteractionFlags(Qt::TextEditorInteraction);
text_item -> setPlainText(properties_.text);
text_item -> previous_text = properties_.text;
calculateTextItemPosition();

View File

@@ -94,16 +94,7 @@ void Diagram::keyPressEvent(QKeyEvent *e) {
case Qt::Key_Down: movement = QPointF(0.0, +yGrid); break;
}
if (!movement.isNull() && !focusItem()) {
QSet<Element *> moved_elements = elementsToMove();
if (!moved_elements.isEmpty()) {
Element *first_elmt = NULL;
foreach(Element *elmt, moved_elements) {
first_elmt = elmt;
break;
}
first_elmt -> setPos(first_elmt -> pos() + movement);
first_elmt -> moveOtherElements(movement);
}
moveElements(movement);
}
QGraphicsScene::keyPressEvent(e);
}
@@ -126,6 +117,7 @@ void Diagram::keyReleaseEvent(QKeyEvent *e) {
elementsToMove(),
conductorsToMove(),
conductorsToUpdate(),
textsToMove(),
current_movement
)
);
@@ -240,20 +232,26 @@ QDomDocument Diagram::toXml(bool diagram) {
// si le schema ne contient pas d'element (et donc pas de conducteurs), on retourne de suite le document XML
if (items().isEmpty()) return(document);
// creation de deux listes : une qui contient les elements, une qui contient les conducteurs
QList<Element *> liste_elements;
QList<Conductor *> liste_conductors;
// creation de trois listes : une qui contient les elements, une qui contient les conducteurs, une qui contient les champs de texte
QList<Element *> list_elements;
QList<Conductor *> list_conductors;
QList<DiagramTextItem *> list_texts;
// Determine les elements a « XMLiser »
foreach(QGraphicsItem *qgi, items()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
if (diagram) liste_elements << elmt;
else if (elmt -> isSelected()) liste_elements << elmt;
if (diagram) list_elements << elmt;
else if (elmt -> isSelected()) list_elements << elmt;
} else if (Conductor *f = qgraphicsitem_cast<Conductor *>(qgi)) {
if (diagram) liste_conductors << f;
if (diagram) list_conductors << f;
// lorsqu'on n'exporte pas tout le diagram, il faut retirer les conducteurs non selectionnes
// et pour l'instant, les conducteurs non selectionnes sont les conducteurs dont un des elements n'est pas relie
else if (f -> terminal1 -> parentItem() -> isSelected() && f -> terminal2 -> parentItem() -> isSelected()) liste_conductors << f;
else if (f -> terminal1 -> parentItem() -> isSelected() && f -> terminal2 -> parentItem() -> isSelected()) list_conductors << f;
} else if (DiagramTextItem *dti = qgraphicsitem_cast<DiagramTextItem *>(qgi)) {
if (!dti -> parentItem()) {
if (diagram) list_texts << dti;
else if (dti -> isSelected()) list_texts << dti;
}
}
}
@@ -261,20 +259,31 @@ QDomDocument Diagram::toXml(bool diagram) {
QHash<Terminal *, int> table_adr_id;
// enregistrement des elements
if (liste_elements.isEmpty()) return(document);
if (!list_elements.isEmpty()) {
QDomElement elements = document.createElement("elements");
foreach(Element *elmt, liste_elements) {
foreach(Element *elmt, list_elements) {
elements.appendChild(elmt -> toXml(document, table_adr_id));
}
racine.appendChild(elements);
}
// enregistrement des conducteurs
if (liste_conductors.isEmpty()) return(document);
if (!list_conductors.isEmpty()) {
QDomElement conductors = document.createElement("conductors");
foreach(Conductor *cond, liste_conductors) {
foreach(Conductor *cond, list_conductors) {
conductors.appendChild(cond -> toXml(document, table_adr_id));
}
racine.appendChild(conductors);
}
// enregistrement des champs de texte
if (!list_texts.isEmpty()) {
QDomElement inputs = document.createElement("inputs");
foreach(DiagramTextItem *dti, list_texts) {
inputs.appendChild(dti -> toXml(document));
}
racine.appendChild(inputs);
}
// on retourne le document XML ainsi genere
return(document);
@@ -296,15 +305,15 @@ QDomDocument Diagram::toXml(bool diagram) {
fromXml
@return true si l'import a reussi, false sinon
*/
bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_informations, QList<Element *> *added_elements, QList<Conductor *> *added_conductors) {
QDomElement racine = document.documentElement();
bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_informations, QList<Element *> *added_elements_ptr, QList<Conductor *> *added_conductors_ptr, QList<DiagramTextItem *> *added_texts_ptr) {
QDomElement root = document.documentElement();
// le premier element doit etre un schema
if (racine.tagName() != "diagram") return(false);
if (root.tagName() != "diagram") return(false);
// verifie basiquement que la version actuelle est capable de lire ce fichier
if (racine.hasAttribute("version")) {
if (root.hasAttribute("version")) {
bool conv_ok;
qreal diagram_version = racine.attribute("version").toDouble(&conv_ok);
qreal diagram_version = root.attribute("version").toDouble(&conv_ok);
if (conv_ok && QET::version.toDouble() < diagram_version) {
QMessageBox::warning(
0,
@@ -318,27 +327,27 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
// lecture des attributs de ce schema
if (consider_informations) {
border_and_inset.setAuthor(racine.attribute("author"));
border_and_inset.setTitle(racine.attribute("title"));
border_and_inset.setDate(QDate::fromString(racine.attribute("date"), "yyyyMMdd"));
border_and_inset.setFileName(racine.attribute("filename"));
border_and_inset.setFolio(racine.attribute("folio"));
border_and_inset.setAuthor(root.attribute("author"));
border_and_inset.setTitle(root.attribute("title"));
border_and_inset.setDate(QDate::fromString(root.attribute("date"), "yyyyMMdd"));
border_and_inset.setFileName(root.attribute("filename"));
border_and_inset.setFolio(root.attribute("folio"));
bool ok;
// nombre de colonnes
int nb_cols = racine.attribute("cols").toInt(&ok);
int nb_cols = root.attribute("cols").toInt(&ok);
if (ok) border_and_inset.setNbColumns(nb_cols);
// taille des colonnes
double col_size = racine.attribute("colsize").toDouble(&ok);
double col_size = root.attribute("colsize").toDouble(&ok);
if (ok) border_and_inset.setColumnsWidth(col_size);
// hauteur du schema
double height = racine.attribute("height").toDouble(&ok);
double height = root.attribute("height").toDouble(&ok);
if (ok) border_and_inset.setColumnsHeight(height);
// repere le permier element "defaultconductor"
for (QDomNode node = racine.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
for (QDomNode node = root.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
QDomElement elmts = node.toElement();
if(elmts.isNull() || elmts.tagName() != "defaultconductor") continue;
defaultConductorProperties.fromXml(elmts);
@@ -348,21 +357,13 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
}
// si la racine n'a pas d'enfant : le chargement est fini (schema vide)
if (racine.firstChild().isNull()) return(true);
if (root.firstChild().isNull()) return(true);
// chargement de tous les Elements du fichier XML
QList<Element *> elements_ajoutes;
QHash< int, Terminal *> table_adr_id;
QHash< int, Terminal *> &ref_table_adr_id = table_adr_id;
for (QDomNode node = racine.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
// on s'interesse a l'element XML "elements" (= groupe d'elements)
QDomElement elmts = node.toElement();
if(elmts.isNull() || elmts.tagName() != "elements") continue;
// parcours des enfants de l'element XML "elements"
for (QDomNode n = elmts.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
// on s'interesse a l'element XML "element" (elements eux-memes)
QDomElement e = n.toElement();
if (e.isNull() || !Element::valideXml(e)) continue;
// chargement de tous les elements du fichier XML
QList<Element *> added_elements;
QHash<int, Terminal *> table_adr_id;
foreach (QDomElement e, QET::findInDomElement(root, "elements", "element")) {
if (!Element::valideXml(e)) continue;
// cree un element dont le type correspond à l'id type
QString type_id = e.attribute("type");
@@ -376,29 +377,34 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
}
// charge les caracteristiques de l'element
if (nvel_elmt -> fromXml(e, ref_table_adr_id)) {
if (nvel_elmt -> fromXml(e, table_adr_id)) {
// ajout de l'element au schema et a la liste des elements ajoutes
addItem(nvel_elmt);
elements_ajoutes << nvel_elmt;
added_elements << nvel_elmt;
} else {
delete nvel_elmt;
qDebug("Le chargement des parametres d'un element a echoue");
}
}
// chargement de tous les textes du fichiers XML
QList<DiagramTextItem *> added_texts;
foreach (QDomElement f, QET::findInDomElement(root, "inputs", "input")) {
DiagramTextItem *dti = new DiagramTextItem(0, this);
dti -> fromXml(f);
added_texts << dti;
}
if (added_elements) (*added_elements) << elements_ajoutes;
// aucun Element n'a ete ajoute - inutile de chercher des conducteurs - le chargement est fini
if (!elements_ajoutes.size()) return(true);
// gere la translation des nouveaux elements si celle-ci est demandee
// gere la translation des nouveaux elements et texte si celle-ci est demandee
if (position != QPointF()) {
// determine quel est le coin superieur gauche du rectangle entourant les elements ajoutes
qreal minimum_x = 0, minimum_y = 0;
bool init = false;
foreach (Element *elmt_ajoute, elements_ajoutes) {
QPointF csg = elmt_ajoute -> mapToScene(elmt_ajoute -> boundingRect().topLeft());
QList<QGraphicsItem *> added_items;
foreach (Element *added_element, added_elements) added_items << added_element;
foreach (DiagramTextItem *added_text, added_texts) added_items << added_text;
foreach (QGraphicsItem *item, added_items) {
QPointF csg = item -> mapToScene(item -> boundingRect().topLeft());
qreal px = csg.x();
qreal py = csg.y();
if (!init) {
@@ -412,21 +418,18 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
}
qreal diff_x = position.x() - minimum_x;
qreal diff_y = position.y() - minimum_y;
foreach (Element *elmt_ajoute, elements_ajoutes) {
elmt_ajoute -> setPos(elmt_ajoute -> pos().x() + diff_x, elmt_ajoute -> pos().y() + diff_y);
foreach (Element *added_element, added_elements) {
added_element -> setPos(added_element -> pos().x() + diff_x, added_element -> pos().y() + diff_y);
}
foreach (DiagramTextItem *added_text, added_texts) {
added_text -> setPos(added_text -> pos().x() + diff_x, added_text -> pos().y() + diff_y);
}
}
// chargement de tous les Conducteurs du fichier XML
for (QDomNode node = racine.firstChild() ; !node.isNull() ; node = node.nextSibling()) {
// on s'interesse a l'element XML "conducteurs" (= groupe de conducteurs)
QDomElement conductors = node.toElement();
if(conductors.isNull() || conductors.tagName() != "conductors") continue;
// parcours des enfants de l'element XML "conducteurs"
for (QDomNode n = conductors.firstChild() ; !n.isNull() ; n = n.nextSibling()) {
// on s'interesse a l'element XML "element" (elements eux-memes)
QDomElement f = n.toElement();
if (f.isNull() || !Conductor::valideXml(f)) continue;
QList<Conductor *> added_conductors;
foreach (QDomElement f, QET::findInDomElement(root, "conductors", "conductor")) {
if (!Conductor::valideXml(f)) continue;
// verifie que les bornes que le conducteur relie sont connues
int id_p1 = f.attribute("terminal1").toInt();
int id_p2 = f.attribute("terminal2").toInt();
@@ -435,18 +438,27 @@ bool Diagram::fromXml(QDomDocument &document, QPointF position, bool consider_in
Terminal *p1 = table_adr_id.value(id_p1);
Terminal *p2 = table_adr_id.value(id_p2);
if (p1 != p2) {
bool peut_poser_conductor = true;
bool can_add_conductor = true;
bool cia = ((Element *)p2 -> parentItem()) -> connexionsInternesAcceptees();
if (!cia) foreach(QGraphicsItem *item, p2 -> parentItem() -> children()) if (item == p1) peut_poser_conductor = false;
if (peut_poser_conductor) {
if (!cia) {
foreach(QGraphicsItem *item, p2 -> parentItem() -> children()) {
if (item == p1) can_add_conductor = false;
}
}
if (can_add_conductor) {
Conductor *c = new Conductor(table_adr_id.value(id_p1), table_adr_id.value(id_p2), 0, this);
c -> fromXml(f);
if (added_conductors) (*added_conductors) << c;
added_conductors << c;
}
}
} else qDebug() << "Le chargement du conductor" << id_p1 << id_p2 << "a echoue";
}
}
// remplissage des listes facultatives
if (added_elements_ptr != NULL) *added_elements_ptr = added_elements;
if (added_conductors_ptr != NULL) *added_conductors_ptr = added_conductors;
if (added_texts_ptr != NULL) *added_texts_ptr = added_texts;
return(true);
}
@@ -485,6 +497,7 @@ void Diagram::invalidateMovedElements() {
elements_to_move.clear();
conductors_to_move.clear();
conductors_to_update.clear();
texts_to_move.clear();
}
/// reconstruit la liste des elements et conducteurs en mouvement
@@ -493,6 +506,8 @@ void Diagram::fetchMovedElements() {
foreach (QGraphicsItem *item, selectedItems()) {
if (Element *elmt = qgraphicsitem_cast<Element *>(item)) {
elements_to_move << elmt;
} else if (DiagramTextItem *t = qgraphicsitem_cast<DiagramTextItem *>(item)) {
if (!t -> parentItem()) texts_to_move << t;
}
}
@@ -518,6 +533,44 @@ void Diagram::fetchMovedElements() {
moved_elements_fetched = true;
}
/**
Deplace les elements, conducteurs et textes selectionnes en gerant au
mieux les conducteurs (seuls les conducteurs dont un seul des elements
est deplace sont recalcules, les autres sont deplaces).
@param diff Translation a effectuer
@param dontmove QGraphicsItem (optionnel) a ne pas deplacer ; note : ce
parametre ne concerne que les elements et les champs de texte.
*/
void Diagram::moveElements(const QPointF &diff, QGraphicsItem *dontmove) {
// inutile de deplacer les autres elements s'il n'y a pas eu de mouvement concret
if (diff.isNull()) return;
current_movement += diff;
// deplace les elements selectionnes
foreach(Element *element, elementsToMove()) {
if (dontmove != NULL && element == dontmove) continue;
element -> setPos(element -> pos() + diff);
}
// deplace certains conducteurs
foreach(Conductor *conductor, conductorsToMove()) {
conductor -> setPos(conductor -> pos() + diff);
}
// recalcule les autres conducteurs
const QHash<Conductor *, Terminal *> &conductors_modify = conductorsToUpdate();
foreach(Conductor *conductor, conductors_modify.keys()) {
conductor -> updateWithNewPos(QRectF(), conductors_modify[conductor], conductors_modify[conductor] -> amarrageConductor());
}
// deplace les champs de texte
foreach(DiagramTextItem *dti, textsToMove()) {
if (dontmove != NULL && dti == dontmove) continue;
dti -> setPos(dti -> pos() + diff);
}
}
/**
Definit s'il faut afficher ou non les bornes
@param dt true pour afficher les bornes, false sinon

View File

@@ -9,6 +9,7 @@
class Element;
class Terminal;
class Conductor;
class DiagramTextItem;
/**
Cette classe represente un schema electrique.
Elle gere les differents elements et conducteurs qui le composent
@@ -55,6 +56,7 @@ class Diagram : public QGraphicsScene {
QSet<Element *> elements_to_move;
QSet<Conductor *> conductors_to_move;
QHash<Conductor *, Terminal *> conductors_to_update;
QSet<DiagramTextItem *> texts_to_move;
QGIManager qgi_manager;
QUndoStack undo_stack;
bool draw_terminals;
@@ -72,7 +74,7 @@ class Diagram : public QGraphicsScene {
// fonctions relatives a l'import / export XML
QDomDocument toXml(bool = true);
bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, QList<Element *> * = NULL, QList<Conductor *> * = NULL);
bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, QList<Element *> * = NULL, QList<Conductor *> * = NULL, QList<DiagramTextItem *> * = NULL);
// fonctions relatives aux options graphiques
void setDisplayGrid(bool);
@@ -94,7 +96,9 @@ class Diagram : public QGraphicsScene {
const QSet<Element *> &elementsToMove();
const QSet<Conductor *> &conductorsToMove();
const QHash<Conductor *, Terminal *> &conductorsToUpdate();
const QSet<DiagramTextItem *> &textsToMove();
QSet<Conductor *> selectedConductors() const;
void moveElements(const QPointF &, QGraphicsItem * = NULL);
QUndoStack &undoStack();
QGIManager &qgiManager();
@@ -215,6 +219,12 @@ inline const QHash<Conductor *, Terminal *> &Diagram::conductorsToUpdate() {
return(conductors_to_update);
}
/// @return la liste des textes a deplacer
inline const QSet<DiagramTextItem *> &Diagram::textsToMove() {
if (!moved_elements_fetched) fetchMovedElements();
return(texts_to_move);
}
/// @return la pile d'annulations de ce schema
inline QUndoStack &Diagram::undoStack() {
return(undo_stack);

View File

@@ -41,6 +41,39 @@ void AddElementCommand::redo() {
element -> setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
}
/**
Constructeur
@param dia Schema auquel on ajoute du texte
@param elmt Texte ajoute
@param p Position a laquelle le texte est ajoute
@param parent QUndoCommand parent
*/
AddTextCommand::AddTextCommand(Diagram *dia, DiagramTextItem *text, const QPointF &pos, QUndoCommand *parent) :
QUndoCommand(QObject::tr("Ajouter un champ de texte"), parent),
textitem(text),
diagram(dia),
position(pos)
{
diagram -> qgiManager().manage(textitem);
}
/// Destructeur
AddTextCommand::~AddTextCommand() {
diagram -> qgiManager().release(textitem);
}
/// Annule l'ajout
void AddTextCommand::undo() {
diagram -> removeItem(textitem);
}
/// Refait l'ajour
void AddTextCommand::redo() {
diagram -> addItem(textitem);
textitem -> setPos(position);
textitem -> setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
}
/**
Constructeur
@param d Schema auquel on ajoute un conducteur
@@ -82,28 +115,33 @@ void AddConductorCommand::redo() {
@param dia Schema dont on supprime des elements et conducteurs
@param elements Elements supprimes
@param conductors Conducteurs supprimes
@param texts Textes supprimes
@param parent QUndoCommand parent
*/
DeleteElementsCommand::DeleteElementsCommand(
Diagram *dia,
QSet<Element *> elements,
QSet<Conductor *> conductors,
QSet<DiagramTextItem *> texts,
QUndoCommand *parent
) :
QUndoCommand(parent),
removed_elements(elements),
removed_conductors(conductors),
removed_texts(texts),
diagram(dia)
{
setText(QObject::tr("supprimer ") + QET::ElementsAndConductorsSentence(removed_elements.count(), removed_conductors.count()));
setText(QObject::tr("supprimer ") + QET::ElementsAndConductorsSentence(removed_elements.count(), removed_conductors.count(), removed_texts.count()));
foreach(QGraphicsItem *qgi, removed_elements) diagram -> qgiManager().manage(qgi);
foreach(QGraphicsItem *qgi, removed_conductors) diagram -> qgiManager().manage(qgi);
foreach(QGraphicsItem *qgi, removed_texts) diagram -> qgiManager().manage(qgi);
}
/// Destructeur
DeleteElementsCommand::~DeleteElementsCommand() {
foreach(QGraphicsItem *qgi, removed_elements) diagram -> qgiManager().release(qgi);
foreach(QGraphicsItem *qgi, removed_conductors) diagram -> qgiManager().release(qgi);
foreach(QGraphicsItem *qgi, removed_texts) diagram -> qgiManager().release(qgi);
}
/// annule les suppressions
@@ -119,6 +157,11 @@ void DeleteElementsCommand::undo() {
c -> terminal1 -> addConductor(c);
c -> terminal2 -> addConductor(c);
}
// remet les textes
foreach(DiagramTextItem *t, removed_texts) {
diagram -> addItem(t);
}
}
/// refait les suppressions
@@ -134,6 +177,11 @@ void DeleteElementsCommand::redo() {
foreach(Element *e, removed_elements) {
diagram -> removeItem(e);
}
// enleve les textes
foreach(DiagramTextItem *t, removed_texts) {
diagram -> removeItem(t);
}
}
/**
@@ -141,29 +189,34 @@ void DeleteElementsCommand::redo() {
@param dia Schema sur lequel on colle les elements et conducteurs
@param e Elements colles sur le schema
@param c Conducteurs colles sur le schema
@param t Textes colles sur le schema
@param parent QUndoCommand parent
*/
PasteDiagramCommand::PasteDiagramCommand(
Diagram *dia,
const QList<Element *> &e,
const QList<Conductor *> &c,
const QList<DiagramTextItem *> &t,
QUndoCommand *parent
) :
QUndoCommand(parent),
elements(e),
conductors(c),
texts(t),
diagram(dia),
first_redo(true)
{
setText(QObject::tr("coller ") + QET::ElementsAndConductorsSentence(elements.count(), conductors.count()));
foreach(QGraphicsItem *qgi, elements) diagram -> qgiManager().manage(qgi);
foreach(QGraphicsItem *qgi, conductors) diagram -> qgiManager().manage(qgi);
foreach(QGraphicsItem *qgi, texts) diagram -> qgiManager().manage(qgi);
}
/// Destructeur
PasteDiagramCommand::~PasteDiagramCommand() {
foreach(QGraphicsItem *qgi, elements) diagram -> qgiManager().release(qgi);
foreach(QGraphicsItem *qgi, conductors) diagram -> qgiManager().release(qgi);
foreach(QGraphicsItem *qgi, texts) diagram -> qgiManager().release(qgi);
}
/// annule le coller
@@ -177,6 +230,9 @@ void PasteDiagramCommand::undo() {
// enleve les elements
foreach(Element *e, elements) diagram -> removeItem(e);
// enleve les textes
foreach(DiagramTextItem *t, texts) diagram -> removeItem(t);
}
/// refait le coller
@@ -192,9 +248,13 @@ void PasteDiagramCommand::redo() {
c -> terminal1 -> addConductor(c);
c -> terminal2 -> addConductor(c);
}
// pose les textes
foreach(DiagramTextItem *t, texts) diagram -> addItem(t);
}
foreach(Element *e, elements) e -> setSelected(true);
foreach(Conductor *c, conductors) c -> setSelected(true);
foreach(DiagramTextItem *t, texts) t -> setSelected(true);
}
/**
@@ -208,11 +268,12 @@ CutDiagramCommand::CutDiagramCommand(
Diagram *dia,
QSet<Element *> elements,
QSet<Conductor *> conductors,
QSet<DiagramTextItem *> texts,
QUndoCommand *parent
) :
DeleteElementsCommand(dia, elements, conductors, parent)
DeleteElementsCommand(dia, elements, conductors, texts, parent)
{
setText(QObject::tr("couper ") + QET::ElementsAndConductorsSentence(elements.count(), conductors.count()));
setText(QObject::tr("couper ") + QET::ElementsAndConductorsSentence(elements.count(), conductors.count(), texts.count()));
}
/// Destructeur
@@ -225,6 +286,7 @@ CutDiagramCommand::~CutDiagramCommand() {
@param move_elements Elements a deplacer
@param move_conductors Conducteurs a deplacer
@param modify_conductors Conducteurs a mettre a jour
@param move_texts Textes a deplacer
@param m translation subie par les elements
@param parent QUndoCommand parent
*/
@@ -233,6 +295,7 @@ MoveElementsCommand::MoveElementsCommand(
const QSet<Element *> &move_elements,
const QSet<Conductor *> &move_conductors,
const QHash<Conductor *, Terminal *> &modify_conductors,
const QSet<DiagramTextItem *> &move_texts,
const QPointF &m,
QUndoCommand *parent
) :
@@ -241,9 +304,11 @@ MoveElementsCommand::MoveElementsCommand(
elements_to_move(move_elements),
conductors_to_move(move_conductors),
conductors_to_update(modify_conductors),
movement(m)
texts_to_move(move_texts),
movement(m),
first_redo(true)
{
setText(QObject::tr("d\351placer ") + QET::ElementsAndConductorsSentence(elements_to_move.count(), conductors_to_move.count()));
setText(QObject::tr("d\351placer ") + QET::ElementsAndConductorsSentence(elements_to_move.count(), conductors_to_move.count(), texts_to_move.count()));
}
/// Destructeur
@@ -280,6 +345,11 @@ void MoveElementsCommand::move(const QPointF &actual_movement) {
foreach(Conductor *conductor, conductors_to_update.keys()) {
conductor -> updateWithNewPos(QRectF(), conductors_to_update[conductor], conductors_to_update[conductor] -> amarrageConductor());
}
// deplace les textes
foreach(DiagramTextItem *text, texts_to_move) {
text -> setPos(text -> pos() + actual_movement);
}
}
/**

View File

@@ -32,6 +32,32 @@ class AddElementCommand : public QUndoCommand {
QPointF position;
};
/**
Cette classe represente l'action d'ajouter du texte au schema
*/
class AddTextCommand : public QUndoCommand {
// constructeurs, destructeur
public:
AddTextCommand(Diagram *, DiagramTextItem *, const QPointF &, QUndoCommand * = 0);
virtual ~AddTextCommand();
private:
AddTextCommand(const AddTextCommand &);
// methodes
public:
virtual void undo();
virtual void redo();
// attributs
private:
/// texte ajoute
DiagramTextItem *textitem;
/// schema sur lequel on ajoute le texte
Diagram *diagram;
/// position du texte sur le schema
QPointF position;
};
/**
Cette classe represente l'action d'ajouter un conducteur au schema
*/
@@ -63,7 +89,7 @@ class AddConductorCommand : public QUndoCommand {
class DeleteElementsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
DeleteElementsCommand(Diagram *, QSet<Element *>, QSet<Conductor *>, QUndoCommand * = 0);
DeleteElementsCommand(Diagram *, QSet<Element *>, QSet<Conductor *>, QSet<DiagramTextItem *>, QUndoCommand * = 0);
virtual ~DeleteElementsCommand();
private:
DeleteElementsCommand(const DeleteElementsCommand &);
@@ -79,6 +105,8 @@ class DeleteElementsCommand : public QUndoCommand {
QSet<Element *> removed_elements;
/// liste des conducteurs enleves
QSet<Conductor *> removed_conductors;
/// liste des textes enleves
QSet<DiagramTextItem *> removed_texts;
/// schema dont on supprime des elements et conducteurs
Diagram *diagram;
};
@@ -89,7 +117,7 @@ class DeleteElementsCommand : public QUndoCommand {
class PasteDiagramCommand : public QUndoCommand {
// constructeurs, destructeur
public:
PasteDiagramCommand(Diagram *, const QList<Element *> &, const QList<Conductor *> &, QUndoCommand * = 0);
PasteDiagramCommand(Diagram *, const QList<Element *> &, const QList<Conductor *> &, const QList<DiagramTextItem *> &, QUndoCommand * = 0);
virtual ~PasteDiagramCommand();
private:
PasteDiagramCommand(const PasteDiagramCommand &);
@@ -105,6 +133,8 @@ class PasteDiagramCommand : public QUndoCommand {
QList<Element *> elements;
/// conducteurs ajoutes
QList<Conductor *> conductors;
/// textes ajoutes
QList<DiagramTextItem *> texts;
/// schema sur lequel on colle les elements et conducteurs
Diagram *diagram;
/// booleen pour empecher le premier appel a redo
@@ -118,7 +148,7 @@ class PasteDiagramCommand : public QUndoCommand {
class CutDiagramCommand : public DeleteElementsCommand {
// constructeurs, destructeur
public:
CutDiagramCommand(Diagram *, QSet<Element *>, QSet<Conductor *>, QUndoCommand * = 0);
CutDiagramCommand(Diagram *, QSet<Element *>, QSet<Conductor *>, QSet<DiagramTextItem *>, QUndoCommand * = 0);
virtual ~CutDiagramCommand();
private:
CutDiagramCommand(const CutDiagramCommand &);
@@ -131,7 +161,7 @@ class CutDiagramCommand : public DeleteElementsCommand {
class MoveElementsCommand : public QUndoCommand {
// constructeurs, destructeur
public:
MoveElementsCommand(Diagram *, const QSet<Element *> &, const QSet<Conductor *> &, const QHash<Conductor *, Terminal *> &, const QPointF &m, QUndoCommand * = 0);
MoveElementsCommand(Diagram *, const QSet<Element *> &, const QSet<Conductor *> &, const QHash<Conductor *, Terminal *> &, const QSet<DiagramTextItem *> &, const QPointF &m, QUndoCommand * = 0);
virtual ~MoveElementsCommand();
private:
MoveElementsCommand(const MoveElementsCommand &);
@@ -152,6 +182,8 @@ class MoveElementsCommand : public QUndoCommand {
QSet<Conductor *> conductors_to_move;
/// conducteurs a actualiser
QHash<Conductor *, Terminal *> conductors_to_update;
/// textes a deplacer
QSet<DiagramTextItem *> texts_to_move;
/// mouvement effectue
QPointF movement;
/// booleen pour ne pas executer le premier redo()

View File

@@ -9,7 +9,8 @@
DiagramTextItem::DiagramTextItem(QGraphicsItem *parent, QGraphicsScene *scene) :
QGraphicsTextItem(parent, scene)
{
setTextInteractionFlags(Qt::TextEditorInteraction);
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
}
/**
@@ -22,7 +23,8 @@ DiagramTextItem::DiagramTextItem(const QString &text, QGraphicsItem *parent, QGr
QGraphicsTextItem(text, parent, scene),
previous_text(text)
{
setTextInteractionFlags(Qt::TextEditorInteraction);
setFlags(QGraphicsItem::ItemIsSelectable|QGraphicsItem::ItemIsMovable);
connect(this, SIGNAL(lostFocus()), this, SLOT(setNonFocusable()));
}
/// Destructeur
@@ -44,14 +46,6 @@ void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
if (Diagram *dia = diagram()) {
dia -> undoStack().push(new ChangeDiagramTextCommand(this, previous_text, toPlainText()));
previous_text = toPlainText();
// si l'object parent est un conducteur, previent celui-ci du changement de texte
Conductor *c;
if (parentItem() && (c = qgraphicsitem_cast<Conductor *>(parentItem()))) {
ConductorProperties cp = c -> properties();
cp.text = toPlainText();
c -> setProperties(cp);
}
}
}
@@ -59,4 +53,128 @@ void DiagramTextItem::focusOutEvent(QFocusEvent *e) {
QTextCursor cursor = textCursor();
cursor.clearSelection();
setTextCursor(cursor);
if (flags() & QGraphicsItem::ItemIsMovable) {
// hack a la con pour etre re-entrant
setTextInteractionFlags(Qt::NoTextInteraction);
QTimer::singleShot(0, this, SIGNAL(lostFocus()));
}
}
/**
Permet de lire le texte a mettre dans le champ a partir d'un element XML.
Cette methode se base sur la position du champ pour assigner ou non la
valeur a ce champ.
@param e L'element XML representant le champ de texte
*/
void DiagramTextItem::fromXml(const QDomElement &e) {
setPos(e.attribute("x").toDouble(), e.attribute("y").toDouble());
setPlainText(e.attribute("text"));
previous_text = e.attribute("text");
}
/**
@param document Le document XML a utiliser
@return L'element XML representant ce champ de texte
*/
QDomElement DiagramTextItem::toXml(QDomDocument &document) const {
QDomElement result = document.createElement("input");
result.setAttribute("x", pos().x());
result.setAttribute("y", pos().y());
result.setAttribute("text", toPlainText());
return(result);
}
void DiagramTextItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) {
if (flags() & QGraphicsItem::ItemIsMovable && !(textInteractionFlags() & Qt::TextEditable)) {
// rend le champ de texte editable
setTextInteractionFlags(Qt::TextEditorInteraction);
// simule un clic simple, ce qui edite le champ de texte
QGraphicsSceneMouseEvent *mouseEvent = new QGraphicsSceneMouseEvent(QEvent::GraphicsSceneMousePress);
mouseEvent -> setAccepted(true);
mouseEvent -> setPos(event -> pos());
mouseEvent -> setScenePos(event -> scenePos());
mouseEvent -> setScreenPos(event -> screenPos());
mouseEvent -> setButtonDownPos(Qt::LeftButton, event -> buttonDownPos(Qt::LeftButton));
mouseEvent -> setButtonDownScreenPos(Qt::LeftButton, event -> buttonDownScreenPos(Qt::LeftButton));
mouseEvent -> setButtonDownScenePos(Qt::LeftButton, event -> buttonDownScenePos(Qt::LeftButton));
mouseEvent -> setWidget(event -> widget());
QGraphicsTextItem::mousePressEvent(mouseEvent);
delete mouseEvent;
} else {
QGraphicsTextItem::mouseDoubleClickEvent(event);
}
}
/**
Gere les mouvements de souris lies au champ de texte
*/
void DiagramTextItem::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (textInteractionFlags() & Qt::TextEditable) {
QGraphicsTextItem::mouseMoveEvent(e);
} else if ((flags() & QGraphicsItem::ItemIsMovable) && (e -> buttons() & Qt::LeftButton)) {
QPointF oldPos = pos();
setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
if (Diagram *diagram_ptr = diagram()) {
diagram_ptr -> moveElements(pos() - oldPos, this);
}
} else e -> ignore();
}
/**
Gere le relachement de souris
Cette methode a ete reimplementee pour tenir a jour la liste des elements
et conducteurs a deplacer au niveau du schema.
*/
void DiagramTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
if (Diagram *diagram_ptr = diagram()) {
if ((flags() & QGraphicsItem::ItemIsMovable) && (!diagram_ptr -> current_movement.isNull())) {
diagram_ptr -> undoStack().push(
new MoveElementsCommand(
diagram_ptr,
diagram_ptr -> elementsToMove(),
diagram_ptr -> conductorsToMove(),
diagram_ptr -> conductorsToUpdate(),
diagram_ptr -> textsToMove(),
diagram_ptr -> current_movement
)
);
diagram_ptr -> current_movement = QPointF();
}
diagram_ptr -> invalidateMovedElements();
}
QGraphicsTextItem::mouseReleaseEvent(e);
}
/**
Change la position du champ de texte en veillant a ce qu'il
reste sur la grille du schema auquel il appartient.
@param p Nouvelles coordonnees de l'element
*/
void DiagramTextItem::setPos(const QPointF &p) {
if (p == pos()) return;
// pas la peine de positionner sur la grille si l'element n'est pas sur un Diagram
if (scene()) {
// arrondit l'abscisse a 10 px pres
int p_x = qRound(p.x() / (Diagram::xGrid * 1.0)) * Diagram::xGrid;
// arrondit l'ordonnee a 10 px pres
int p_y = qRound(p.y() / (Diagram::yGrid * 1.0)) * Diagram::yGrid;
QGraphicsTextItem::setPos(p_x, p_y);
} else QGraphicsTextItem::setPos(p);
}
/**
Change la position du champ de texte en veillant a ce que l'il
reste sur la grille du schema auquel il appartient.
@param x Nouvelle abscisse de l'element
@param y Nouvelle ordonnee de l'element
*/
void DiagramTextItem::setPos(qreal x, qreal y) {
setPos(QPointF(x, y));
}
/// Rend le champ de texte non focusable
void DiagramTextItem::setNonFocusable() {
setFlag(QGraphicsTextItem::ItemIsFocusable, false);
}

View File

@@ -6,6 +6,7 @@
Cette classe represente un champ de texte editable sur le schema.
*/
class DiagramTextItem : public QGraphicsTextItem {
Q_OBJECT
// constructeurs, destructeur
public:
DiagramTextItem(QGraphicsItem * = 0, QGraphicsScene * = 0);
@@ -26,8 +27,23 @@ class DiagramTextItem : public QGraphicsTextItem {
*/
virtual int type() const { return Type; }
Diagram *diagram() const;
virtual void fromXml(const QDomElement &);
virtual QDomElement toXml(QDomDocument &) const;
virtual void setPos(const QPointF &);
virtual void setPos(qreal, qreal);
protected:
virtual void focusOutEvent(QFocusEvent *);
virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
// signaux
signals:
void lostFocus();
// slots
public slots:
void setNonFocusable();
};
#endif

View File

@@ -10,7 +10,7 @@
Constructeur
@param parent Le QWidegt parent de cette vue de schema
*/
DiagramView::DiagramView(QWidget *parent) : QGraphicsView(parent) {
DiagramView::DiagramView(QWidget *parent) : QGraphicsView(parent), is_adding_text(false) {
setInteractive(true);
setCacheMode(QGraphicsView::CacheBackground);
setOptimizationFlags(QGraphicsView::DontSavePainterState|QGraphicsView::DontAdjustForAntialiasing);
@@ -79,6 +79,7 @@ void DiagramView::deleteSelection() {
QSet<Element *> garbage_elmt;
QSet<Conductor *> garbage_conductors;
QSet<DiagramTextItem *> garbage_texts;
// creation de deux listes : une pour les conducteurs, une pour les elements
foreach (QGraphicsItem *qgi, scene -> selectedItems()) {
@@ -90,10 +91,12 @@ void DiagramView::deleteSelection() {
garbage_elmt << e;
// s'il s'agit d'un element, on veille a enlever ses conducteurs
garbage_conductors += e -> conductors().toSet();
} else if (DiagramTextItem *t = qgraphicsitem_cast<DiagramTextItem *>(qgi)) {
if (!t -> parentItem()) garbage_texts << t;
}
}
scene -> clearSelection();
scene -> undoStack().push(new DeleteElementsCommand(scene, garbage_elmt, garbage_conductors));
scene -> undoStack().push(new DeleteElementsCommand(scene, garbage_elmt, garbage_conductors, garbage_texts));
}
/**
@@ -209,21 +212,25 @@ void DiagramView::cut() {
copy();
QSet<Element *> cut_elmt;
QSet<Conductor *> cut_conductors;
QSet<DiagramTextItem *> cut_texts;
// creation de deux listes : une pour les conducteurs, une pour les elements
foreach (QGraphicsItem *qgi, scene -> selectedItems()) {
// pour chaque qgi selectionne, il s'agit soit d'un element soit d'un conducteur
if (Conductor * c = qgraphicsitem_cast<Conductor *>(qgi)) {
if (Conductor *c = qgraphicsitem_cast<Conductor *>(qgi)) {
// s'il s'agit d'un conducteur, on le met dans la liste des conducteurs
cut_conductors << c;
} else if (Element *e = qgraphicsitem_cast<Element *>(qgi)) {
cut_elmt << e;
// s'il s'agit d'un element, on veille a enlever ses conducteurs
cut_conductors += e -> conductors().toSet();
} else if (DiagramTextItem *t = qgraphicsitem_cast<DiagramTextItem *>(qgi)) {
// les textes recherches n'ont pas de parent
if (!t -> parentItem()) cut_texts << t;
}
}
scene -> clearSelection();
scene -> undoStack().push(new CutDiagramCommand(scene, cut_elmt, cut_conductors));
scene -> undoStack().push(new CutDiagramCommand(scene, cut_elmt, cut_conductors, cut_texts));
}
/**
@@ -248,12 +255,13 @@ void DiagramView::paste() {
// listes pour recupere les elements et conducteurs ajoutes au schema par le coller
QList<Element *> elements_pasted;
QList<Conductor *> conductors_pasted;
scene -> fromXml(document_xml, QPointF(), false, &elements_pasted, &conductors_pasted);
QList<DiagramTextItem *> texts_pasted;
scene -> fromXml(document_xml, QPointF(), false, &elements_pasted, &conductors_pasted, &texts_pasted);
// si quelque chose a effectivement ete ajoute au schema, on cree
if (elements_pasted.count() || conductors_pasted.count()) {
scene -> clearSelection();
scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conductors_pasted));
scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conductors_pasted, texts_pasted));
}
}
@@ -270,14 +278,23 @@ void DiagramView::mousePressEvent(QMouseEvent *e) {
// listes pour recupere les elements et conducteurs ajoutes au schema par le coller
QList<Element *> elements_pasted;
QList<Conductor *> conductors_pasted;
scene -> fromXml(document_xml, mapToScene(e -> pos()), false, &elements_pasted, &conductors_pasted);
QList<DiagramTextItem *> texts_pasted;
scene -> fromXml(document_xml, mapToScene(e -> pos()), false, &elements_pasted, &conductors_pasted, &texts_pasted);
// si quelque chose a effectivement ete ajoute au schema, on cree
if (elements_pasted.count() || conductors_pasted.count()) {
scene -> clearSelection();
scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conductors_pasted));
scene -> undoStack().push(new PasteDiagramCommand(scene, elements_pasted, conductors_pasted, texts_pasted));
}
} 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, e -> pos()));
is_adding_text = false;
emit(textAdded(false));
}
QGraphicsView::mousePressEvent(e);
}
}
@@ -792,3 +809,7 @@ bool DiagramView::event(QEvent *e) {
}
return(QGraphicsView::event(e));
}
void DiagramView::addText() {
is_adding_text = true;
}

View File

@@ -22,6 +22,7 @@ class DiagramView : public QGraphicsView {
private:
Diagram *scene;
bool is_adding_text;
// methodes
public:
@@ -38,6 +39,7 @@ class DiagramView : public QGraphicsView {
void shrink();
Diagram *diagram() { return(scene); }
bool hasSelectedItems();
void addText();
protected:
virtual void wheelEvent(QWheelEvent *);
@@ -57,6 +59,8 @@ class DiagramView : public QGraphicsView {
void selectionChanged();
/// Signal emis lorsque le mode de selection change
void modeChanged();
/// Signal emis lorsqu'un texte a ete pose
void textAdded(bool);
public slots:
void selectNothing();

View File

@@ -246,44 +246,12 @@ void Element::mouseMoveEvent(QGraphicsSceneMouseEvent *e) {
if (e -> buttons() & Qt::LeftButton) {
QPointF oldPos = pos();
setPos(mapToParent(e -> pos()) - matrix().map(e -> buttonDownPos(Qt::LeftButton)));
moveOtherElements(pos() - oldPos);
if (Diagram *diagram_ptr = diagram()) {
diagram_ptr -> moveElements(pos() - oldPos, this);
}
} else e -> ignore();
}
/**
Deplace les autres elements selectionnes en gerant au mieux les conducteurs
(seuls les conducteurs dont un seul des elements est deplace sont
recalcules, les autres sont deplaces).
@param diff Translation a effectuer
*/
void Element::moveOtherElements(const QPointF &diff) {
// inutile de deplacer les autres elements s'il n'y a pas eu de mouvement concret
if (diff.isNull()) return;
// recupere le schema parent
Diagram *diagram_ptr = diagram();
if (!diagram_ptr) return;
diagram_ptr -> current_movement += diff;
// deplace les elements selectionnes
foreach(Element *element, diagram_ptr -> elementsToMove()) {
if (element == this) continue;
element -> setPos(element -> pos() + diff);
}
// deplace certains conducteurs
foreach(Conductor *conductor, diagram_ptr -> conductorsToMove()) {
conductor -> setPos(conductor -> pos() + diff);
}
// recalcule les autres conducteurs
const QHash<Conductor *, Terminal *> &conductors_modify = diagram_ptr -> conductorsToUpdate();
foreach(Conductor *conductor, conductors_modify.keys()) {
conductor -> updateWithNewPos(QRectF(), conductors_modify[conductor], conductors_modify[conductor] -> amarrageConductor());
}
}
/**
Gere le relachement de souris
Cette methode a ete reimplementee pour tenir a jour la liste des elements
@@ -299,6 +267,7 @@ void Element::mouseReleaseEvent(QGraphicsSceneMouseEvent *e) {
diagram_ptr -> elementsToMove(),
diagram_ptr -> conductorsToMove(),
diagram_ptr -> conductorsToUpdate(),
diagram_ptr -> textsToMove(),
diagram_ptr -> current_movement
)
);
@@ -353,7 +322,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
ce recensement servira lors de la mise en place des fils
*/
QList<QDomElement> liste_terminals;
foreach(QDomElement qde, findInDomElement(e, "terminals", "terminal")) {
foreach(QDomElement qde, QET::findInDomElement(e, "terminals", "terminal")) {
if (Terminal::valideXml(qde)) liste_terminals << qde;
}
@@ -390,7 +359,7 @@ bool Element::fromXml(QDomElement &e, QHash<int, Terminal *> &table_id_adr) {
}
// importe les valeurs des champs de texte
QList<QDomElement> inputs = findInDomElement(e, "inputs", "input");
QList<QDomElement> inputs = QET::findInDomElement(e, "inputs", "input");
foreach(QGraphicsItem *qgi, children()) {
if (ElementTextItem *eti = qgraphicsitem_cast<ElementTextItem *>(qgi)) {
foreach(QDomElement input, inputs) eti -> fromXml(input);
@@ -470,33 +439,6 @@ QDomElement Element::toXml(QDomDocument &document, QHash<Terminal *, int> &table
return(element);
}
/**
Methode statique sans rapport direct avec la manipulation des elements.
Etant donne un element XML e, elle renvoie la liste de tous les elements
children imbriques dans les elements parent, eux-memes enfants de l'elememt e
@param e Element XML a explorer
@param parent tag XML intermediaire
@param children tag XML a rechercher
@return La liste des elements XML children
*/
QList<QDomElement> Element::findInDomElement(QDomElement e, QString parent, QString children) {
// recense les champs de texte
QList<QDomElement> return_list;
// parcours des enfants de l'element
for (QDomNode enfant = e.firstChild() ; !enfant.isNull() ; enfant = enfant.nextSibling()) {
// on s'interesse a l'element XML "parent"
QDomElement parents = enfant.toElement();
if (parents.isNull() || parents.tagName() != parent) continue;
// parcours des enfants de l'element XML "parent"
for (QDomNode node_children = parents.firstChild() ; !node_children.isNull() ; node_children = node_children.nextSibling()) {
// on s'interesse a l'element XML "children"
QDomElement n_children = node_children.toElement();
if (!n_children.isNull() && n_children.tagName() == children) return_list.append(n_children);
}
}
return(return_list);
}
/// @return le Diagram auquel cet element appartient, ou 0 si cet element est independant
Diagram *Element::diagram() const {
return(qobject_cast<Diagram *>(scene()));

View File

@@ -61,7 +61,6 @@ class Element : public QGraphicsItem {
// methodes relatives a la position
void setPos(const QPointF &);
void setPos(qreal, qreal);
void moveOtherElements(const QPointF &);
// methodes relatives aux connexions internes
bool connexionsInternesAcceptees();
@@ -69,8 +68,8 @@ class Element : public QGraphicsItem {
// methodes relatives aux fichiers XML
static bool valideXml(QDomElement &);
virtual bool fromXml(QDomElement &, QHash<int, Terminal *>&);
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int>&) const;
virtual bool fromXml(QDomElement &, QHash<int, Terminal *> &);
virtual QDomElement toXml(QDomDocument &, QHash<Terminal *, int> &) const;
// methodes d'acces aux possibilites d'orientation
bool setOrientation(QET::Orientation o);
@@ -85,7 +84,6 @@ class Element : public QGraphicsItem {
bool peut_relier_ses_propres_terminals;
void drawSelection(QPainter *, const QStyleOptionGraphicsItem *);
void updatePixmap();
static QList<QDomElement> findInDomElement(QDomElement, QString, QString);
};
/**

View File

@@ -11,6 +11,8 @@ ElementTextItem::ElementTextItem(QGraphicsItem *parent, QGraphicsScene *scene) :
DiagramTextItem(parent, scene),
follow_parent_rotations(false)
{
setFlags(QGraphicsItem::ItemIsSelectable);
setTextInteractionFlags(Qt::TextEditorInteraction);
}
/**
@@ -23,6 +25,8 @@ ElementTextItem::ElementTextItem(const QString &text, QGraphicsItem *parent, QGr
DiagramTextItem(text, parent, scene),
follow_parent_rotations(false)
{
setFlags(QGraphicsItem::ItemIsSelectable);
setTextInteractionFlags(Qt::TextEditorInteraction);
}
/// Destructeur

36
qet.cpp
View File

@@ -130,16 +130,48 @@ bool QET::attributeIsAReal(const QDomElement &e, QString nom_attribut, double *r
@param conductors_count nombre de conducteurs
@return la proposition decrivant le nombre d'elements et de conducteurs
*/
QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count) {
QString QET::ElementsAndConductorsSentence(int elements_count, int conductors_count, int texts_count) {
QString text;
if (elements_count) {
text += QString::number(elements_count) + " ";
text += elements_count > 1 ? QObject::tr("\351l\351ments") : QObject::tr("\351l\351ment");
if (conductors_count) text += QObject::tr(" et ");
if (conductors_count ^ texts_count) text += QObject::tr(" et ");
else if (conductors_count && texts_count) text += QObject::tr(", ");
}
if (conductors_count) {
text += QString::number(conductors_count) + " ";
text += conductors_count > 1 ? QObject::tr("conducteurs") : QObject::tr("conducteur");
if (texts_count) text += QObject::tr(" et ");
}
if (texts_count) {
text += QString::number(texts_count) + " ";
text += texts_count > 1 ? QObject::tr("champs de texte") : QObject::tr("champ de texte");
}
return(text);
}
/**
Etant donne un element XML e, renvoie la liste de tous les elements
children imbriques dans les elements parent, eux-memes enfants de l'elememt e
@param e Element XML a explorer
@param parent tag XML intermediaire
@param children tag XML a rechercher
@return La liste des elements XML children
*/
QList<QDomElement> QET::findInDomElement(const QDomElement &e, const QString &parent, const QString &children) {
QList<QDomElement> return_list;
// parcours des elements parents
for (QDomNode enfant = e.firstChild() ; !enfant.isNull() ; enfant = enfant.nextSibling()) {
// on s'interesse a l'element XML "parent"
QDomElement parents = enfant.toElement();
if (parents.isNull() || parents.tagName() != parent) continue;
// parcours des enfants de l'element XML "parent"
for (QDomNode node_children = parents.firstChild() ; !node_children.isNull() ; node_children = node_children.nextSibling()) {
// on s'interesse a l'element XML "children"
QDomElement n_children = node_children.toElement();
if (!n_children.isNull() && n_children.tagName() == children) return_list.append(n_children);
}
}
return(return_list);
}

3
qet.h
View File

@@ -22,6 +22,7 @@ namespace QET {
bool estVerticale(QET::Orientation);
bool attributeIsAnInteger(const QDomElement &, QString , int * = NULL);
bool attributeIsAReal(const QDomElement &, QString , double * = NULL);
QString ElementsAndConductorsSentence(int, int);
QString ElementsAndConductorsSentence(int, int, int = 0);
QList<QDomElement> findInDomElement(const QDomElement &, const QString &, const QString &);
}
#endif

View File

@@ -40,9 +40,6 @@ QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) :
// si aucun schema n'a ete ouvert jusqu'a maintenant, on ouvre un nouveau schema
if (!diagram_views.size()) diagram_views << new DiagramView(this);
// ajout de tous les DiagramView necessaires
foreach (DiagramView *sv, diagram_views) addDiagramView(sv);
// titre de la fenetre
setWindowTitle(tr("QElectroTech"));
@@ -79,6 +76,9 @@ QETDiagramEditor::QETDiagramEditor(const QStringList &files, QWidget *parent) :
connect(&workspace, SIGNAL(windowActivated(QWidget *)), this, SLOT(slot_updateActions()));
connect(QApplication::clipboard(), SIGNAL(dataChanged()), this, SLOT(slot_updateActions()));
// ajout de tous les DiagramView necessaires
foreach (DiagramView *sv, diagram_views) addDiagramView(sv);
// affichage
show();
}
@@ -165,6 +165,7 @@ void QETDiagramEditor::actions() {
conductor_reset = new QAction(QIcon(":/ico/conductor2.png"), tr("R\351initialiser les conducteurs"), this);
conductor_default = new QAction(QIcon(":/ico/conductor3.png"), tr("Conducteurs par d\351faut"), this);
infos_diagram = new QAction(QIcon(":/ico/info.png"), tr("Propri\351t\351s du sch\351ma"), this);
add_text = new QAction(QIcon(":/ico/textfield.png"), tr("Ajouter un champ de texte"), this);
add_column = new QAction(QIcon(":/ico/add_col.png"), tr("Ajouter une colonne"), this);
remove_column = new QAction(QIcon(":/ico/remove_col.png"), tr("Enlever une colonne"), this);
expand_diagram = new QAction( tr("Agrandir le sch\351ma"), this);
@@ -279,6 +280,7 @@ void QETDiagramEditor::actions() {
about_qt -> setStatusTip(tr("Affiche des informations sur la biblioth\350que Qt"));
// traitements speciaux
add_text -> setCheckable(true);
mode_selection -> setCheckable(true);
mode_visualise -> setCheckable(true);
mode_selection -> setChecked(true);
@@ -324,6 +326,7 @@ void QETDiagramEditor::actions() {
connect(conductor_reset, SIGNAL(triggered()), this, SLOT(slot_resetConductors()) );
connect(conductor_default,SIGNAL(triggered()), this, SLOT(slot_editDefaultConductors()));
connect(infos_diagram, SIGNAL(triggered()), this, SLOT(slot_editInfos()) );
connect(add_text, SIGNAL(triggered()), this, SLOT(slot_addText()) );
connect(add_column, SIGNAL(triggered()), this, SLOT(slot_addColumn()) );
connect(remove_column, SIGNAL(triggered()), this, SLOT(slot_removeColumn()) );
connect(expand_diagram, SIGNAL(triggered()), this, SLOT(slot_expand()) );
@@ -464,6 +467,7 @@ void QETDiagramEditor::toolbar() {
view_bar -> addAction(zoom_reset);
diagram_bar -> addAction(infos_diagram);
diagram_bar -> addAction(add_text);
diagram_bar -> addAction(conductor_default);
diagram_bar -> addAction(conductor_prop);
diagram_bar -> addAction(conductor_reset);
@@ -707,6 +711,7 @@ void QETDiagramEditor::slot_updateActions() {
conductor_reset -> setEnabled(opened_document && selected_conductors_count);
conductor_default-> setEnabled(opened_document);
infos_diagram -> setEnabled(opened_document);
add_text -> setEnabled(opened_document);
add_column -> setEnabled(opened_document);
remove_column -> setEnabled(opened_document);
expand_diagram -> setEnabled(opened_document);
@@ -774,6 +779,7 @@ void QETDiagramEditor::addDiagramView(DiagramView *dv) {
QWidget *p = workspace.addWindow(dv);
connect(dv -> diagram(), SIGNAL(selectionChanged()), this, SLOT(slot_updateActions()));
connect(dv, SIGNAL(modeChanged()), this, SLOT(slot_updateActions()));
connect(dv, SIGNAL(textAdded(bool)), add_text, SLOT(setChecked(bool)));
// affiche la fenetre
if (maximise) p -> showMaximized();
@@ -893,6 +899,15 @@ void QETDiagramEditor::slot_resetConductors() {
*/
void QETDiagramEditor::slot_editDefaultConductors() {
if (DiagramView *dv = currentDiagram()) {
dv->editDefaultConductorProperties();
dv -> editDefaultConductorProperties();
}
}
/**
Ajoute un texte au schema courant
*/
void QETDiagramEditor::slot_addText() {
if (DiagramView *dv = currentDiagram()) {
dv -> addText();
}
}

View File

@@ -68,6 +68,7 @@ class QETDiagramEditor : public QMainWindow {
void slot_editConductor();
void slot_resetConductors();
void slot_editDefaultConductors();
void slot_addText();
// attributs
private:
@@ -97,6 +98,7 @@ class QETDiagramEditor : public QMainWindow {
QAction *conductor_reset;
QAction *conductor_default;
QAction *infos_diagram;
QAction *add_text;
QAction *add_column;
QAction *remove_column;
QAction *expand_diagram;