1 /*
2 Copyright 2006-2019 The QElectroTech Team
3 This file is part of QElectroTech.
4
5 QElectroTech is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 2 of the License, or
8 (at your option) any later version.
9
10 QElectroTech is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #ifndef DIAGRAM_H
19 #define DIAGRAM_H
20 #include <QtWidgets>
21 #include <QtXml>
22 #include <QHash>
23 #include "bordertitleblock.h"
24 #include "conductorproperties.h"
25 #include "exportproperties.h"
26 #include "qgimanager.h"
27 #include "numerotationcontext.h"
28 #include "qetproject.h"
29 #include "properties/xrefproperties.h"
30 #include "elementsmover.h"
31 #include "elementtextsmover.h"
32
33 class Conductor;
34 class CustomElement;
35 class DiagramContent;
36 class DiagramPosition;
37 class DiagramTextItem;
38 class Element;
39 class ElementsLocation;
40 class QETProject;
41 class Terminal;
42 class DiagramImageItem;
43 class DiagramEventInterface;
44
45 /**
46 This class represents an electric diagram. It manages its various child
47 elements, conductors and texts and handles their graphic rendering.
48 */
49 class Diagram : public QGraphicsScene
50 {
51 Q_OBJECT
52
53 // constructors, destructor
54 public:
55 Diagram(QETProject *project);
56 ~Diagram() override;
57 private:
58 Diagram(const Diagram &diagram);
59
60 // ATTRIBUTES
61 public:
62 /**
63 Represents available options when rendering a particular diagram:
64 * EmptyBorder: display border only
65 * TitleBlock: display title block
66 * Columns: display columns
67 */
68 enum BorderOptions { EmptyBorder, TitleBlock, Columns };
69 /// Represents available option of Numerotation type.
70 enum NumerotationType { Conductors };
71 /// Default properties for new conductors
72 ConductorProperties defaultConductorProperties;
73 /// Diagram dimensions and title block
74 BorderTitleBlock border_and_titleblock;
75 /// abscissa grid step size
76 static int xGrid;
77 /// ordinate grid step size
78 static int yGrid;
79 /// Key grid x step size
80 static int xKeyGrid;
81 /// Key grid y step size
82 static int yKeyGrid;
83 /// Key grid fine x step size
84 static int xKeyGridFine;
85 /// Key grid fine y step size
86 static int yKeyGridFine;
87 /// margin around the diagram
88 static const qreal margin;
89 /// background color of diagram
90
91 static QColor background_color;
92 /// Hash containing max values for folio sequential autonums in this diagram
93 QHash <QString, QStringList> m_elmt_unitfolio_max;
94 QHash <QString, QStringList> m_elmt_tenfolio_max;
95 QHash <QString, QStringList> m_elmt_hundredfolio_max;
96 /// Hash containing max values for folio sequential autonums in this diagram
97 QHash <QString, QStringList> m_cnd_unitfolio_max;
98 QHash <QString, QStringList> m_cnd_tenfolio_max;
99 QHash <QString, QStringList> m_cnd_hundredfolio_max;
100
101 private:
102 QGraphicsLineItem *conductor_setter_;
103 ElementsMover m_elements_mover;
104 ElementTextsMover m_element_texts_mover;
105 QGIManager *qgi_manager_;
106 QETProject *m_project;
107
108 QDomDocument xml_document_;
109
110 qreal diagram_qet_version_;
111
112 bool draw_grid_;
113 bool use_border_;
114 bool draw_terminals_;
115 bool draw_colored_conductors_;
116
117 QString m_conductors_autonum_name;
118 DiagramEventInterface *m_event_interface;
119
120 bool m_freeze_new_elements;
121 bool m_freeze_new_conductors_;
122
123 // METHODS
124 protected:
125 void drawBackground(QPainter *, const QRectF &) override;
126
127 void mouseDoubleClickEvent (QGraphicsSceneMouseEvent *event) override;
128 void mousePressEvent (QGraphicsSceneMouseEvent *event) override;
129 void mouseMoveEvent (QGraphicsSceneMouseEvent *event) override;
130 void mouseReleaseEvent (QGraphicsSceneMouseEvent *event) override;
131 void wheelEvent (QGraphicsSceneWheelEvent *event) override;
132 void keyPressEvent (QKeyEvent *event) override;
133 void keyReleaseEvent (QKeyEvent *) override;
134
135 public:
136 void setEventInterface (DiagramEventInterface *event_interface);
137 void clearEventInterface();
138
139 //methods related to autonum
140 QString conductorsAutonumName() const;
141 void setConductorsAutonumName(const QString &name);
142
143 static bool clipboardMayContainDiagram();
144
145 // methods related to parent project
146 QETProject *project() const;
147 void setProject(QETProject *);
148 int folioIndex() const;
149 qreal declaredQElectroTechVersion(bool = true) const;
showMe()150 void showMe() {emit showDiagram(this);}
151 bool isReadOnly() const;
152
153 // methods related to conductor creation
154 void setConductor(bool);
155 void setConductorStart (QPointF);
156 void setConductorStop(QPointF);
157 QList < QSet <Conductor *> > potentials();
158
159 // methods related to XML import/export
160 QDomDocument toXml(bool = true);
161 bool initFromXml(QDomElement &, QPointF = QPointF(), bool = true, DiagramContent * = nullptr);
162 bool fromXml(QDomDocument &, QPointF = QPointF(), bool = true, DiagramContent * = nullptr);
163 bool fromXml(QDomElement &, QPointF = QPointF(), bool = true, DiagramContent * = nullptr);
164 void folioSequentialsToXml(QHash<QString, QStringList>*, QDomElement *, const QString&, const QString&, QDomDocument *);
165 void folioSequentialsFromXml(const QDomElement&, QHash<QString, QStringList>*, const QString&, const QString&, const QString&, const QString&);
166
167 void refreshContents();
168
169 // methods related to graphics items addition/removal on the diagram
170 virtual void addItem (QGraphicsItem *item);
171 virtual void removeItem (QGraphicsItem *item);
172
173 // methods related to graphics options
174 ExportProperties applyProperties(const ExportProperties &);
175 void setDisplayGrid(bool);
176 bool displayGrid();
177 void setUseBorder(bool);
178 bool useBorder();
179 void setBorderOptions(BorderOptions);
180 BorderOptions borderOptions();
181 DiagramPosition convertPosition(const QPointF &);
182 static QPointF snapToGrid(const QPointF &p);
183
184 bool drawTerminals() const;
185 void setDrawTerminals(bool);
186 bool drawColoredConductors() const;
187 void setDrawColoredConductors(bool);
188
189 QString title() const;
190 bool toPaintDevice(QPaintDevice &, int = -1, int = -1, Qt::AspectRatioMode = Qt::KeepAspectRatio);
191 QSize imageSize() const;
192
193 bool isEmpty() const;
194
195 QList<Element *> elements() const;
196 QList<Conductor *> conductors() const;
197 QSet<Conductor *> selectedConductors() const;
198 DiagramContent content() const;
199 bool canRotateSelection() const;
200 ElementsMover &elementsMover();
201 ElementTextsMover &elementTextsMover();
202 bool usesElement(const ElementsLocation &);
203 bool usesTitleBlockTemplate(const QString &);
204
205 QUndoStack &undoStack();
206 QGIManager &qgiManager();
207
208 //methods related to element label Update Policy
209 void freezeElements(bool freeze);
210 void unfreezeElements();
211 void setFreezeNewElements(bool);
212 bool freezeNewElements();
213
214 //methods related to conductor label Update Policy
215 void freezeConductors(bool freeze);
216 void setFreezeNewConductors(bool);
217 bool freezeNewConductors();
218
219 //methods related to insertion and loading of folio sequential
220 void insertFolioSeqHash (QHash<QString, QStringList> *hash, const QString& title, const QString& seq, NumerotationContext *nc);
221 void loadFolioSeqHash (QHash<QString, QStringList> *hash, const QString& title, const QString& seq, NumerotationContext *nc);
222 void changeZValue(QET::DepthOption option);
223
224 public slots:
225 void adjustSceneRect ();
226 void titleChanged(const QString &);
227 void titleBlockTemplateChanged(const QString &);
228 void titleBlockTemplateRemoved(const QString &, const QString & = QString());
229 void setTitleBlockTemplate(const QString &);
230 void updateLabels();
231 void loadElmtFolioSeq();
232 void loadCndFolioSeq();
233
234 // methods related to graphics items selection
235 void selectAll();
236 void deselectAll();
237 void invertSelection();
238
239 signals:
240 void showDiagram (Diagram *);
241 void usedTitleBlockTemplateChanged(const QString &);
242 void diagramTitleChanged(Diagram *, const QString &);
243 void findElementRequired(const ElementsLocation &); /// Signal emitted when users wish to locate an element from the diagram within elements collection
244 void editElementRequired(const ElementsLocation &); /// Signal emitted when users wish to edit an element from the diagram
245 void diagramActivated();
246 };
Q_DECLARE_METATYPE(Diagram *)247 Q_DECLARE_METATYPE(Diagram *)
248
249 /**
250 Display or hide the conductor setter, i.e. a dashed conductor stub which appears when creating a conductor between two terminals.
251 @param pf true pour ajouter le poseur de conducteur, false pour l'enlever
252 */
253 inline void Diagram::setConductor(bool adding) {
254 if (adding) {
255 if (!conductor_setter_ -> scene()) addItem(conductor_setter_);
256 } else {
257 if (conductor_setter_ -> scene()) removeItem(conductor_setter_);
258 }
259 }
260
261 /**
262 Set the start point of the conductor setter.
263 @param start the point (in scene coordinates) which the newly created
264 conductor should start from.
265 */
setConductorStart(QPointF start)266 inline void Diagram::setConductorStart(QPointF start) {
267 conductor_setter_ -> setLine(QLineF(start, conductor_setter_ -> line().p2()));
268 }
269
270 /**
271 Set the end point of the conductor setter.
272 @param end the point (in scene coordinates) upon to which the newly created
273 conductor should be drawn.
274 */
setConductorStop(QPointF end)275 inline void Diagram::setConductorStop(QPointF end) {
276 conductor_setter_ -> setLine(QLineF(conductor_setter_ -> line().p1(), end));
277 }
278
279 /**
280 Set whether the diagram grid should be drawn.
281 @param dg true to render the grid, false otherwise.
282 */
setDisplayGrid(bool dg)283 inline void Diagram::setDisplayGrid(bool dg) {
284 draw_grid_ = dg;
285 }
286
287 /**
288 @return true if the grid is drawn, false otherwise.
289 */
displayGrid()290 inline bool Diagram::displayGrid() {
291 return(draw_grid_);
292 }
293
294 /**
295 Set whether the diagram border (including rows/colums headers and the title
296 block) should be rendered along with the diagram. When set to false, the size
297 of the smallest rectangle containing all items is considered as the diagram
298 size.
299 @param ub true to take the border into account, false otherwise
300 */
setUseBorder(bool ub)301 inline void Diagram::setUseBorder(bool ub) {
302 use_border_ = ub;
303 }
304
305 /**
306 @return true if the border is rendered and take into account, false
307 otherwise.
308 */
useBorder()309 inline bool Diagram::useBorder() {
310 return(use_border_);
311 }
312
313 /**
314 Set the rendering options for the diagram border (including rows/colums
315 headers and the title block)
316 @param bo Enabled options ORed together
317 @see BorderOptions
318 */
setBorderOptions(Diagram::BorderOptions bo)319 inline void Diagram::setBorderOptions(Diagram::BorderOptions bo) {
320 border_and_titleblock.displayBorder(!(bo & EmptyBorder));
321 border_and_titleblock.displayColumns(bo & Columns);
322 border_and_titleblock.displayTitleBlock(bo & TitleBlock);
323 }
324
325 /**
326 @return The rendering optios for the diagram border
327 @see setBorderOptions
328 */
borderOptions()329 inline Diagram::BorderOptions Diagram::borderOptions() {
330 BorderOptions options = EmptyBorder;
331 if (border_and_titleblock.titleBlockIsDisplayed()) options = (BorderOptions)(options|TitleBlock);
332 if (border_and_titleblock.columnsAreDisplayed()) options = (BorderOptions)(options|Columns);
333 return(options);
334 }
335
336 /// @return the diagram undo stack
undoStack()337 inline QUndoStack &Diagram::undoStack() {
338 return *(project()->undoStack());
339 }
340
341 /// @return the diagram graphics item manager
qgiManager()342 inline QGIManager &Diagram::qgiManager() {
343 return(*qgi_manager_);
344 }
345
346 /// @return true if terminals are rendered, false otherwise
drawTerminals()347 inline bool Diagram::drawTerminals() const {
348 return(draw_terminals_);
349 }
350
351 /// @return true if conductors colors are rendered, false otherwise.
drawColoredConductors()352 inline bool Diagram::drawColoredConductors() const {
353 return(draw_colored_conductors_);
354 }
355
356 #endif
357