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 "diagramprintdialog.h"
19 #include "qetprintpreviewdialog.h"
20 #include <math.h>
21 #include "diagramschooser.h"
22 #include "exportproperties.h"
23 #include "qeticons.h"
24 #include "qetmessagebox.h"
25 
26 #include <QPrinter>
27 #include <QPrintDialog>
28 
29 /**
30 	Constructeur
31 	@param project Schema a imprimer
32 	@param parent  Widget parent du dialogue
33 */
DiagramPrintDialog(QETProject * project,QWidget * parent)34 DiagramPrintDialog::DiagramPrintDialog(QETProject *project, QWidget *parent) :
35 	QWidget(parent),
36 	project_(project),
37 	dialog_(nullptr)
38 {
39 	// initialise l'imprimante
40 	printer_ = new QPrinter();
41 
42 	// orientation paysage par defaut
43 	printer_ -> setOrientation(QPrinter::Landscape);
44 	backup_diagram_background_color = Diagram::background_color;
45 	Diagram::background_color = Qt::white;
46 }
47 
48 /**
49 	Destructeur
50 */
~DiagramPrintDialog()51 DiagramPrintDialog::~DiagramPrintDialog() {
52 	delete dialog_;
53 	delete printer_;
54 	Diagram::background_color = backup_diagram_background_color;
55 }
56 
57 /**
58 	Definit le nom du PDF si l'utilisateur choisit une sortie vers un PDF
59 */
setFileName(const QString & name)60 void DiagramPrintDialog::setFileName(const QString &name) {
61 	file_name_ = name;
62 }
63 
64 /**
65 	@return le nom du PDF
66 */
fileName() const67 QString DiagramPrintDialog::fileName() const {
68 	return(file_name_);
69 }
70 
71 /**
72 	Definit le nom du document
73 */
setDocName(const QString & name)74 void DiagramPrintDialog::setDocName(const QString &name) {
75 	doc_name_ = name;
76 }
77 
78 /**
79 	@return le nom du document
80 */
docName() const81 QString DiagramPrintDialog::docName() const {
82 	return(doc_name_);
83 }
84 
85 /**
86 	@param diagram Diagram to be printed
87 	@param include_titleblock (Optional, defaults to true) Whether the diagram
88 	titleblock should be printed.
89 	@return the rectangle to be printed
90 */
diagramRect(Diagram * diagram,const ExportProperties & options) const91 QRect DiagramPrintDialog::diagramRect(Diagram *diagram, const ExportProperties &options) const {
92 	if (!diagram) return(QRect());
93 
94 	QRectF diagram_rect = diagram -> border_and_titleblock.borderAndTitleBlockRect();
95 	if (!options.draw_titleblock) {
96 		qreal titleblock_height = diagram -> border_and_titleblock.titleBlockRect().height();
97 		diagram_rect.setHeight(diagram_rect.height() - titleblock_height);
98 	}
99 
100 	// ajuste la bordure du schema d'un pixel (epaisseur du trait)
101 	diagram_rect = diagram_rect.adjusted(0.0, 0.0, 1.0, 1.0);
102 
103 	return(diagram_rect.toAlignedRect());
104 }
105 
106 /**
107 	Execute le dialogue d'impression
108 */
exec()109 void DiagramPrintDialog::exec() {
110 
111 	// prise en compte du nom du document
112 	if (!doc_name_.isEmpty()) printer_ -> setDocName(doc_name_);
113 	printer_ -> setCreator(QString("QElectroTech %1").arg(QET::displayedVersion));
114 
115 	// affichage d'un premier dialogue demandant a l'utilisateur le type
116 	// d'impression qu'il souhaite effectuer
117 	buildPrintTypeDialog();
118 	if (dialog_ -> exec() == QDialog::Rejected) return;
119 
120 	// parametrage de l'imprimante en fonction du type d'impression choisi
121 	if (printer_choice_ -> isChecked()) {
122 		// affichage du dialogue d'impression standard pour parametrer l'imprimante
123 		QPrintDialog print_dialog(printer_, parentWidget());
124 #ifdef Q_OS_MAC
125 		print_dialog.setWindowFlags(Qt::Sheet);
126 #endif
127 		print_dialog.setWindowTitle(tr("Options d'impression", "window title"));
128 		print_dialog.setEnabledOptions(QAbstractPrintDialog::PrintShowPageSize);
129 		if (print_dialog.exec() == QDialog::Rejected) return;
130 	}
131 	else
132 	{
133 		printer_ -> setOutputFormat(QPrinter::PdfFormat);
134 		printer_ -> setOutputFileName(filepath_field_ -> text());
135 	}
136 
137 	loadPageSetupForCurrentPrinter();
138 
139 	//Preview before print
140 #if defined Q_OS_LINUX
141 	//Due to some bug with xfwm, we display this dialog has a windows on linux os (X11)
142 	//@TODO see if we must this line with graphic server wayland
143 	QETPrintPreviewDialog preview_dialog(project_, printer_, parentWidget(), Qt::Window);
144 #else
145 	QETPrintPreviewDialog preview_dialog(project_, printer_, parentWidget());
146 #endif
147 	connect(
148 		&preview_dialog,
149 		SIGNAL(paintRequested(const QList<Diagram *> &, bool, const ExportProperties, QPrinter *)),
150 		this,
151 		SLOT(print(const QList<Diagram *> &, bool, const ExportProperties))
152 	);
153 	DiagramsChooser *dc = preview_dialog.diagramsChooser();
154 	dc -> setSelectedAllDiagrams();
155 	if (preview_dialog.exec() == QDialog::Rejected) return;
156 
157 	savePageSetupForCurrentPrinter();
158 
159 	// effectue l'impression en elle-meme
160 	print(
161 		dc -> selectedDiagrams(),
162 		preview_dialog.fitDiagramsToPages(),
163 		preview_dialog.exportProperties()
164 	);
165 }
166 
167 /**
168 	@param diagram Schema a imprimer
169 	@param options Rendering options
170 	@param fullpage true pour utiliser toute la feuille dans le calcul
171 	@return Le nombre de pages necessaires pour imprimer le schema
172 	avec l'orientation et le format papier utilise dans l'imprimante en cours.
173 */
pagesCount(Diagram * diagram,const ExportProperties & options,bool fullpage) const174 int DiagramPrintDialog::pagesCount(Diagram *diagram, const ExportProperties &options, bool fullpage) const {
175 	return(horizontalPagesCount(diagram, options, fullpage) * verticalPagesCount(diagram, options, fullpage));
176 }
177 
178 /**
179 	@param diagram Schema a imprimer
180 	@param options Rendering options
181 	@param fullpage true pour utiliser toute la feuille dans le calcul
182 	@return La largeur du "poster" en nombre de pages pour imprimer le schema
183 	avec l'orientation et le format papier utilise dans l'imprimante en cours.
184 */
horizontalPagesCount(Diagram * diagram,const ExportProperties & options,bool fullpage) const185 int DiagramPrintDialog::horizontalPagesCount(Diagram *diagram, const ExportProperties &options, bool fullpage) const {
186 	// note : pageRect et Paper Rect tiennent compte de l'orientation du papier
187 	QRect printable_area = fullpage ? printer_ -> paperRect() : printer_ -> pageRect();
188 	QRect diagram_rect = diagramRect(diagram, options);
189 
190 	int h_pages_count = int(ceil(qreal(diagram_rect.width()) / qreal(printable_area.width())));
191 	return(h_pages_count);
192 }
193 
194 /**
195 	@param diagram Schema a imprimer
196 	@param options Rendering options
197 	@param fullpage true pour utiliser toute la feuille dans le calcul
198 	@return La largeur du "poster" en nombre de pages pour imprimer le schema
199 	avec l'orientation et le format papier utilise dans l'imprimante en cours.
200 */
verticalPagesCount(Diagram * diagram,const ExportProperties & options,bool fullpage) const201 int DiagramPrintDialog::verticalPagesCount(Diagram *diagram, const ExportProperties &options, bool fullpage) const {
202 	// note : pageRect et Paper Rect tiennent compte de l'orientation du papier
203 	QRect printable_area = fullpage ? printer_ -> paperRect() : printer_ -> pageRect();
204 	QRect diagram_rect = diagramRect(diagram, options);
205 
206 	int v_pages_count = int(ceil(qreal(diagram_rect.height()) / qreal(printable_area.height())));
207 	return(v_pages_count);
208 }
209 
210 /**
211 	Construit un dialogue non standard pour demander a l'utilisateur quelle type
212 	d'impression il souhaite effectuer : PDF, PS ou imprimante physique
213 */
buildPrintTypeDialog()214 void DiagramPrintDialog::buildPrintTypeDialog() {
215 	// initialisation des widgets
216 	dialog_           = new QDialog(parentWidget());
217 #ifdef Q_OS_MAC
218 	dialog_ -> setWindowFlags(Qt::Sheet);
219 #endif
220 
221 	printtype_label_  = new QLabel(tr("Quel type d'impression désirez-vous effectuer ?"));
222 	printer_icon_     = new QLabel();
223 	pdf_icon_         = new QLabel();
224 
225 	printtype_choice_ = new QButtonGroup();
226 	printer_choice_   = new QRadioButton(tr("Impression sur une imprimante physique",               "Print type choice"));
227 	pdf_choice_       = new QRadioButton(tr("Impression vers un fichier au format PDF",             "Print type choice"));
228 
229 	filepath_field_   = new QLineEdit();
230 	browse_button_    = new QPushButton("...");
231 	buttons_          = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
232 
233 	dialog_ -> setWindowTitle(tr("Choix du type d'impression"));
234 	printer_icon_ -> setPixmap(QET::Icons::Printer.pixmap(32, 32));
235 	pdf_icon_     -> setPixmap(QET::Icons::PDF.pixmap(32, 32));
236 
237 	printtype_choice_ -> addButton(printer_choice_);
238 	printtype_choice_ -> addButton(pdf_choice_);
239 
240 	printer_choice_ -> setChecked(true);
241 	if (!file_name_.isEmpty()) filepath_field_ -> setText(file_name_ + ".pdf");
242 
243 	// connexions signaux / slots
244 	connect(printer_choice_, SIGNAL(toggled(bool)), this,    SLOT(updatePrintTypeDialog()));
245 	connect(pdf_choice_,     SIGNAL(toggled(bool)), this,    SLOT(updatePrintTypeDialog()));
246 	connect(browse_button_,  SIGNAL(clicked(bool)), this,    SLOT(browseFilePrintTypeDialog()));
247 	connect(buttons_,        SIGNAL(accepted()),    this,    SLOT(acceptPrintTypeDialog()));
248 	connect(buttons_,        SIGNAL(rejected()),    dialog_, SLOT(reject()));
249 
250 	// organisation graphique
251 	glayout0_ = new QGridLayout();
252 	hlayout0_ = new QHBoxLayout();
253 	vlayout0_ = new QVBoxLayout();
254 
255 	hlayout0_ -> addWidget(filepath_field_);
256 	hlayout0_ -> addWidget(browse_button_);
257 	glayout0_ -> addWidget(printer_icon_,   0, 0);
258 	glayout0_ -> addWidget(printer_choice_, 0, 1);
259 	glayout0_ -> addWidget(pdf_icon_,       1, 0);
260 	glayout0_ -> addWidget(pdf_choice_,     1, 1);
261 	glayout0_ -> addLayout(hlayout0_,       3, 1);
262 
263 	vlayout0_ -> addWidget(printtype_label_);
264 	vlayout0_ -> addLayout(glayout0_);
265 	vlayout0_ -> addWidget(buttons_);
266 
267 	dialog_ -> setLayout(vlayout0_);
268 
269 	updatePrintTypeDialog();
270 }
271 
272 /**
273 	Assure la coherence du dialogue permettant le choix du type d'impression
274 */
updatePrintTypeDialog()275 void DiagramPrintDialog::updatePrintTypeDialog() {
276 	// imprime-t-on vers un fichier ?
277 	bool file_print = !(printer_choice_ -> isChecked());
278 
279 	// on n'active le champ fichier que pour les impressions vers un fichier
280 	filepath_field_ -> setEnabled(file_print);
281 	browse_button_  -> setEnabled(file_print);
282 
283 	// on corrige eventuellement l'extension du fichier deja selectionne
284 	if (file_print)
285 	{
286 		QString filepath = filepath_field_ -> text();
287 		if (!filepath.isEmpty())
288 		{
289 			if (pdf_choice_ -> isChecked() && filepath.endsWith(".ps"))
290 			{
291 				QRegExp re("\\.ps$", Qt::CaseInsensitive);
292 				filepath.replace(re, ".pdf");
293 				filepath_field_ -> setText(filepath);
294 			}
295 		}
296 	}
297 }
298 
299 /**
300 	Verifie l'etat du dialogue permettant le choix du type d'impression lorsque
301 	l'utilisateur le valide.
302 */
acceptPrintTypeDialog()303 void DiagramPrintDialog::acceptPrintTypeDialog() {
304 	bool file_print = !(printer_choice_ -> isChecked());
305 	if (file_print) {
306 		// un fichier doit avoir ete entre
307 		if (filepath_field_ -> text().isEmpty()) {
308 			QET::QetMessageBox::information(
309 				parentWidget(),
310 				tr("Fichier manquant", "message box title"),
311 				tr("Vous devez indiquer le chemin du fichier PDF/PS à créer.", "message box content")
312 			);
313 		} else dialog_ -> accept();
314 	} else {
315 		// une imprimante doit avoir ete selectionnee
316 		/// @todo
317 		dialog_ -> accept();
318 	}
319 }
320 
321 /**
322 	Permet a l'utilisateur de choisir un fichier
323 */
browseFilePrintTypeDialog()324 void DiagramPrintDialog::browseFilePrintTypeDialog() {
325 	QString extension;
326 	QString filter;
327 	if (printer_choice_ -> isChecked()) return;
328 	else if (pdf_choice_ -> isChecked())
329 	{
330 		extension = ".pdf";
331 		filter    = tr("Fichiers PDF (*.pdf)",       "file filter");
332 	}
333 
334 	QString filepath = QFileDialog::getSaveFileName(
335 		parentWidget(),
336 		QString(),
337 		filepath_field_ -> text(),
338 		filter
339 	);
340 
341 	if (!filepath.isEmpty()) {
342 		if (!filepath.endsWith(extension)) filepath += extension;
343 		filepath = QDir::toNativeSeparators(QDir::cleanPath(filepath));
344 		filepath_field_ -> setText(filepath);
345 	}
346 }
347 
348 /**
349 	Effectue l'impression elle-meme
350 	@param diagrams Schemas a imprimer
351 	@param fit_page Booleen indiquant s'il faut adapter les schemas aux pages
352 	ou non
353 	@param options Options de rendu
354 */
print(const QList<Diagram * > & diagrams,bool fit_page,const ExportProperties & options)355 void DiagramPrintDialog::print(const QList<Diagram *> &diagrams, bool fit_page, const ExportProperties& options) {
356 	//qDebug() << "Demande d'impression de " << diagrams.count() << "schemas.";
357 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
358     #ifdef Q_OS_WIN
359         #ifdef QT_DEBUG
360             qDebug() << "--";
361             qDebug() << "DiagramPrintDialog::print  printer_->resolution() before " << printer_->resolution();
362             qDebug() << "DiagramPrintDialog::print  screennumber " << QApplication::desktop()->screenNumber();
363         #endif
364 
365         QScreen *srn = QApplication::screens().at(QApplication::desktop()->screenNumber());
366         qreal dotsPerInch = (qreal)srn->logicalDotsPerInch();
367         printer_->setResolution(dotsPerInch);
368 
369         #ifdef QT_DEBUG
370             qDebug() << "DiagramPrintDialog::print  dotsPerInch " << dotsPerInch;
371             qDebug() << "DiagramPrintDialog::print  printer_->resolution() after" << printer_->resolution();
372             qDebug() << "--";
373         #endif
374     #endif
375 #endif
376 	// QPainter utiliser pour effectuer le rendu
377 	QPainter qp(printer_);
378 
379 	// cas special : il n'y a aucun schema a imprimer
380 	if (!diagrams.count()) {
381 		qp.end();
382 		return;
383 	}
384 
385 	// imprime les schemas
386 	for (int i = 0 ; i < diagrams.count() ; ++ i) {
387 		printDiagram(diagrams[i], fit_page, options, &qp, printer_);
388 		if (i != diagrams.count() - 1) {
389 			printer_ -> newPage();
390 		}
391 	}
392 }
393 
394 /**
395 	Imprime un schema
396 	@param diagram Schema a imprimer
397 	@param fit_page True pour adapter les schemas aux pages, false sinon
398 	@param options Options de rendu a appliquer pour l'impression
399 	@param qp QPainter a utiliser (deja initialise sur printer)
400 	@param printer Imprimante a utiliser
401 */
printDiagram(Diagram * diagram,bool fit_page,const ExportProperties & options,QPainter * qp,QPrinter * printer)402 void DiagramPrintDialog::printDiagram(Diagram *diagram, bool fit_page, const ExportProperties &options, QPainter *qp, QPrinter *printer) {
403 	//qDebug() << printer -> paperSize() << printer -> paperRect() << diagram -> title();
404 	// l'imprimante utilise-t-elle toute la feuille ?
405 	bool full_page = printer -> fullPage();
406 
407 	// impression physique (!= fichier PDF)
408 	if (printer -> outputFileName().isEmpty()) {
409 		// utiliser cette condition pour agir differemment en cas d'impression physique
410 	}
411 
412 	saveReloadDiagramParameters(diagram, options, true);
413 
414 	// deselectionne tous les elements
415 	QList<QGraphicsItem *> selected_elmts = diagram -> selectedItems();
416 	foreach (QGraphicsItem *qgi, selected_elmts) qgi -> setSelected(false);
417 
418 	// enleve le flag focusable de tous les elements concernes pour eviter toute reprise de focus par un champ de texte editable
419 	QList<QGraphicsItem *> focusable_items;
420 	foreach (QGraphicsItem *qgi, diagram -> items()) {
421 		if (qgi -> flags() & QGraphicsItem::ItemIsFocusable) {
422 			focusable_items << qgi;
423 			qgi -> setFlag(QGraphicsItem::ItemIsFocusable, false);
424 		}
425 	}
426 
427 	// evite toute autre forme d'interaction
428 	foreach (QGraphicsView *view, diagram -> views()) {
429 		view -> setInteractive(false);
430 	}
431 
432 	QRect diagram_rect = diagramRect(diagram, options);
433 	if (fit_page) {
434 		// impression adaptee sur une seule page
435 		diagram -> render(qp, QRectF(), diagram_rect, Qt::KeepAspectRatio);
436 	} else {
437 		// impression sur une ou plusieurs pages
438 		QRect printed_area = full_page ? printer -> paperRect() : printer -> pageRect();
439 		//qDebug() << "impression sur une ou plusieurs pages";
440 		//qDebug() << "  schema :" << diagram_rect;
441 		//qDebug() << "  page   :" << printed_area;
442 
443 		int used_width  = printed_area.width();
444 		int used_height = printed_area.height();
445 		int h_pages_count = horizontalPagesCount(diagram, options, full_page);
446 		int v_pages_count = verticalPagesCount(diagram, options, full_page);
447 
448 		QVector< QVector< QRect > > pages_grid;
449 		// le schema est imprime sur une matrice de feuilles
450 		// parcourt les lignes de la matrice
451 		int y_offset = 0;
452 		for (int i = 0 ; i < v_pages_count ; ++ i) {
453 			pages_grid << QVector< QRect >();
454 
455 			// parcourt les feuilles de la ligne
456 			int x_offset = 0;
457 			for (int j = 0 ; j < h_pages_count ; ++ j) {
458 				pages_grid.last() << QRect(
459 					QPoint(x_offset, y_offset),
460 					QSize(
461 						qMin(used_width,  diagram_rect.width()  - x_offset),
462 						qMin(used_height, diagram_rect.height() - y_offset)
463 					)
464 				);
465 				x_offset += used_width;
466 			}
467 
468 			y_offset += used_height;
469 		}
470 
471 		// ne retient que les pages a imprimer
472 		QVector<QRect> pages_to_print;
473 		for (int i = 0 ; i < v_pages_count ; ++ i) {
474 			for (int j = 0 ; j < h_pages_count ; ++ j) {
475 				pages_to_print << pages_grid.at(i).at(j);
476 			}
477 		}
478 		//qDebug() << "  " << pages_to_print.count() << " pages a imprimer :";
479 
480 		// parcourt les pages pour impression
481 		for (int i = 0 ; i < pages_to_print.count() ; ++ i) {
482 			QRect current_rect(pages_to_print.at(i));
483 			//qDebug() << "    " << current_rect;
484 			diagram -> render(
485 				qp,
486 				QRect(QPoint(0,0), current_rect.size()),
487 				current_rect.translated(diagram_rect.topLeft()),
488 				Qt::KeepAspectRatio
489 			);
490 			if (i != pages_to_print.count() - 1) {
491 				printer -> newPage();
492 			}
493 		}
494 	}
495 
496 	// remet en place les interactions
497 	foreach (QGraphicsView *view, diagram -> views()) {
498 		view -> setInteractive(true);
499 	}
500 
501 	// restaure les flags focusable
502 	foreach (QGraphicsItem *qgi, focusable_items) {
503 		qgi -> setFlag(QGraphicsItem::ItemIsFocusable, true);
504 	}
505 
506 	// restaure les elements selectionnes
507 	foreach (QGraphicsItem *qgi, selected_elmts) qgi -> setSelected(true);
508 
509 	saveReloadDiagramParameters(diagram, options, false);
510 }
511 
512 /**
513 	Sauve ou restaure les parametres du schema
514 	@param diagram Schema dont on sauve ou restaure les parametres
515 	@param options Parametres a appliquer
516 	@param save true pour memoriser les parametres du schema et appliquer ceux
517 	definis dans options, false pour restaurer les parametres
518 */
saveReloadDiagramParameters(Diagram * diagram,const ExportProperties & options,bool save)519 void DiagramPrintDialog::saveReloadDiagramParameters(Diagram *diagram, const ExportProperties& options, bool save) {
520 	static ExportProperties state_exportProperties;
521 
522 	if (save) {
523 		// memorise les parametres relatifs au schema tout en appliquant les nouveaux
524 		state_exportProperties = diagram -> applyProperties(options);
525 	} else {
526 		// restaure les parametres relatifs au schema
527 		diagram -> applyProperties(state_exportProperties);
528 	}
529 }
530 
531 /**
532 	Save parameters set in the "page setup" dialog into the QElectroTech
533 	configuration. Key/values pairs are associated to the printer for which
534 	they have been set.
535 */
savePageSetupForCurrentPrinter()536 void DiagramPrintDialog::savePageSetupForCurrentPrinter()
537 {
538 	QSettings settings;
539 	QString printer_section = settingsSectionName(printer_);
540 
541 	while (!settings.group().isEmpty()) settings.endGroup();
542 	settings.beginGroup("printers");
543 	settings.beginGroup(printer_section);
544 
545 	settings.setValue("orientation", printer_ -> orientation() == QPrinter::Portrait ? "portrait" : "landscape");
546 	settings.setValue("papersize", int(printer_ -> paperSize()));
547 	if (printer_ -> paperSize() == QPrinter::Custom) {
548 		QSizeF size = printer_ -> paperSize(QPrinter::Millimeter);
549 		settings.setValue("customwidthmm", size.width());
550 		settings.setValue("customheightmm", size.height());
551 	} else {
552 		settings.remove("customwidthmm");
553 		settings.remove("customheightmm");
554 	}
555 	qreal left, top, right, bottom;
556 	printer_ -> getPageMargins(&left, &top, &right, &bottom, QPrinter::Millimeter);
557 	settings.setValue("marginleft", left);
558 	settings.setValue("margintop", top);
559 	settings.setValue("marginright", right);
560 	settings.setValue("marginbottom", bottom);
561 	settings.setValue("fullpage", printer_ -> fullPage() ? "true" : "false");
562 	settings.endGroup();
563 	settings.endGroup();
564 	settings.sync();
565 }
566 
567 
568 /**
569 	Load parameters previously set in the "page setup" dialog for the current
570 	printer, if any.
571 */
loadPageSetupForCurrentPrinter()572 void DiagramPrintDialog::loadPageSetupForCurrentPrinter()
573 {
574 	QSettings settings;
575 	QString printer_section = settingsSectionName(printer_);
576 
577 	while (!settings.group().isEmpty()) settings.endGroup();
578 	settings.beginGroup("printers");
579 	if (!settings.childGroups().contains(printer_section)) {
580 		settings.endGroup();
581 		return;
582 	}
583 
584 	settings.beginGroup(printer_section);
585 	if (settings.contains("orientation")) {
586 		QString value = settings.value("orientation", "landscape").toString();
587 		printer_ -> setOrientation(value == "landscape" ? QPrinter::Landscape : QPrinter::Portrait);
588 	}
589 	if (settings.contains("papersize")) {
590 		int value = settings.value("papersize", QPrinter::A4).toInt();
591 		if (value == QPrinter::Custom) {
592 			bool w_ok, h_ok;
593 			int w = settings.value("customwidthmm", -1).toInt(&w_ok);
594 			int h = settings.value("customheightmm", -1).toInt(&h_ok);
595 			if (w_ok && h_ok && w != -1 && h != -1) {
596 				printer_ -> setPaperSize(QSizeF(w, h), QPrinter::Millimeter);
597 			}
598 		} else if (value < QPrinter::Custom) {
599 			printer_ -> setPaperSize(static_cast<QPrinter::PaperSize>(value));
600 		}
601 	}
602 
603 	qreal margins[4];
604 	printer_ -> getPageMargins(&margins[0], &margins[1], &margins[2], &margins[3], QPrinter::Millimeter);
605 	QStringList margins_names(QStringList() << "left" << "top" << "right" << "bottom");
606 	for (int i = 0 ; i < 4 ; ++ i) {
607 		bool conv_ok;
608 		qreal value = settings.value("margin" + margins_names.at(i), -1.0).toReal(&conv_ok);
609 		if (conv_ok && value != -1.0) margins[i] = value;
610 	}
611 	printer_ -> setPageMargins(margins[0], margins[1], margins[2], margins[3], QPrinter::Millimeter);
612 	printer_ -> setFullPage(settings.value("fullpage", "false").toString() == "true");
613 
614 	settings.endGroup();
615 	settings.endGroup();
616 }
617 
618 /**
619 	@return a section name for use with QSettings in order to store parameters
620 	related to \a printer.
621 */
settingsSectionName(const QPrinter * printer)622 QString DiagramPrintDialog::settingsSectionName(const QPrinter *printer) {
623 	QPrinter::OutputFormat printer_format = printer -> outputFormat();
624 	if (printer_format == QPrinter::NativeFormat) {
625 		return(printer -> printerName().replace(" ", "_"));
626 	} else if (printer_format == QPrinter::PdfFormat) {
627 		return("QET_PDF_Printing");
628 	}
629 	return(QString());
630 }
631