1 //
2 // C++ Implementation: NativeRenderDialog
3 //
4 // Description:
5 //
6 //
7 // Author: Chris Browet <cbro@semperpax.com>, (C) 2008
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12 #include "NativeRenderDialog.h"
13 
14 #include "MainWindow.h"
15 #include "Document.h"
16 #include "MapView.h"
17 #include "Projection.h"
18 #include "Layer.h"
19 #include "Features.h"
20 #include "MerkaartorPreferences.h"
21 #include "MasPaintStyle.h"
22 #include "PictureViewerDialog.h"
23 
24 #include <QPrinter>
25 #include <QPrintPreviewDialog>
26 #include <QPrintPreviewWidget>
27 
28 #include <QMainWindow>
29 #include <QProgressDialog>
30 #include <QPainter>
31 #include <QSvgGenerator>
32 #include <QFileDialog>
33 
NativeRenderDialog(Document * aDoc,const CoordBox & aCoordBox,QWidget * parent)34 NativeRenderDialog::NativeRenderDialog(Document *aDoc, const CoordBox& aCoordBox, QWidget *parent)
35     :QObject(parent), theDoc(aDoc), theOrigBox(aCoordBox)
36 {
37     thePrinter = new QPrinter();
38     thePrinter->setDocName(aDoc->title());
39 
40     mapview = new MapView(NULL);
41     mapview->setDocument(theDoc);
42 
43     preview = new QPrintPreviewDialog( thePrinter, parent );
44     QMainWindow* mw = preview->findChild<QMainWindow*>();
45     prtW = dynamic_cast<QPrintPreviewWidget*>(mw->centralWidget());
46 
47     QWidget* myWidget = new QWidget(preview);
48     ui.setupUi(myWidget);
49     ui.verticalLayout->addWidget(prtW);
50     mw->setCentralWidget(myWidget);
51 
52     /* Set the DPI validator to accept positive values only.  */
53     dpiValidator = new QIntValidator( ui.fieldDpi );
54     dpiValidator->setBottom( 0 );
55     ui.fieldDpi->setValidator( dpiValidator );
56 
57     /* Set the UI parameters first, before we tie in the updatePreview signal/slot. */
58     setBoundingBox(aCoordBox);
59     setOptions(M_PREFS->getRenderOptions());
60 
61     /* Tie in the updatePreview slot to the UI. */
62     connect(ui.cbShowNodes, SIGNAL(toggled(bool)), prtW, SLOT(updatePreview()));
63     connect(ui.cbShowRelations, SIGNAL(toggled(bool)), prtW, SLOT(updatePreview()));
64     connect(ui.cbShowGrid, SIGNAL(toggled(bool)), prtW, SLOT(updatePreview()));
65     connect(ui.cbShowScale, SIGNAL(toggled(bool)), prtW, SLOT(updatePreview()));
66     connect(ui.cbShowUnstyled, SIGNAL(toggled(bool)), prtW, SLOT(updatePreview()));
67     connect(ui.sbMinLat, SIGNAL(valueChanged(double)), prtW, SLOT(updatePreview()));
68     connect(ui.sbMaxLat, SIGNAL(valueChanged(double)), prtW, SLOT(updatePreview()));
69     connect(ui.sbMinLon, SIGNAL(valueChanged(double)), prtW, SLOT(updatePreview()));
70     connect(ui.sbMaxLon, SIGNAL(valueChanged(double)), prtW, SLOT(updatePreview()));
71 
72     connect(ui.btExportPDF, SIGNAL(clicked()), SLOT(exportPDF()));
73     connect(ui.btExportSVG, SIGNAL(clicked()), SLOT(exportSVG()));
74     connect(ui.btExportRaster, SIGNAL(clicked()), SLOT(exportRaster()));
75 
76     connect( preview, &QPrintPreviewDialog::paintRequested,
77              this,    &NativeRenderDialog::renderPreview );
78 }
79 
options()80 RendererOptions NativeRenderDialog::options()
81 {
82     RendererOptions opt;
83     opt.options |= RendererOptions::ForPrinting;
84     opt.options |= RendererOptions::BackgroundVisible;
85     opt.options |= RendererOptions::ForegroundVisible;
86     opt.options |= RendererOptions::TouchupVisible;
87     opt.options |= RendererOptions::NamesVisible;
88 
89     if (ui.cbShowNodes->isChecked())
90         opt.options |= RendererOptions::NodesVisible;
91     if (ui.cbShowRelations->isChecked())
92         opt.options |= RendererOptions::RelationsVisible;
93     if (ui.cbShowScale->isChecked())
94         opt.options |= RendererOptions::ScaleVisible;
95     if (ui.cbShowGrid->isChecked())
96         opt.options |= RendererOptions::LatLonGridVisible;
97     if (!ui.cbShowUnstyled->isChecked())
98         opt.options |= RendererOptions::UnstyledHidden;
99 
100     return opt;
101 }
102 
setOptions(RendererOptions aOpt)103 void NativeRenderDialog::setOptions(RendererOptions aOpt)
104 {
105     ui.cbShowNodes->setChecked(aOpt.options & RendererOptions::NodesVisible);
106     ui.cbShowRelations->setChecked(aOpt.options & RendererOptions::RelationsVisible);
107     ui.cbShowScale->setChecked(aOpt.options & RendererOptions::ScaleVisible);
108     ui.cbShowGrid->setChecked(aOpt.options & RendererOptions::LatLonGridVisible);
109     ui.cbShowUnstyled->setChecked(!(aOpt.options & RendererOptions::UnstyledHidden));
110 
111     prtW->updatePreview();
112 }
113 
boundingBox()114 CoordBox NativeRenderDialog::boundingBox()
115 {
116     CoordBox VP(Coord(
117                     ui.sbMinLon->value(),
118                     ui.sbMinLat->value()
119             ), Coord(
120                     ui.sbMaxLon->value(),
121                     ui.sbMaxLat->value()
122                     ));
123     return VP;
124 }
125 
setBoundingBox(CoordBox aBBox)126 void NativeRenderDialog::setBoundingBox(CoordBox aBBox)
127 {
128     ui.sbMinLat->setValue(aBBox.bottomLeft().y());
129     ui.sbMaxLat->setValue(aBBox.topLeft().y());
130     ui.sbMinLon->setValue(aBBox.topLeft().x());
131     ui.sbMaxLon->setValue(aBBox.topRight().x());
132 
133     prtW->updatePreview();
134 }
135 
exec()136 int NativeRenderDialog::exec()
137 {
138     return preview->exec();
139 }
140 
renderPreview(QPrinter * printer)141 void NativeRenderDialog::renderPreview(QPrinter* printer)
142 {
143     /* Set the preview resolution. Having full resolution just for preview
144      * could result in huge delay when opening the dialog the first time. */
145     printer->setResolution(96);
146     QPainter P(printer);
147     P.setRenderHint(QPainter::Antialiasing);
148     QRect theR = printer->pageRect();
149     qDebug() << "Rendering preview to:" << theR;
150     theR.moveTo(0, 0);
151     render(P, theR, options());
152 }
153 
render(QPainter & P,QRect theR,RendererOptions opt)154 void NativeRenderDialog::render(QPainter& P, QRect theR, RendererOptions opt)
155 {
156     P.setClipRect(theR);
157     P.setClipping(true);
158     P.setRenderHint(QPainter::Antialiasing);
159 
160     mapview->setGeometry(theR);
161     mapview->setViewport(boundingBox(), theR);
162     mapview->setRenderOptions(opt);
163     mapview->invalidate(true, true, false);
164     mapview->drawFeaturesSync(P);
165     if (opt.options & RendererOptions::ScaleVisible)
166         mapview->drawScale(P);
167     if (opt.options & RendererOptions::LatLonGridVisible)
168         mapview->drawLatLonGrid(P);
169 }
170 
setPrinterOptions()171 void NativeRenderDialog::setPrinterOptions() {
172     int userDpi = ui.fieldDpi->currentText().toInt();
173     thePrinter->setResolution(userDpi);
174 }
175 
exportPDF()176 void NativeRenderDialog::exportPDF()
177 {
178     QString s;
179     QFileDialog dlg(NULL, tr("Output filename"), QString("%1/%2.pdf").arg(M_PREFS->getworkingdir()).arg(tr("untitled")), tr("PDF files (*.pdf)") + "\n" + tr("All Files (*)"));
180     dlg.setFileMode(QFileDialog::AnyFile);
181     dlg.setDefaultSuffix("pdf");
182     dlg.setAcceptMode(QFileDialog::AcceptSave);
183 
184     if (dlg.exec()) {
185         if (dlg.selectedFiles().size())
186             s = dlg.selectedFiles()[0];
187     }
188 //    QString s = QFileDialog::getSaveFileName(NULL,tr("Output filename"),"",tr("PDF files (*.pdf)"));
189     if (s.isNull())
190         return;
191 
192     thePrinter->setOutputFormat(QPrinter::PdfFormat);
193     thePrinter->setOutputFileName(s);
194     setPrinterOptions();
195 
196     QPainter P(thePrinter);
197     P.setRenderHint(QPainter::Antialiasing);
198     QRect theR = thePrinter->pageRect();
199     theR.moveTo(0, 0);
200     RendererOptions opt = options();
201     opt.options |= RendererOptions::PrintAllLabels;
202     render(P, theR, opt);
203 }
204 
exportRaster()205 void NativeRenderDialog::exportRaster()
206 {
207     QString s;
208     QFileDialog dlg(NULL, tr("Output filename"), QString("%1/%2.png").arg(M_PREFS->getworkingdir()).arg(tr("untitled")), tr("Image files (*.png *.jpg)") + "\n" + tr("All Files (*)"));
209     dlg.setFileMode(QFileDialog::AnyFile);
210     dlg.setDefaultSuffix("png");
211     dlg.setAcceptMode(QFileDialog::AcceptSave);
212 
213     if (dlg.exec()) {
214         if (dlg.selectedFiles().size())
215             s = dlg.selectedFiles()[0];
216     }
217 //    QString s = QFileDialog::getSaveFileName(NULL,tr("Output filename"),"",tr("Image files (*.png *.jpg)"));
218     if (s.isNull())
219         return;
220 
221     setPrinterOptions();
222 
223     QRect theR = thePrinter->pageRect();
224     theR.moveTo(0, 0);
225 
226     QPixmap pix(theR.size());
227     if (M_PREFS->getUseShapefileForBackground())
228         pix.fill(M_PREFS->getWaterColor());
229     else if (M_PREFS->getBackgroundOverwriteStyle() || !M_STYLE->getGlobalPainter().getDrawBackground())
230         pix.fill(M_PREFS->getBgColor());
231     else
232         pix.fill(M_STYLE->getGlobalPainter().getBackgroundColor());
233 
234     QPainter P(&pix);
235     P.setRenderHint(QPainter::Antialiasing);
236     render(P, theR, options());
237 
238     pix.save(s);
239 }
240 
exportSVG()241 void NativeRenderDialog::exportSVG()
242 {
243     QString s;
244     QFileDialog dlg(NULL, tr("Output filename"), QString("%1/%2.svg").arg(M_PREFS->getworkingdir()).arg(tr("untitled")), tr("SVG files (*.svg)") + "\n" + tr("All Files (*)"));
245     dlg.setFileMode(QFileDialog::AnyFile);
246     dlg.setDefaultSuffix("svg");
247     dlg.setAcceptMode(QFileDialog::AcceptSave);
248 
249     if (dlg.exec()) {
250         if (dlg.selectedFiles().size())
251             s = dlg.selectedFiles()[0];
252     }
253 //    QString s = QFileDialog::getSaveFileName(NULL,tr("Output filename"),"",tr("SVG files (*.svg)"));
254     if (s.isNull())
255         return;
256 
257     setPrinterOptions();
258 
259     QSvgGenerator svgg;
260     QRect theR = thePrinter->pageRect();
261     theR.moveTo(0, 0);
262     svgg.setSize(theR.size());
263     svgg.setFileName(s);
264 #if QT_VERSION >= 0x040500
265         svgg.setViewBox(theR);
266 #endif
267 
268     QPainter P(&svgg);
269     P.setRenderHint(QPainter::Antialiasing);
270     RendererOptions opt = options();
271     opt.options |= RendererOptions::PrintAllLabels;
272 
273     render(P, theR, opt);
274 }
275 
276