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 #include "exportdialog.h"
19 #include <QSvgGenerator>
20 #include <cmath>
21 #include <QtXml>
22 #include <utility>
23 #include "qeticons.h"
24 #include "qetmessagebox.h"
25 #include "exportpropertieswidget.h"
26 #include "createdxf.h"
27 #include "conductorsegment.h"
28 #include "qetgraphicsitem/conductor.h"
29 #include "qetgraphicsitem/diagramtextitem.h"
30 #include "qetgraphicsitem/conductortextitem.h"
31 #include "qetgraphicsitem/independenttextitem.h"
32 #include "qetgraphicsitem/diagramimageitem.h"
33 #include "qetgraphicsitem/qetshapeitem.h"
34 #include "diagramfoliolist.h"
35 #include "elementpicturefactory.h"
36 #include "element.h"
37 #include "dynamicelementtextitem.h"
38
39 #include <QGraphicsSimpleTextItem>
40
41 /**
42 Constructeur
43 @param project Le projet a exporter
44 @param parent Le Widget parent de ce dialogue
45 */
ExportDialog(QETProject * project,QWidget * parent)46 ExportDialog::ExportDialog(QETProject *project, QWidget *parent) : QDialog(parent) {
47 if (!project) return;
48
49 // recupere le projet a exporter
50 project_ = project;
51
52 // recupere les parametres d'export definis dans la configuration de l'application
53 ExportProperties default_export_properties = ExportProperties::defaultExportProperties();
54
55 // on utilise le repertoire du projet a exporter si possible
56 if (!project_ -> filePath().isEmpty()) {
57 default_export_properties.destination_directory = project_ -> currentDir();
58 }
59
60 // la taille minimale du dialogue est fixee
61 setMinimumSize(800, 590);
62 resize(minimumSize());
63 setWindowTitle(tr("Exporter les folios du projet", "window title"));
64
65 // options d'export, dans le widget epw
66 epw = new ExportPropertiesWidget(default_export_properties);
67
68 // le dialogue comporte deux boutons
69 buttons = new QDialogButtonBox(this);
70 buttons -> setOrientation(Qt::Horizontal);
71 buttons -> setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Save);
72 QPushButton *export_button = buttons -> button(QDialogButtonBox::Save);
73 export_button -> setText(tr("Exporter"));
74
75 // disposition des elements
76
77 QHBoxLayout *hLayout = new QHBoxLayout();
78 hLayout -> addWidget(new QLabel(tr("Choisissez les folios que vous désirez exporter ainsi que leurs dimensions :")));
79 selectAll = new QPushButton();
80 deSelectAll = new QPushButton();
81 selectAll -> setText(tr("Tout cocher"));
82 deSelectAll -> setText(tr("Tout décocher"));
83 hLayout -> addWidget(selectAll);
84 hLayout -> addWidget(deSelectAll);
85 connect(selectAll, SIGNAL(clicked()), this, SLOT(slot_selectAllClicked()));
86 connect(deSelectAll, SIGNAL(clicked()), this, SLOT(slot_deSelectAllClicked()));
87
88
89 QVBoxLayout *layout = new QVBoxLayout(this);
90 layout -> addLayout(hLayout);
91 layout -> addWidget(initDiagramsListPart(), 1);
92 layout -> addWidget(epw);
93 layout -> addWidget(buttons);
94
95 // connexions signaux/slots
96 connect(epw, SIGNAL(formatChanged()), this, SLOT(slot_changeFilesExtension()));
97 connect(epw, SIGNAL(exportedAreaChanged()), this, SLOT(slot_changeUseBorder()));
98 connect(buttons, SIGNAL(accepted()), this, SLOT(slot_export()));
99 connect(buttons, SIGNAL(rejected()), this, SLOT(reject()));
100
101 // ajustement des extensions des fichiers
102 slot_changeFilesExtension(true);
103 }
104
105 /**
106 Destructeur - ne fait rien
107 */
~ExportDialog()108 ExportDialog::~ExportDialog() {
109 }
110
111 /**
112 @return le nombre de schemas coches (donc a exporter)
113 */
diagramsToExportCount() const114 int ExportDialog::diagramsToExportCount() const {
115 int checked_diagrams_count = 0;
116 foreach(ExportDiagramLine *diagram_line, diagram_lines_.values()) {
117 if (diagram_line -> must_export -> isChecked()) ++ checked_diagrams_count;
118 }
119 return(checked_diagrams_count);
120 }
121
122 /**
123 Met en place la liste des schemas
124 @return Le widget representant la liste des schemas
125 */
initDiagramsListPart()126 QWidget *ExportDialog::initDiagramsListPart() {
127 preview_mapper_ = new QSignalMapper(this);
128 width_mapper_ = new QSignalMapper(this);
129 height_mapper_ = new QSignalMapper(this);
130 ratio_mapper_ = new QSignalMapper(this);
131 reset_mapper_ = new QSignalMapper(this);
132 clipboard_mapper_ = new QSignalMapper(this);
133
134 connect(preview_mapper_, SIGNAL(mapped(int)), this, SLOT(slot_previewDiagram(int)));
135 connect(width_mapper_, SIGNAL(mapped(int)), this, SLOT(slot_correctHeight(int)));
136 connect(height_mapper_, SIGNAL(mapped(int)), this, SLOT(slot_correctWidth(int)));
137 connect(ratio_mapper_, SIGNAL(mapped(int)), this, SLOT(slot_keepRatioChanged(int)));
138 connect(reset_mapper_, SIGNAL(mapped(int)), this, SLOT(slot_resetSize(int)));
139 connect(clipboard_mapper_, SIGNAL(mapped(int)), this, SLOT(slot_exportToClipBoard(int)));
140
141 diagrams_list_layout_ = new QGridLayout();
142
143 int line_count = 0;
144 diagrams_list_layout_ -> addWidget(new QLabel(tr("Titre du folio")), line_count, 1, Qt::AlignHCenter | Qt::AlignVCenter);
145 diagrams_list_layout_ -> addWidget(new QLabel(tr("Nom de fichier")), line_count, 2, Qt::AlignHCenter | Qt::AlignVCenter);
146 diagrams_list_layout_ -> addWidget(new QLabel(tr("Dimensions")), line_count, 3, Qt::AlignHCenter | Qt::AlignVCenter);
147
148 // remplit la liste
149 foreach (Diagram *diagram, project_ -> diagrams()) {
150 ++ line_count;
151 ExportDiagramLine *diagram_line = new ExportDiagramLine(diagram, diagramSize(diagram));
152 diagram_lines_.insert(line_count, diagram_line);
153 diagrams_list_layout_ -> addWidget(diagram_line -> must_export, line_count, 0);
154 diagrams_list_layout_ -> addWidget(diagram_line -> title_label, line_count, 1);
155 diagrams_list_layout_ -> addWidget(diagram_line -> file_name, line_count, 2);
156 diagrams_list_layout_ -> addLayout(diagram_line -> sizeLayout(), line_count, 3);
157
158 // si on decoche tous les schemas, on desactive le bouton "Exporter"
159 connect(diagram_line -> must_export, SIGNAL(toggled(bool)), this, SLOT(slot_checkDiagramsCount()));
160
161 // mappings et signaux pour la gestion des dimensions du schema
162 width_mapper_ -> setMapping(diagram_line -> width, line_count);
163 height_mapper_ -> setMapping(diagram_line -> height, line_count);
164 ratio_mapper_ -> setMapping(diagram_line -> keep_ratio, line_count);
165 reset_mapper_ -> setMapping(diagram_line -> reset_size, line_count);
166 connect(diagram_line -> width, SIGNAL(valueChanged(int)), width_mapper_, SLOT(map()));
167 connect(diagram_line -> height, SIGNAL(valueChanged(int)), height_mapper_, SLOT(map()));
168 connect(diagram_line -> keep_ratio, SIGNAL(toggled(bool)), ratio_mapper_, SLOT(map()));
169 connect(diagram_line -> reset_size, SIGNAL(clicked(bool)), reset_mapper_, SLOT(map()));
170
171 // mappings et signaux pour l'apercu du schema
172 preview_mapper_ -> setMapping(diagram_line -> preview, line_count);
173 connect(diagram_line -> preview, SIGNAL(clicked(bool)), preview_mapper_, SLOT(map()));
174
175 // mappings et signaux pour l'export du schema vers le presse-papier
176 clipboard_mapper_ -> setMapping(diagram_line -> clipboard, line_count);
177 connect(diagram_line -> clipboard, SIGNAL(clicked(bool)), clipboard_mapper_, SLOT(map()));
178 }
179
180 QWidget *widget_diagrams_list = new QWidget();
181 widget_diagrams_list -> setLayout(diagrams_list_layout_);
182
183 QScrollArea *scroll_diagrams_list = new QScrollArea();
184 scroll_diagrams_list -> setWidget(widget_diagrams_list);
185
186 return(scroll_diagrams_list);
187 }
188
slot_selectAllClicked()189 void ExportDialog::slot_selectAllClicked() {
190 foreach (ExportDiagramLine *diagramLine, diagram_lines_) {
191 diagramLine -> must_export -> setChecked(true);
192 }
193 }
194
slot_deSelectAllClicked()195 void ExportDialog::slot_deSelectAllClicked() {
196 foreach (ExportDiagramLine *diagramLine, diagram_lines_) {
197 diagramLine -> must_export -> setChecked(false);
198 }
199 }
200
201
202
203 /**
204 @param diagram Un schema
205 @return le rapport largeur / hauteur du schema
206 */
diagramRatio(Diagram * diagram)207 qreal ExportDialog::diagramRatio(Diagram *diagram) {
208 QSize diagram_size = diagramSize(diagram);
209 qreal diagram_ratio = (qreal)diagram_size.width() / (qreal)diagram_size.height();
210 return(diagram_ratio);
211 }
212
213 /**
214 @param diagram Un schema
215 @return les dimensions du schema, en tenant compte du type d'export : cadre
216 ou elements
217 */
diagramSize(Diagram * diagram)218 QSize ExportDialog::diagramSize(Diagram *diagram) {
219 // sauvegarde le parametre useBorder du schema
220 bool state_useBorder = diagram -> useBorder();
221
222 // applique le useBorder adequat et calcule le ratio
223 diagram -> setUseBorder(epw -> exportProperties().exported_area == QET::BorderArea);
224 QSize diagram_size = diagram -> imageSize();
225
226 // restaure le parametre useBorder du schema
227 diagram -> setUseBorder(state_useBorder);
228
229 return(diagram_size);
230 }
231
232 /**
233 Cette methode ajuste la largeur d'un des schemas a exporter en fonction de
234 sa hauteur si et seulement si l'option "Conserver les proportions" est
235 activee pour ce schema.
236 @param diagram_id numero du schema concerne
237 */
slot_correctWidth(int diagram_id)238 void ExportDialog::slot_correctWidth(int diagram_id) {
239 // recupere l'ExportDiagramLine concernee
240 ExportDialog::ExportDiagramLine *current_diagram = diagram_lines_[diagram_id];
241 if (!current_diagram) return;
242
243 // ne fait rien si l'option "Conserver les proportions" n'est pas activee
244 if (!(current_diagram -> keep_ratio -> isChecked())) return;
245
246 // recupere les proportions du schema
247 qreal diagram_ratio = diagramRatio(current_diagram -> diagram);
248
249 // ajuste la largeur
250 current_diagram -> width -> blockSignals(true);
251 current_diagram -> width -> setValue(qRound(current_diagram -> height -> value() * diagram_ratio));
252 current_diagram -> width -> blockSignals(false);
253 }
254
255 /**
256 Cette methode ajuste la hauteur d'un des schemas a exporter en fonction de
257 sa largeur si et seulement si l'option "Conserver les proportions" est
258 activee pour ce schema.
259 @param diagram_id numero du schema concerne
260 */
slot_correctHeight(int diagram_id)261 void ExportDialog::slot_correctHeight(int diagram_id) {
262 // recupere l'ExportDiagramLine concernee
263 ExportDialog::ExportDiagramLine *current_diagram = diagram_lines_[diagram_id];
264 if (!current_diagram) return;
265
266 // ne fait rien si l'option "Conserver les proportions" n'est pas activee
267 if (!(current_diagram -> keep_ratio -> isChecked())) return;
268
269 // recupere les proportions du schema
270 qreal diagram_ratio = diagramRatio(current_diagram -> diagram);
271
272 // ajuste la hauteur
273 current_diagram -> height -> blockSignals(true);
274 current_diagram -> height -> setValue(qRound(current_diagram -> width -> value() / diagram_ratio));
275 current_diagram -> height -> blockSignals(false);
276 }
277
278 /**
279 Prend en compte le fait qu'il faut desormais conserver ou non les
280 proportions d'un des schemas
281 @param diagram_id numero du schema concerne
282 */
slot_keepRatioChanged(int diagram_id)283 void ExportDialog::slot_keepRatioChanged(int diagram_id) {
284 // recupere l'ExportDiagramLine concernee
285 ExportDialog::ExportDiagramLine *current_diagram = diagram_lines_[diagram_id];
286 if (!current_diagram) return;
287
288 // gere l'icone du bouton "Conserver les proportions"
289 if (current_diagram -> keep_ratio -> isChecked()) {
290 current_diagram -> keep_ratio -> setIcon(QET::Icons::ObjectLocked);
291 } else {
292 current_diagram -> keep_ratio -> setIcon(QET::Icons::ObjectUnlocked);
293 }
294
295 // ne fait rien si l'option "Conserver les proportions" n'est pas activee
296 if (!(current_diagram -> keep_ratio -> isChecked())) return;
297
298 // au contraire, si elle est activee, ajuste la hauteur en fonction de la largeur
299 slot_correctHeight(diagram_id);
300 }
301
302 /**
303 Reinitialise les dimensions d'un des schemas
304 @param diagram_id numero du schema concerne
305 */
slot_resetSize(int diagram_id)306 void ExportDialog::slot_resetSize(int diagram_id) {
307 // recupere l'ExportDiagramLine concernee
308 ExportDialog::ExportDiagramLine *current_diagram = diagram_lines_[diagram_id];
309 if (!current_diagram) return;
310
311 // recupere la taille du schema
312 QSize diagram_size = diagramSize(current_diagram -> diagram);
313
314 // reinitialise les champs largeur et hauteur
315 current_diagram -> width -> blockSignals(true);
316 current_diagram -> height -> blockSignals(true);
317 current_diagram -> width -> setValue(diagram_size.width());
318 current_diagram -> height -> setValue(diagram_size.height());
319 current_diagram -> width -> blockSignals(false);
320 current_diagram -> height -> blockSignals(false);
321 }
322
323 /**
324 Genere l'image a exporter
325 @param diagram Schema a exporter en SVG
326 @param width Largeur de l'export
327 @param height Hauteur de l'export
328 @param keep_aspect_ratio True pour conserver le ratio, false sinon
329 @return l'image a exporter
330 */
generateImage(Diagram * diagram,int width,int height,bool keep_aspect_ratio)331 QImage ExportDialog::generateImage(Diagram *diagram, int width, int height, bool keep_aspect_ratio) {
332 saveReloadDiagramParameters(diagram, true);
333
334 QImage image(width, height, QImage::Format_RGB32);
335 diagram -> toPaintDevice(
336 image,
337 width,
338 height,
339 keep_aspect_ratio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio
340 );
341
342 saveReloadDiagramParameters(diagram, false);
343
344 return(image);
345 }
346
347 /**
348 Sauve ou restaure les parametres du schema
349 @param diagram Schema dont on sauve ou restaure les parametres
350 @param save true pour memoriser les parametres du schema et appliquer ceux
351 definis par le formulaire, false pour restaurer les parametres
352 */
saveReloadDiagramParameters(Diagram * diagram,bool save)353 void ExportDialog::saveReloadDiagramParameters(Diagram *diagram, bool save) {
354 static ExportProperties state_exportProperties;
355
356 if (save) {
357 // memorise les parametres relatifs au schema tout en appliquant les nouveaux
358 state_exportProperties = diagram -> applyProperties(epw -> exportProperties());
359 } else {
360 // restaure les parametres relatifs au schema
361 diagram -> applyProperties(state_exportProperties);
362 }
363 }
364
365 /**
366 Exporte le schema en SVG
367 @param diagram Schema a exporter en SVG
368 @param width Largeur de l'export SVG
369 @param height Hauteur de l'export SVG
370 @param keep_aspect_ratio True pour conserver le ratio, false sinon
371 @param io_device Peripherique de sortie pour le code SVG (souvent : un fichier)
372 */
generateSvg(Diagram * diagram,int width,int height,bool keep_aspect_ratio,QIODevice & io_device)373 void ExportDialog::generateSvg(Diagram *diagram, int width, int height, bool keep_aspect_ratio, QIODevice &io_device) {
374 saveReloadDiagramParameters(diagram, true);
375
376 // genere une QPicture a partir du schema
377 QPicture picture;
378 diagram -> toPaintDevice(
379 picture,
380 width,
381 height,
382 keep_aspect_ratio ? Qt::KeepAspectRatio : Qt::IgnoreAspectRatio
383 );
384
385 // "joue" la QPicture sur un QSvgGenerator
386 QSvgGenerator svg_engine;
387 svg_engine.setSize(QSize(width, height));
388 svg_engine.setOutputDevice(&io_device);
389 QPainter svg_painter(&svg_engine);
390 picture.play(&svg_painter);
391
392 saveReloadDiagramParameters(diagram, false);
393 }
394
395 /**
396 Exporte le schema en DXF
397 @param diagram Schema a exporter en DXF
398 @param width Largeur de l'export DXF
399 @param height Hauteur de l'export DXF
400 @param keep_aspect_ratio True pour conserver le ratio, false sinon
401 @param io_device Peripherique de sortie pour le code DXF (souvent : un fichier)
402 */
generateDxf(Diagram * diagram,int width,int height,bool keep_aspect_ratio,QString & file_path)403 void ExportDialog::generateDxf(Diagram *diagram, int width, int height, bool keep_aspect_ratio, QString &file_path) {
404 saveReloadDiagramParameters(diagram, true);
405
406 width -= 2*Diagram::margin;
407 height -= 2*Diagram::margin;
408
409 Createdxf::xScale = Createdxf::sheetWidth / double(width);
410 Createdxf::yScale = Createdxf::sheetHeight / double(height);
411
412 Createdxf::dxfBegin(file_path);
413
414 //Add project elements (lines, rectangles, circles, texts) to dxf file
415 if (epw -> exportProperties().draw_border) {
416 Createdxf::drawRectangle(file_path, 0, 0, double(width)*Createdxf::xScale, double(height)*Createdxf::yScale, 0);
417 }
418 diagram -> border_and_titleblock.drawDxf(width, height, keep_aspect_ratio, file_path, 0);
419
420 // Build the lists of elements.
421 QList<Element *> list_elements;
422 QList<Conductor *> list_conductors;
423 QList<DiagramTextItem *> list_texts;
424 QList<DiagramImageItem *> list_images;
425 QList<QLineF *> list_lines;
426 QList<QRectF *> list_rectangles;
427 //QList<QRectF *> list_ellipses;
428 QList <QetShapeItem *> list_shapes;
429
430 DiagramFolioList *ptr = dynamic_cast<DiagramFolioList *>(diagram);
431 if (ptr) {
432 list_lines = ptr -> lines();
433 list_rectangles = ptr -> rectangles();
434 QSettings settings;
435
436 // fill the rows with text.
437 QString authorTranslatable = tr("Auteur");
438 QString titleTranslatable = tr("Titre");
439 QString folioTranslatable = tr("Folio");
440 QString dateTranslatable = tr("Date");
441
442 qreal x0 = list_rectangles[0] -> topLeft().x();
443 qreal y0 = list_rectangles[0] -> topLeft().y();
444 qreal rowHeight = (list_rectangles[0] -> height())/30;
445 QRectF row_RectF(x0, y0, list_rectangles[0] -> width(), rowHeight);
446
447 fillRow(file_path, row_RectF, authorTranslatable, titleTranslatable, folioTranslatable, dateTranslatable);
448 QList<Diagram *> diagram_list = ptr -> project() -> diagrams();
449
450 int startDiagram = (ptr -> getId()) *29;
451
452 for (int i = startDiagram; i < startDiagram+29 && i < diagram_list.size(); ++i) {
453 y0 += rowHeight;
454 QRectF row_rect(x0, y0, list_rectangles[0] -> width(), rowHeight);
455 if (settings.value("genericpanel/folio", true).toBool()){
456 fillRow(file_path, row_rect, diagram_list[i] -> border_and_titleblock.author(),
457 diagram_list[i] -> title(),
458 diagram_list[i] -> border_and_titleblock.finalfolio(),
459 diagram_list[i] -> border_and_titleblock.date().toString("dd/MM/yy"));
460
461 }else{
462 fillRow(file_path, row_rect, diagram_list[i] -> border_and_titleblock.author(),
463 diagram_list[i] -> title(),
464 QString::number(diagram_list[i] ->folioIndex()+1),
465 diagram_list[i] -> border_and_titleblock.date().toString("dd/MM/yy"));
466
467 }
468 }
469
470 } else {
471 // Determine les elements a "XMLiser"
472 foreach(QGraphicsItem *qgi, diagram -> items()) {
473 if (Element *elmt = qgraphicsitem_cast<Element *>(qgi)) {
474 list_elements << elmt;
475 } else if (Conductor *f = qgraphicsitem_cast<Conductor *>(qgi)) {
476 list_conductors << f;
477 } else if (IndependentTextItem *iti = qgraphicsitem_cast<IndependentTextItem *>(qgi)) {
478 list_texts << iti;
479 } else if (DiagramImageItem *dii = qgraphicsitem_cast<DiagramImageItem *>(qgi)) {
480 list_images << dii;
481 } else if (QetShapeItem *dii = qgraphicsitem_cast<QetShapeItem *>(qgi)) {
482 list_shapes << dii;
483 } else if (DynamicElementTextItem *deti = qgraphicsitem_cast<DynamicElementTextItem *>(qgi)) {
484 list_texts << deti;
485 }
486 }
487 }
488
489 foreach (QetShapeItem *qsi, list_shapes) qsi->toDXF(file_path, qsi->pen());
490
491 //Draw elements
492 foreach(Element *elmt, list_elements)
493 {
494 double rotation_angle = elmt -> orientation() * 90;
495
496 qreal elem_pos_x = elmt -> pos().x();
497 qreal elem_pos_y = elmt -> pos().y();// - (diagram -> margin / 2);
498
499 qreal hotspot_x = (elem_pos_x) * Createdxf::xScale;
500 qreal hotspot_y = Createdxf::sheetHeight - (elem_pos_y) * Createdxf::yScale;
501
502 ElementPictureFactory::primitives primitives = ElementPictureFactory::instance()->getPrimitives(elmt->location());
503
504 for(QGraphicsSimpleTextItem *text : primitives.m_texts)
505 {
506 qreal fontSize = text->font().pointSizeF();
507 if (fontSize < 0)
508 fontSize = text->font().pixelSize();
509
510 fontSize *= Createdxf::yScale;
511 qreal x = elem_pos_x + text->pos().x();
512 qreal y = elem_pos_y + text->pos().y();
513 x *= Createdxf::xScale;
514 y = Createdxf::sheetHeight - (y * Createdxf::yScale);// - fontSize;
515 QPointF transformed_point = rotation_transformed(x, y, hotspot_x, hotspot_y, rotation_angle);
516 x = transformed_point.x();
517 y = transformed_point.y();
518 QStringList lines = text->text().split('\n');
519 y += (fontSize/2) * (lines.count()-1);
520 for (QString line : lines)
521 {
522 qreal angle = 360 - (text->rotation() + rotation_angle);
523 if (line.size() > 0 && line != "_" ) {
524 Createdxf::drawText(file_path, line, x, y, fontSize, angle, 0);
525 }
526 angle += 1080;
527 // coordinates for next line
528 if (int(angle) % 360 == 0) // no rotation
529 y -= fontSize*1.06;
530 else if (int(angle - 180) % 360 == 0) // 180 degrees rotation
531 y += fontSize*1.06;
532 else if (int(angle - 270) % 360 == 0) // 270 degrees rotation
533 x -= fontSize*1.06;
534 else // ((angle - 90) % 360 == 0) 90 degrees rotation
535 x += fontSize*1.06;
536 }
537 }
538
539 for (QLineF line : primitives.m_lines)
540 {
541 qreal x1 = (elem_pos_x + line.p1().x()) * Createdxf::xScale;
542 qreal y1 = Createdxf::sheetHeight - (elem_pos_y + line.p1().y()) * Createdxf::yScale;
543 QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
544 x1 = transformed_point.x();
545 y1 = transformed_point.y();
546 qreal x2 = (elem_pos_x + line.p2().x()) * Createdxf::xScale;
547 qreal y2 = Createdxf::sheetHeight - (elem_pos_y + line.p2().y()) * Createdxf::yScale;
548 transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
549 x2 = transformed_point.x();
550 y2 = transformed_point.y();
551 Createdxf::drawLine(file_path, x1, y1, x2, y2, 0);
552 }
553
554 for (QRectF rect : primitives.m_rectangles)
555 {
556 qreal x1 = (elem_pos_x + rect.bottomLeft().x()) * Createdxf::xScale;
557 qreal y1 = Createdxf::sheetHeight - (elem_pos_y + rect.bottomLeft().y()) * Createdxf::yScale;
558 qreal w = rect.width() * Createdxf::xScale;
559 qreal h = rect.height() * Createdxf::yScale;
560 // opposite corner
561 qreal x2 = x1 + w;
562 qreal y2 = y1 + h;
563 QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
564 x1 = transformed_point.x();
565 y1 = transformed_point.y();
566 transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
567 x2 = transformed_point.x();
568 y2 = transformed_point.y();
569 qreal bottom_left_x = (x1 < x2) ? x1 : x2;
570 qreal bottom_left_y = (y1 < y2) ? y1 : y2;
571 w = (x1 < x2) ? x2-x1 : x1-x2;
572 h = (y1 < y2) ? y2-y1 : y1-y2;
573 Createdxf::drawRectangle(file_path, bottom_left_x, bottom_left_y, w, h, 0);
574 }
575
576 for (QRectF circle_rect : primitives.m_circles)
577 {
578 qreal x1 = (elem_pos_x + circle_rect.center().x()) * Createdxf::xScale;
579 qreal y1 = Createdxf::sheetHeight - (elem_pos_y + circle_rect.center().y()) * Createdxf::yScale;
580 qreal r = circle_rect.width() * Createdxf::xScale / 2;
581 QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
582 x1 = transformed_point.x();
583 y1 = transformed_point.y();
584 Createdxf::drawCircle(file_path, r, x1, y1, 0);
585 }
586
587 for (QVector<QPointF> polygon : primitives.m_polygons)
588 {
589 if (polygon.size() == 0)
590 continue;
591 qreal x1 = (elem_pos_x + polygon.at(0).x()) * Createdxf::xScale;
592 qreal y1 = Createdxf::sheetHeight - (elem_pos_y + polygon.at(0).y()) * Createdxf::yScale;
593 QPointF transformed_point = rotation_transformed(x1, y1, hotspot_x, hotspot_y, rotation_angle);
594 x1 = transformed_point.x();
595 y1 = transformed_point.y();
596 for (int i = 1; i < polygon.size(); ++i ) {
597 qreal x2 = (elem_pos_x + polygon.at(i).x()) * Createdxf::xScale;
598 qreal y2 = Createdxf::sheetHeight - (elem_pos_y + polygon.at(i).y()) * Createdxf::yScale;
599 QPointF transformed_point = rotation_transformed(x2, y2, hotspot_x, hotspot_y, rotation_angle);
600 x2 = transformed_point.x();
601 y2 = transformed_point.y();
602 Createdxf::drawLine(file_path, x1, y1, x2, y2, 0);
603 x1 = x2;
604 y1 = y2;
605 }
606 }
607
608 // Draw arcs and ellipses
609 for (QVector<qreal> arc : primitives.m_arcs)
610 {
611 if (arc.size() == 0)
612 continue;
613 qreal x = (elem_pos_x + arc.at(0)) * Createdxf::xScale;
614 qreal y = Createdxf::sheetHeight - (elem_pos_y + arc.at(1)) * Createdxf::yScale;
615 qreal w = arc.at(2) * Createdxf::xScale;
616 qreal h = arc.at(3) * Createdxf::yScale;
617 qreal startAngle = arc.at(4);
618 qreal spanAngle = arc .at(5);
619 Createdxf::drawArcEllipse(file_path, x, y, w, h, startAngle, spanAngle, hotspot_x, hotspot_y, rotation_angle, 0);
620 }
621 }
622
623 //Draw conductors
624 foreach(Conductor *cond, list_conductors) {
625 foreach(ConductorSegment *segment, cond -> segmentsList()) {
626 qreal x1 = (segment -> firstPoint().x()) * Createdxf::xScale;
627 qreal y1 = Createdxf::sheetHeight - (segment -> firstPoint().y() * Createdxf::yScale);
628 qreal x2 = (segment -> secondPoint().x()) * Createdxf::xScale;
629 qreal y2 = Createdxf::sheetHeight - (segment -> secondPoint().y() * Createdxf::yScale);
630 Createdxf::drawLine(file_path, x1, y1, x2, y2, 0);
631 }
632 //Draw conductor text item
633 ConductorTextItem *textItem = cond -> textItem();
634 if (textItem) {
635 qreal fontSize = textItem -> font().pointSizeF();
636 if (fontSize < 0)
637 fontSize = textItem -> font().pixelSize();
638 fontSize *= Createdxf::yScale;
639 qreal x = (textItem -> pos().x()) * Createdxf::xScale;
640 qreal y = Createdxf::sheetHeight - (textItem -> pos().y() * Createdxf::yScale) - fontSize;
641 QStringList lines = textItem->toPlainText().split('\n');
642 foreach (QString line, lines) {
643 qreal angle = 360 - (textItem -> rotation());
644 if (line.size() > 0 && line != "_" )
645 Createdxf::drawText(file_path, line, x, y, fontSize, angle, 0 );
646
647 angle += 1080;
648 // coordinates for next line
649 if (int(angle) % 360 == 0) // no rotation
650 y -= fontSize*1.06;
651 else if (int(angle - 180) % 360 == 0) // 180 degrees rotation
652 y += fontSize*1.06;
653 else if (int(angle - 270) % 360 == 0) // 270 degrees rotation
654 x -= fontSize*1.06;
655 else // ((angle - 90) % 360 == 0) 90 degrees rotation
656 x += fontSize*1.06;
657 }
658
659 }
660 }
661
662 //Draw text items
663 foreach(DiagramTextItem *dti, list_texts) {
664 qreal fontSize = dti -> font().pointSizeF();
665 if (fontSize < 0)
666 fontSize = dti -> font().pixelSize();
667 fontSize *= Createdxf::yScale;
668 qreal x = (dti->scenePos().x()) * Createdxf::xScale;
669 qreal y = Createdxf::sheetHeight - (dti->scenePos().y() * Createdxf::yScale) - fontSize*1.05;
670 QStringList lines = dti -> toPlainText().split('\n');
671 foreach (QString line, lines) {
672 qreal angle = 360 - (dti -> rotation());
673 if (line.size() > 0 && line != "_" )
674 Createdxf::drawText(file_path, line, x, y, fontSize, angle, 0);
675
676 angle += 1080;
677 // coordinates for next line
678 if (int(angle) % 360 == 0) // no rotation
679 y -= fontSize*1.06;
680 else if (int(angle - 180) % 360 == 0) // 180 degrees rotation
681 y += fontSize*1.06;
682 else if (int(angle - 270) % 360 == 0) // 270 degrees rotation
683 x -= fontSize*1.06;
684 else // ((angle - 90) % 360 == 0) 90 degrees rotation
685 x += fontSize*1.06;
686 }
687 }
688 Createdxf::dxfEnd(file_path);
689
690 saveReloadDiagramParameters(diagram, false);
691 }
692
fillRow(const QString & file_path,const QRectF & row_rect,QString author,const QString & title,QString folio,QString date)693 void ExportDialog::fillRow(const QString& file_path, const QRectF &row_rect, QString author, const QString& title,
694 QString folio, QString date)
695 {
696 qreal x = row_rect.bottomLeft().x();
697 qreal y = row_rect.bottomLeft().y();
698
699 x *= Createdxf::xScale;
700 y = Createdxf::sheetHeight - y * Createdxf::yScale;
701 qreal height = row_rect.height() * Createdxf::yScale *0.7;
702 y += height*0.2;
703
704 Createdxf::drawTextAligned(file_path, std::move(folio),
705 x + 0.02*DiagramFolioList::colWidths[0]*row_rect.width()*Createdxf::xScale, y, height, 0, 0, 5, 0,
706 x + 0.95*DiagramFolioList::colWidths[0]*row_rect.width()*Createdxf::xScale, 0);
707
708 x += DiagramFolioList::colWidths[0]*row_rect.width()*Createdxf::xScale;
709 QString heading = tr("Titre");
710 if (title == heading)
711 Createdxf::drawTextAligned(file_path, title,
712 x + 0.02*DiagramFolioList::colWidths[1]*row_rect.width()*Createdxf::xScale, y, height, 0, 0, 5, 0,
713 x + 0.02*DiagramFolioList::colWidths[1]*row_rect.width()*Createdxf::xScale, 0);
714 else
715 Createdxf::drawTextAligned(file_path, title,
716 x + 0.02*DiagramFolioList::colWidths[1]*row_rect.width()*Createdxf::xScale, y, height, 0, 0, 5, 0,
717 x + 0.02*DiagramFolioList::colWidths[1]*row_rect.width()*Createdxf::xScale, 0, true);
718
719 x += DiagramFolioList::colWidths[1]*row_rect.width()*Createdxf::xScale;
720 Createdxf::drawTextAligned(file_path, std::move(author),
721 x + 0.02*DiagramFolioList::colWidths[2]*row_rect.width()*Createdxf::xScale, y, height, 0, 0, 5, 0,
722 x + 3.02*DiagramFolioList::colWidths[2]*row_rect.width()*Createdxf::xScale, 0);
723
724 x += DiagramFolioList::colWidths[2]*row_rect.width()*Createdxf::xScale;
725 Createdxf::drawTextAligned(file_path, std::move(date),
726 x + 0.02*DiagramFolioList::colWidths[3]*row_rect.width()*Createdxf::xScale, y, height, 0, 0, 5, 0,
727 x + 5.02*DiagramFolioList::colWidths[3]*row_rect.width()*Createdxf::xScale, 0);
728 }
729
rotation_transformed(qreal px,qreal py,qreal origin_x,qreal origin_y,qreal angle)730 QPointF ExportDialog::rotation_transformed(qreal px, qreal py , qreal origin_x, qreal origin_y, qreal angle) {
731
732 angle *= -3.14159265 / 180;
733
734 float s = sin(angle);
735 float c = cos(angle);
736
737 // Vector to rotate:
738 qreal Vx = px - origin_x;
739 qreal Vy = py - origin_y;
740
741 // rotate vector
742 float xnew = Vx * c - Vy * s;
743 float ynew = Vx * s + Vy * c;
744
745 return QPointF(xnew + origin_x, ynew + origin_y);
746 }
747
748
749
750 /**
751 Slot effectuant les exports apres la validation du dialogue.
752 */
slot_export()753 void ExportDialog::slot_export() {
754 // recupere la liste des schemas a exporter
755 QList<ExportDiagramLine *> diagrams_to_export;
756 foreach(ExportDiagramLine *diagram_line, diagram_lines_.values()) {
757 if (diagram_line -> must_export -> isChecked()) {
758 diagrams_to_export << diagram_line;
759 }
760 }
761
762 // verification #1 : chaque schema coche doit avoir un nom de fichier distinct
763 QSet<QString> filenames;
764 foreach(ExportDiagramLine *diagram_line, diagrams_to_export) {
765 QString diagram_file = diagram_line -> file_name -> text();
766 if (!diagram_file.isEmpty()) {
767 filenames << diagram_file;
768 }
769 }
770 if (filenames.count() != diagrams_to_export.count()) {
771 QET::QetMessageBox::warning(
772 this,
773 tr("Noms des fichiers cibles", "message box title"),
774 tr(
775 "Vous devez entrer un nom de fichier non vide et unique pour chaque "
776 "folio à exporter.",
777 "message box content"
778 )
779 );
780 return;
781 }
782
783 // verification #2 : un chemin vers un dossier doit avoir ete specifie
784
785 QDir target_dir_path(epw -> exportProperties().destination_directory);
786 if (!target_dir_path.exists()) {
787 QET::QetMessageBox::warning(
788 this,
789 tr("Dossier non spécifié", "message box title"),
790 tr("Vous devez spécifier le chemin du dossier dans lequel seront enregistrés les fichiers images.", "message box content"),
791 QMessageBox::Ok
792 );
793 return;
794 }
795
796 // exporte chaque schema a exporter
797 foreach(ExportDiagramLine *diagram_line, diagrams_to_export) {
798 exportDiagram(diagram_line);
799 }
800
801 // fermeture du dialogue
802 accept();
803 }
804
805 /**
806 Exporte un schema
807 @param diagram_line La ligne decrivant le schema a exporter et la maniere
808 de l'exporter
809 */
exportDiagram(ExportDiagramLine * diagram_line)810 void ExportDialog::exportDiagram(ExportDiagramLine *diagram_line) {
811 ExportProperties export_properties(epw -> exportProperties());
812
813 // recupere le format a utiliser (acronyme et extension)
814 QString format_acronym = export_properties.format;
815 QString format_extension = "." + format_acronym.toLower();
816
817 // determine le nom de fichier a utiliser
818 QString diagram_path = diagram_line -> file_name -> text();
819
820 // determine le chemin du fichier
821 QDir target_dir_path(export_properties.destination_directory);
822 diagram_path = target_dir_path.absoluteFilePath(diagram_path);
823
824 // recupere des informations sur le fichier specifie
825 QFileInfo file_infos(diagram_path);
826
827 // verifie qu'il est possible d'ecrire dans le fichier en question
828 if (file_infos.exists() && !file_infos.isWritable()) {
829 QET::QetMessageBox::critical(
830 this,
831 tr("Impossible d'écrire dans ce fichier", "message box title"),
832 QString(
833 tr(
834 "Il semblerait que vous n'ayez pas les permissions "
835 "nécessaires pour écrire dans le fichier %1.",
836 "message box content"
837 )
838 ).arg(diagram_path),
839 QMessageBox::Ok
840 );
841 return;
842 }
843
844 // ouvre le fichier
845 QFile target_file(diagram_path);
846
847 // enregistre l'image dans le fichier
848 if (format_acronym == "SVG") {
849 generateSvg(
850 diagram_line -> diagram,
851 diagram_line -> width -> value(),
852 diagram_line -> height -> value(),
853 diagram_line -> keep_ratio -> isChecked(),
854 target_file
855 );
856 } else if (format_acronym == "DXF") {
857 generateDxf(
858 diagram_line -> diagram,
859 diagram_line -> width -> value(),
860 diagram_line -> height -> value(),
861 diagram_line -> keep_ratio -> isChecked(),
862 diagram_path
863 );
864 } else {
865 QImage image = generateImage(
866 diagram_line -> diagram,
867 diagram_line -> width -> value(),
868 diagram_line -> height -> value(),
869 diagram_line -> keep_ratio -> isChecked()
870 );
871 image.save(&target_file, format_acronym.toUtf8().data());
872 }
873 target_file.close();
874 }
875
876 /**
877 Slot appele lorsque l'utilisateur change la zone du schema qui doit etre
878 exportee. Il faut alors ajuster les dimensions des schemas.
879 */
slot_changeUseBorder()880 void ExportDialog::slot_changeUseBorder() {
881 // parcourt les schemas a exporter
882 foreach(int diagram_id, diagram_lines_.keys()) {
883 ExportDiagramLine *diagram_line = diagram_lines_[diagram_id];
884
885 // corrige les dimensions des schemas dont il faut preserver le ratio
886 if (diagram_line -> keep_ratio -> isChecked()) {
887 slot_correctHeight(diagram_id);
888 }
889 }
890 }
891
892 /**
893 Ce slot est appele quand un schema a ete coche ou decoche.
894 Il active ou desactive le bouton "Exporter" en fonction du nombre de
895 schemas coches, et il garde au plus un schema coche si on exporte vers
896 le presse-papier.
897 */
slot_checkDiagramsCount()898 void ExportDialog::slot_checkDiagramsCount() {
899 QPushButton *export_button = buttons -> button(QDialogButtonBox::Save);
900 export_button -> setEnabled(diagramsToExportCount());
901 }
902
903 /**
904 Modifie les extensions des fichiers en fonction du format selectionne
905 @param force_extension true pour ajouter l'extension si elle n'est pas
906 presente, false pour se contenter de la modifier si elle est incorrecte.
907 */
slot_changeFilesExtension(bool force_extension)908 void ExportDialog::slot_changeFilesExtension(bool force_extension) {
909 // recupere le format a utiliser (acronyme et extension)
910 QString format_acronym = epw -> exportProperties().format;
911 QString format_extension = "." + format_acronym.toLower();
912
913 // parcourt les schemas a exporter
914 foreach(ExportDiagramLine *diagram_line, diagram_lines_.values()) {
915 QString diagram_filename = diagram_line -> file_name -> text();
916
917 // cas 1 : l'extension est presente et correcte : on ne fait rien
918 if (diagram_filename.endsWith(format_extension, Qt::CaseInsensitive)) {
919 continue;
920 }
921
922 QFileInfo diagram_filename_info(diagram_filename);
923 // cas 2 : l'extension est absente
924 if (diagram_filename_info.suffix().isEmpty()) {
925 if (force_extension) {
926 diagram_filename = diagram_filename_info.completeBaseName() + format_extension;
927 }
928 } else {
929 // cas 3 : l'extension est presente mais erronee
930 diagram_filename = diagram_filename_info.completeBaseName() + format_extension;
931 }
932
933 diagram_line -> file_name -> setText(diagram_filename);
934 }
935 }
936
937 /**
938 Cette methode fait apparaitre un dialogue permettant de previsualiser un
939 des schemas a exporter
940 @param diagram_id numero du schema a previsualiser
941 */
slot_previewDiagram(int diagram_id)942 void ExportDialog::slot_previewDiagram(int diagram_id) {
943 // recupere l'ExportDiagramLine concernee
944 ExportDialog::ExportDiagramLine *current_diagram = diagram_lines_[diagram_id];
945 if (!current_diagram) return;
946
947 // initialise un dialogue
948 QDialog preview_dialog;
949 preview_dialog.setWindowTitle(tr("Aperçu"));
950 preview_dialog.setWindowState(preview_dialog.windowState() | Qt::WindowMaximized);
951
952 QGraphicsScene *preview_scene = new QGraphicsScene();
953 preview_scene -> setBackgroundBrush(Qt::lightGray);
954 QGraphicsView *preview_view = new QGraphicsView(preview_scene);
955 preview_view -> setDragMode(QGraphicsView::ScrollHandDrag);
956 QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Ok);
957 connect(buttons, SIGNAL(accepted()), &preview_dialog, SLOT(accept()));
958
959 QVBoxLayout *vboxlayout1 = new QVBoxLayout();
960 vboxlayout1 -> addWidget(preview_view);
961 vboxlayout1 -> addWidget(buttons);
962 preview_dialog.setLayout(vboxlayout1);
963
964 // genere le nouvel apercu
965 QImage preview_image = generateImage(
966 current_diagram -> diagram,
967 current_diagram -> width -> value(),
968 current_diagram -> height -> value(),
969 current_diagram -> keep_ratio -> isChecked()
970 );
971
972 // nettoie l'apercu
973 foreach (QGraphicsItem *qgi, preview_scene -> items()) {
974 preview_scene -> removeItem(qgi);
975 delete qgi;
976 }
977
978 // ajoute le nouvel apercu
979 QGraphicsPixmapItem *qgpi = new QGraphicsPixmapItem(QPixmap::fromImage(preview_image));
980 preview_scene -> addItem(qgpi);
981 preview_scene -> setSceneRect(QRectF(0.0, 0.0, preview_image.width(), preview_image.height()));
982
983 // montre l'apercu
984 preview_dialog.exec();
985 }
986
987 /**
988 Cette methode exporte un schema vers le presse-papier
989 @param diagram_id numero du schema a previsualiser
990 */
slot_exportToClipBoard(int diagram_id)991 void ExportDialog::slot_exportToClipBoard(int diagram_id) {
992 // recupere l'ExportDiagramLine concernee
993 ExportDialog::ExportDiagramLine *diagram_line = diagram_lines_[diagram_id];
994 if (!diagram_line) return;
995
996 // recupere le format a utiliser (acronyme et extension)
997 QString format_acronym = epw -> exportProperties().format;
998
999 QClipboard *clipboard = QApplication::clipboard();
1000
1001 // enregistre l'image dans le fichier
1002 if (format_acronym == "SVG") {
1003 QByteArray ba;
1004 QBuffer buffer(&ba);
1005 buffer.open(QIODevice::WriteOnly);
1006 generateSvg(
1007 diagram_line -> diagram,
1008 diagram_line -> width -> value(),
1009 diagram_line -> height -> value(),
1010 diagram_line -> keep_ratio -> isChecked(),
1011 buffer
1012 );
1013 buffer.close();
1014 clipboard -> setText(ba);
1015 } else {
1016 QImage image = generateImage(
1017 diagram_line -> diagram,
1018 diagram_line -> width -> value(),
1019 diagram_line -> height -> value(),
1020 diagram_line -> keep_ratio -> isChecked()
1021 );
1022 clipboard -> setImage(image);
1023 }
1024 }
1025
1026 /**
1027 Constructeur
1028 @param dia Schema concerne,
1029 @param diagram_size taille du schema tenant compte des parametres d'export
1030 */
ExportDiagramLine(Diagram * dia,QSize diagram_size)1031 ExportDialog::ExportDiagramLine::ExportDiagramLine(Diagram *dia, QSize diagram_size) {
1032 diagram = dia;
1033 must_export = new QCheckBox();
1034 must_export -> setChecked(true);
1035
1036 // titre et nom de fichier du schema
1037 QString diagram_title = diagram -> title();
1038 QString diagram_index = QString::number(diagram -> folioIndex()+1);
1039 //QString diagram_folio_label = diagram -> border_and_titleblock.finalfolio();
1040 if (diagram_title.isEmpty()) diagram_title = QObject::tr("Folio sans titre");
1041 QString diagram_filename = diagram -> title();
1042 if (diagram_filename.isEmpty()) diagram_filename = QObject::tr("schema");
1043 diagram_filename = QET::stringToFileName(diagram_index + "_" + diagram_filename);
1044
1045 title_label = new QLabel(diagram_title);
1046
1047 file_name = new QLineEdit();
1048 file_name -> setText(diagram_filename);
1049 file_name -> setMinimumWidth(280);
1050
1051 width = new QSpinBox();
1052 width -> setRange(1, 10000);
1053 width -> setSuffix(tr("px"));
1054 width -> setValue(diagram_size.width());
1055
1056 height = new QSpinBox();
1057 height -> setRange(1, 10000);
1058 height -> setSuffix(tr("px"));
1059 height -> setValue(diagram_size.height());
1060
1061 x_label = new QLabel("*");
1062
1063 keep_ratio = new QPushButton();
1064 keep_ratio -> setCheckable(true);
1065 keep_ratio -> setChecked(true);
1066 keep_ratio -> setIcon(QET::Icons::ObjectLocked);
1067 keep_ratio -> setToolTip(QObject::tr("Conserver les proportions"));
1068
1069 reset_size = new QPushButton();
1070 reset_size -> setIcon(QET::Icons::Start);
1071 reset_size -> setToolTip(QObject::tr("Réinitialiser les dimensions"));
1072
1073 preview = new QPushButton();
1074 preview -> setIcon(QET::Icons::ZoomOriginal);
1075 preview -> setToolTip(QObject::tr("Aperçu"));
1076
1077 clipboard = new QPushButton();
1078 clipboard -> setIcon(QET::Icons::IC_CopyFile);
1079 clipboard -> setToolTip(QObject::tr("Exporter vers le presse-papier"));
1080 }
1081
1082 /**
1083 Destructeur
1084 */
~ExportDiagramLine()1085 ExportDialog::ExportDiagramLine::~ExportDiagramLine() {
1086 }
1087
1088 /**
1089 @return un layout contenant les widgets necessaires a la gestion de la
1090 taille d'un schema avant son export.
1091 */
sizeLayout()1092 QBoxLayout *ExportDialog::ExportDiagramLine::sizeLayout() {
1093 QHBoxLayout *layout = new QHBoxLayout();
1094 layout -> addWidget(width);
1095 layout -> addWidget(x_label);
1096 layout -> addWidget(height);
1097 layout -> addWidget(keep_ratio);
1098 layout -> addWidget(reset_size);
1099 layout -> addWidget(preview);
1100 layout -> addWidget(clipboard);
1101 return(layout);
1102 }
1103