/* Copyright 2006-2009 Xavier Guerrin This file is part of QElectroTech. QElectroTech is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. QElectroTech is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QElectroTech. If not, see . */ #ifndef SCHEMA_H #define SCHEMA_H #include #include #include "borderinset.h" #include "qgimanager.h" #include "conductorproperties.h" class Element; class CustomElement; class Terminal; class Conductor; class DiagramTextItem; class DiagramContent; class QETProject; class ElementsLocation; /** Cette classe represente un schema electrique. Elle gere les differents elements et conducteurs qui le composent et en effectue le rendu graphique. */ class Diagram : public QGraphicsScene { Q_OBJECT // constructeurs, destructeur public: Diagram(QObject * = 0); virtual ~Diagram(); private: Diagram(const Diagram &diagram); // attributs public: /** Represente les options possibles pour l'affichage du schema : * EmptyBorder : N'afficher que la bordure * Inset : Afficher le cartouche * Columns : Afficher les colonnes */ enum BorderOptions { EmptyBorder, Inset, Columns }; /// Proprietes par defaut des nouveaux conducteurs ConductorProperties defaultConductorProperties; /// Dimensions et cartouches du schema BorderInset border_and_inset; /// Mouvement en cours lors d'un deplacement d'elements et conducteurs QPointF current_movement; /// taille de la grille en abscisse static const int xGrid; /// taille de la grille en ordonnee static const int yGrid; /// marge autour du schema static const qreal margin; private: QGraphicsLineItem *conductor_setter; bool draw_grid; bool use_border; bool moved_elements_fetched; QSet elements_to_move; QSet conductors_to_move; QHash conductors_to_update; QSet texts_to_move; QGIManager *qgi_manager; QUndoStack *undo_stack; bool draw_terminals; QDomDocument xml_document; QETProject *project_; bool read_only_; // methodes protected: virtual void drawBackground(QPainter *, const QRectF &); virtual void keyPressEvent(QKeyEvent *); virtual void keyReleaseEvent(QKeyEvent *); public: static bool clipboardMayContainDiagram(); // fonctions relatives au projet parent QETProject *project() const; void setProject(QETProject *); // fonctions relatives a la lecture seule bool isReadOnly() const; void setReadOnly(bool); // fonctions relatives a la pose de conducteurs void setConductor(bool); void setConductorStart (QPointF); void setConductorStop(QPointF); // fonctions relatives a l'import / export XML QDomDocument toXml(bool = true); bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, DiagramContent * = NULL); bool fromXml(QDomElement &, QPointF = QPointF(), bool = true, DiagramContent * = NULL); void write(); void write(const QDomElement &); bool wasWritten() const; QDomElement writeXml(QDomDocument &) const; // fonctions relative a l'ajout et a l'enlevement d'elements graphiques sur le schema void addElement(Element *); void addConductor(Conductor *); void addDiagramTextItem(DiagramTextItem *); void removeElement(Element *); void removeConductor(Conductor *); void removeDiagramTextItem(DiagramTextItem *); // fonctions relatives aux options graphiques void setDisplayGrid(bool); bool displayGrid(); void setUseBorder(bool); bool useBorder(); void setBorderOptions(BorderOptions); BorderOptions borderOptions(); bool drawTerminals() const; void setDrawTerminals(bool); QRectF border() const; QString title() const; bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio); QSize imageSize() const; bool isEmpty() const; QList customElements() const; void invalidateMovedElements(); void fetchMovedElements(); const QSet &elementsToMove(); const QSet &conductorsToMove(); const QHash &conductorsToUpdate(); const QSet &textsToMove(); QSet selectedConductors() const; DiagramContent content() const; DiagramContent selectedContent(); void moveElements(const QPointF &, QGraphicsItem * = NULL); bool usesElement(const ElementsLocation &); QUndoStack &undoStack(); QGIManager &qgiManager(); public slots: void diagramTextChanged(DiagramTextItem *, const QString &, const QString &); private slots: void slot_checkSelectionEmptinessChange(); signals: /** Ce signal est emis lorsque la selection passe de l'etat rempli (par un nombre quelconque d'elements et conducteurs) a l'etat vide et vice-versa. */ void selectionEmptinessChanged(); void written(); void readOnlyChanged(bool); }; /** Permet d'ajouter ou enlever le « poseur de conducteur », c'est-a-dire la droite en pointilles qui apparait lorsqu'on pose un conducteur entre deux bornes. @param pf true pour ajouter le poseur de conducteur, false pour l'enlever */ inline void Diagram::setConductor(bool pf) { if (pf) { if (!conductor_setter -> scene()) addItem(conductor_setter); } else { if (conductor_setter -> scene()) removeItem(conductor_setter); } } /** Specifie les coordonnees du point de depart du poseur de conducteur @param d Le nouveau point de depart du poseur de conducteur */ inline void Diagram::setConductorStart(QPointF d) { conductor_setter -> setLine(QLineF(d, conductor_setter -> line().p2())); } /** Specifie les coordonnees du point d'arrivee du poseur de conducteur @param a Le nouveau point d'arrivee du poseur de conducteur */ inline void Diagram::setConductorStop(QPointF a) { conductor_setter -> setLine(QLineF(conductor_setter -> line().p1(), a)); } /** Permet de specifier si la grille du schema doit etre dessinee ou non @param dg true pour afficher la grille, false pour ne pas l'afficher */ inline void Diagram::setDisplayGrid(bool dg) { draw_grid = dg; } /** Permet de savoir si la grille du schema est dessinee ou non @return true si la grille est affichee , false sinon */ inline bool Diagram::displayGrid() { return(draw_grid); } /** Permet de specifier si le cadre du schema doit etre pris en compte pour determiner le contour du schema. @param ub true pour prendre le schema en compte, false sinon */ inline void Diagram::setUseBorder(bool ub) { use_border = ub; } /** Permet de savoir si le cadre du schema est pris en compte pour determiner le contour du schema. */ inline bool Diagram::useBorder() { return(use_border); } /** Permet de definir les options du cadre, des colonnes et du cartouche. @param bo Un OU binaire entre les options possibles @see BorderOptions */ inline void Diagram::setBorderOptions(Diagram::BorderOptions bo) { border_and_inset.displayBorder(!(bo & EmptyBorder)); border_and_inset.displayColumns(bo & Columns); border_and_inset.displayInset(bo & Inset); } /** Permet de savoir les options du cadre, des colonnes et du cartouche. @return Un OU binaire entre les options possibles @see BorderOptions */ inline Diagram::BorderOptions Diagram::borderOptions() { BorderOptions retour = EmptyBorder; if (border_and_inset.insetIsDisplayed()) retour = (BorderOptions)(retour|Inset); if (border_and_inset.columnsAreDisplayed()) retour = (BorderOptions)(retour|Columns); return(retour); } /// @return la liste des elements a deplacer inline const QSet &Diagram::elementsToMove() { if (!moved_elements_fetched) fetchMovedElements(); return(elements_to_move); } /// @return la liste des conducteurs a deplacer inline const QSet &Diagram::conductorsToMove() { if (!moved_elements_fetched) fetchMovedElements(); return(conductors_to_move); } /// @return la liste des conducteurs a modifier (typiquement les conducteurs dont seul un element est deplace) inline const QHash &Diagram::conductorsToUpdate() { if (!moved_elements_fetched) fetchMovedElements(); return(conductors_to_update); } /// @return la liste des textes a deplacer inline const QSet &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); } /// @return le egstionnaire de QGraphicsItem de ce schema inline QGIManager &Diagram::qgiManager() { return(*qgi_manager); } /// @return true si les bornes sont affichees, false sinon inline bool Diagram::drawTerminals() const { return(draw_terminals); } #endif