Quantum GIS API Documentation
1.8
|
00001 /*************************************************************************** 00002 qgsquickprint.cpp 00003 A class to quickly print a map with minimal effort. 00004 ------------------- 00005 begin : Jan 2008 00006 copyright : (c) Tim Sutton, 2008 00007 email : [email protected] 00008 00009 *************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 // 00019 // QGIS Specific includes 00020 // 00021 00022 #include <qgisinterface.h> 00023 #include <qgisgui.h> 00024 #include "qgsquickprint.h" 00025 #include <qgsapplication.h> 00026 #include <qgsmaplayerregistry.h> 00027 #include <qgsvectorlayer.h> 00028 #include <qgssymbol.h> 00029 #include <qgsmapcanvas.h> 00030 #include <qgsrenderer.h> 00031 #include <qgslogger.h> 00032 #include <qgslabelattributes.h> 00033 #include <qgslabel.h> 00034 00035 // 00036 // Qt4 Related Includes 00037 // 00038 00039 #include <QAction> 00040 #include <QToolBar> 00041 #include <QColor> 00042 #include <QPainter> 00043 #include <QDate> 00044 #include <QPixmap> 00045 #include <QString> 00046 #include <QSettings> 00047 #include <QSvgRenderer> 00048 #include <QLinearGradient> 00049 00050 //other includes 00051 #include <cmath> 00052 00053 #ifdef _MSC_VER 00054 #define round(x) ((x) >= 0 ? floor((x)+0.5) : floor((x)-0.5)) 00055 #endif 00056 00057 QgsQuickPrint::QgsQuickPrint() 00058 { 00059 mPageSize = QPrinter::A4; 00060 } 00061 00062 QgsQuickPrint::~QgsQuickPrint() 00063 { 00064 00065 } 00066 void QgsQuickPrint::setTitle( QString theText ) 00067 { 00068 mTitleText = theText; 00069 } 00070 void QgsQuickPrint::setName( QString theText ) 00071 { 00072 mNameText = theText; 00073 } 00074 void QgsQuickPrint::setCopyright( QString theText ) 00075 { 00076 mCopyrightText = theText; 00077 } 00078 void QgsQuickPrint::setNorthArrow( QString theFileName ) 00079 { 00080 mNorthArrowFile = theFileName; 00081 } 00082 void QgsQuickPrint::setLogo1( QString theFileName ) 00083 { 00084 mLogo1File = theFileName; 00085 QgsDebugMsg( QString( "Logo1 set to: %1" ).arg( mLogo1File ) ); 00086 } 00087 void QgsQuickPrint::setLogo2( QString theFileName ) 00088 { 00089 mLogo2File = theFileName; 00090 QgsDebugMsg( QString( "Logo2 set to: %1" ).arg( mLogo2File ) ); 00091 } 00092 void QgsQuickPrint::setOutputPdf( QString theFileName ) 00093 { 00094 mOutputFileName = theFileName; 00095 } 00096 void QgsQuickPrint::setMapCanvas( QgsMapCanvas * thepMapCanvas ) 00097 { 00098 mpMapRenderer = thepMapCanvas->mapRenderer(); 00099 mMapBackgroundColor = thepMapCanvas->canvasColor(); 00100 } 00101 void QgsQuickPrint::setMapRenderer( QgsMapRenderer * thepMapRenderer ) 00102 { 00103 mpMapRenderer = thepMapRenderer; 00104 } 00105 void QgsQuickPrint::setMapBackgroundColor( QColor theColor ) 00106 { 00107 mMapBackgroundColor = theColor; 00108 } 00109 void QgsQuickPrint::setPageSize( QPrinter::PageSize theSize ) 00110 { 00111 mPageSize = theSize; 00112 } 00113 00114 void QgsQuickPrint::printMap() 00115 { 00116 if ( mOutputFileName.isEmpty() ) 00117 { 00118 return; 00119 } 00120 if ( mpMapRenderer == NULL ) 00121 { 00122 return; 00123 } 00124 //ensure the user never omitted the extension from the file name 00125 if ( !mOutputFileName.toUpper().endsWith( ".PDF" ) ) 00126 { 00127 mOutputFileName += ".pdf"; 00128 } 00129 00130 // Initialising the printer this way lets us find out what 00131 // the screen resolution is which we store and then 00132 // reset the resolution of the printer after that... 00133 QPrinter myPrinter( QPrinter::ScreenResolution ); 00134 00135 // Try to force the printer resolution to 300dpi 00136 // to get past platform specific defaults in printer 00137 // resolution... 00138 // 00139 int myPrintResolutionDpi = 300; 00140 myPrinter.setResolution( myPrintResolutionDpi ); 00141 myPrinter.setOutputFormat( QPrinter::PdfFormat ); 00142 QgsDebugMsg( QString( "Printing to page size %1" ).arg( pageSizeToString( mPageSize ) ) ); 00143 myPrinter.setPageSize( mPageSize ); 00144 myPrinter.setOutputFileName( mOutputFileName ); 00145 myPrinter.setOrientation( QPrinter::Landscape ); 00146 myPrinter.setDocName( "quickprint Report" ); 00147 QPainter myPrintPainter( &myPrinter ); 00148 myPrintPainter.setPen( Qt::gray ); 00149 myPrintPainter.setBrush( Qt::white ); 00150 // This is what we are aiming for: 00151 // a 00152 // +-(1)------ Acme Maps (2) --------------------------------------+ 00153 // |b 12/01/2007 (3) | 00154 // | Earthquakes (4) | 00155 // | +--(5)--------------------------------------------------------+ | 00156 // | |c | | 00157 // | | +-(6)---------------------------------------+ +~(7)~~~~~~+ | | 00158 // | | | | | | | | 00159 // | | | | | | | | 00160 // | | | | | | | | 00161 // | | | | | | | | 00162 // | | | | | | | | 00163 // | | | | | | | | 00164 // | | | | | | | | 00165 // | | | | | | | | 00166 // | | | | | | | | 00167 // | | | | | | | | 00168 // | | | | | | | | 00169 // | | +-------------------------------------------+ +~~~~~~~~~~+ | | 00170 // | | | | 00171 // | +-------------------------------------------------------------+ | 00172 // | | 00173 // | +-(8)-----+ +-(9-)----+ +-(10)----+ /|\ | 00174 // | | | |Copyright| | | / | \ | 00175 // | | | | 2008 | | | |(11) | 00176 // | +---------+ +---------+ +---------+ | 00177 // | +~(12)~~~~~~+ | 00178 // +-----------------------------------------------------------------+ 00179 // 00180 // 1) PageBorder 8) Logo1 00181 // 2) PageTitle 9) CopyrightText 00182 // 3) MapDate 10) Logo2 00183 // 4) MapTitle 11) NorthArrow 00184 // 5) MapFrame 12) ScaleBar 00185 // 6) MapPixmap 00186 // 7) LegendPixmap 00187 // a OriginXY 00188 // b HorizontalSpacing 00189 // c VerticalSpacing 00190 00191 // 00192 // Note: Different operating systems will use different 00193 // page resolutions for QPrinter::HighResolution so I'm 00194 // working all coordinates out as percentages of page 00195 // size so that we can hopefully get comarable print 00196 // results on all platforms. 00197 // 00198 00199 // 00200 // Note #2: Im defining all measurements here as my plan 00201 // is to later support templates with different page 00202 // layouts and paper sizes etc. 00203 // 00204 00205 00206 //set the top left origin for the print layout 00207 int myOriginX = myPrinter.pageRect().left(); 00208 int myOriginY = myPrinter.pageRect().top(); 00209 int myDrawableWidth = myPrinter.pageRect().width() - myOriginX; 00210 int myDrawableHeight = myPrinter.pageRect().height() - myOriginY; 00211 00212 //define the spacing between layout elements 00213 int myHorizontalSpacing = myDrawableWidth / 100; // 1% 00214 int myVerticalSpacing = myDrawableHeight / 100; // 1% 00215 00216 //define the proportions for the page layout 00217 int myMapWidthPercent = 65; 00218 int myMapHeightPercent = 71; 00219 int myLegendWidthPercent = 25; 00220 int myLegendHeightPercent = 65; 00221 int myLogoWidthPercent = 23; 00222 int myLogoHeightPercent = 17; 00223 // 00224 // Remember the size and dpi of the maprender 00225 // so we can restore it properly 00226 // 00227 int myOriginalDpi = mpMapRenderer->outputDpi(); 00228 //sensible default to prevent divide by zero 00229 if ( 0 == myOriginalDpi ) 00230 myOriginalDpi = 96; 00231 QSize myOriginalSize = mpMapRenderer->outputSize(); 00232 00233 //define the font sizes and family 00234 int myMapTitleFontSize = 24; 00235 int myMapDateFontSize = 16; 00236 int myMapNameFontSize = 32; 00237 int myLegendFontSize = 12; 00238 #ifdef Q_OS_LINUX//this sucks... 00239 myLegendFontSize -= 2; 00240 #endif 00241 00242 #ifdef WIN32 //this sucks too... 00243 myMapTitleFontSize /= 2; 00244 myMapDateFontSize /= 2; 00245 myMapNameFontSize /= 2; 00246 myLegendFontSize /= 2; 00247 #endif 00248 QString myFontFamily = "Arial"; 00249 00250 // 00251 // Draw the PageBorder 00252 // 00253 myPrintPainter.drawRect( 00254 myOriginX, myOriginY, myDrawableWidth, myDrawableHeight ); 00255 // 00256 // Draw the PageTitle 00257 // 00258 QFont myTitleFont( myFontFamily, myMapTitleFontSize ); 00259 myPrintPainter.setFont( myTitleFont ); 00260 QFontMetrics myTitleMetrics( myTitleFont, &myPrinter ); 00261 int myPageTitleHeight = myTitleMetrics.height(); 00262 int myPageTitleWidth = myTitleMetrics.width( mTitleText ); 00263 myOriginX += myHorizontalSpacing; 00264 myOriginY -= ( myPageTitleHeight / 2 ); 00265 QRect myPageTitleRect( myOriginX, 00266 myOriginY, 00267 myPageTitleWidth, 00268 myPageTitleHeight ); 00269 // make sure the title goes onto a white background 00270 myPrintPainter.setPen( Qt::white ); 00271 myPrintPainter.drawRect( myPageTitleRect ); 00272 myPrintPainter.setPen( Qt::black ); 00273 myPrintPainter.drawText( myPageTitleRect, Qt::AlignCenter, mTitleText ); 00274 00275 // 00276 // Draw the MapDate 00277 // 00278 QFont myDateFont( myFontFamily, myMapDateFontSize ); 00279 QString myDateText( QDate::currentDate().toString( Qt::LocalDate ) ); 00280 myPrintPainter.setFont( myDateFont ); 00281 QFontMetrics myDateMetrics( myDateFont, &myPrinter ); 00282 int myDateHeight = myDateMetrics.height(); 00283 //int myDateWidth = myDateMetrics.width(myDateText); 00284 myOriginX += myHorizontalSpacing; 00285 myOriginY += myPageTitleHeight + myVerticalSpacing ; 00286 QRect myDateRect( myOriginX, 00287 myOriginY, 00288 myPageTitleWidth, //use same width as page title for centering 00289 myDateHeight ); 00290 // make sure the title goes onto a white background 00291 myPrintPainter.setPen( Qt::white ); 00292 myPrintPainter.drawRect( myDateRect ); 00293 myPrintPainter.setPen( Qt::black ); 00294 myPrintPainter.drawText( myDateRect, Qt::AlignCenter, myDateText ); 00295 00296 // 00297 // Draw the MapName 00298 // 00299 QFont myNameFont( myFontFamily, myMapNameFontSize ); 00300 myPrintPainter.setFont( myNameFont ); 00301 QFontMetrics myNameMetrics( myNameFont, &myPrinter ); 00302 int myNameHeight = myNameMetrics.height(); 00303 int myNameWidth = myNameMetrics.width( mNameText ); 00304 myOriginX = myPrinter.pageRect().left() + myDrawableWidth / 2; //page center 00305 myOriginX -= myNameWidth / 2; 00306 myOriginY = myPrinter.pageRect().top() + ( myPageTitleHeight / 2 ) + myVerticalSpacing ; 00307 QRect myNameRect( myOriginX, 00308 myOriginY, 00309 myNameWidth, 00310 myNameHeight ); 00311 // make sure the title goes onto a white background 00312 myPrintPainter.setPen( Qt::white ); 00313 myPrintPainter.drawRect( myNameRect ); 00314 myPrintPainter.setPen( Qt::black ); 00315 myPrintPainter.drawText( myNameRect, Qt::AlignCenter, mNameText ); 00316 00317 // 00318 // Draw the MapFrame (top) 00319 // 00320 int myMapFrameWidth = myDrawableWidth ; 00321 myOriginX = myPrinter.pageRect().left() + myHorizontalSpacing; 00322 myOriginY += myNameHeight + myVerticalSpacing; 00323 QLine myMapFrameTopLine( myOriginX, 00324 myOriginY, 00325 myMapFrameWidth, 00326 myOriginY ); 00327 myPrintPainter.setPen( Qt::black ); 00328 myPrintPainter.drawLine( myMapFrameTopLine ); 00329 00330 00331 // Draw the map onto a pixmap 00332 // @TODO: we need to save teh extent of the screen map and 00333 // then set them again for the print map so that the map scales 00334 // properly in the print 00335 int myMapDimensionX = ( myDrawableWidth / 100 ) * myMapHeightPercent; 00336 int myMapDimensionY = ( myDrawableHeight / 100 ) * myMapWidthPercent; 00337 00338 QImage myMapImage( QSize( myMapDimensionX, myMapDimensionY ), QImage::Format_ARGB32 ); 00339 myMapImage.setDotsPerMeterX(( double )( myPrinter.logicalDpiX() ) / 25.4 * 1000.0 ); 00340 myMapImage.setDotsPerMeterY(( double )( myPrinter.logicalDpiY() ) / 25.4 * 1000.0 ); 00341 myMapImage.fill( 0 ); 00342 QPainter myMapPainter; 00343 myMapPainter.begin( &myMapImage ); 00344 // Now resize for print 00345 mpMapRenderer->setOutputSize( QSize( myMapDimensionX, myMapDimensionY ), ( myPrinter.logicalDpiX() + myPrinter.logicalDpiY() ) / 2 ); 00346 mpMapRenderer->render( &myMapPainter ); 00347 00348 myMapPainter.end(); 00349 //draw the map pixmap onto our pdf print device 00350 myOriginX = myPrinter.pageRect().left() + myHorizontalSpacing; 00351 myOriginY += myVerticalSpacing * 2; 00352 00353 myPrintPainter.drawImage( myOriginX, myOriginY, myMapImage ); 00354 00355 // 00356 // Draw the legend 00357 // 00358 QFont myLegendFont( myFontFamily, myLegendFontSize ); 00359 //myPrintPainter.setFont(myLegendFont); 00360 int myLegendDimensionX = ( myDrawableWidth / 100 ) * myLegendWidthPercent; 00361 int myLegendDimensionY = ( myDrawableHeight / 100 ) * myLegendHeightPercent; 00362 00363 00364 // Create a viewport to make coordinate conversions easier 00365 // The viewport has the same dimensions as the page(otherwise items 00366 // drawn into it will appear squashed), but a different origin. 00367 QRect myOriginalViewport = myPrintPainter.viewport(); //for restoring later 00368 myOriginX += myMapDimensionX + myHorizontalSpacing; 00369 myPrintPainter.setViewport( myOriginX, 00370 myOriginY, 00371 myOriginalViewport.width(), 00372 myOriginalViewport.height() ); 00373 //draw a rectangale around the legend frame 00374 //@TODO make this user settable 00375 if ( 0 == 1 ) //put some real logic here 00376 { 00377 myPrintPainter.drawRect( 0, 0, myLegendDimensionX, myLegendDimensionY ); 00378 } 00379 //get font metric and other vars needed 00380 QFontMetrics myLegendFontMetrics( myLegendFont, &myPrinter ); 00381 int myLegendFontHeight = myLegendFontMetrics.height(); 00382 int myLegendXPos = 0; 00383 int myLegendYPos = 0; 00384 int myLegendSpacer = myLegendFontHeight / 2; //for vertical and horizontal spacing 00385 int myLegendVerticalSpacer = myLegendFontHeight / 3; //for vertical between rows 00386 int myIconWidth = myLegendFontHeight; 00387 myPrintPainter.setFont( myLegendFont ); 00388 QStringList myLayerSet = mpMapRenderer->layerSet(); 00389 QStringListIterator myLayerIterator( myLayerSet ); 00390 //second clause below is to prevent legend spilling out the bottom 00391 while ( myLayerIterator.hasNext() && 00392 myLegendYPos < myLegendDimensionY ) 00393 { 00394 QString myLayerId = myLayerIterator.next(); 00395 QgsMapLayer * mypLayer = 00396 QgsMapLayerRegistry::instance()->mapLayer( myLayerId ); 00397 if ( mypLayer ) 00398 { 00399 QgsVectorLayer *mypVectorLayer = 00400 qobject_cast<QgsVectorLayer *>( mypLayer ); 00401 // TODO: add support for symbology-ng renderers 00402 if ( mypVectorLayer && mypVectorLayer->renderer() ) 00403 { 00404 QString myLayerName = mypVectorLayer->name(); 00405 QIcon myIcon; 00406 QPixmap myPixmap( QSize( myIconWidth, myIconWidth ) ); //square 00407 //based on code from qgslegendlayer.cpp - see that file for more info 00408 const QgsRenderer* mypRenderer = mypVectorLayer->renderer(); 00409 const QList<QgsSymbol*> mySymbolList = mypRenderer->symbols(); 00410 // 00411 // Single symbol 00412 // 00413 double widthScale = ( myPrinter.logicalDpiX() + myPrinter.logicalDpiY() ) / 2.0 / 25.4; 00414 00415 if ( 1 == mySymbolList.size() ) 00416 { 00417 QgsSymbol * mypSymbol = mySymbolList.at( 0 ); 00418 myPrintPainter.setPen( mypSymbol->pen() ); 00419 myPrintPainter.setBrush( mypSymbol->brush() ); 00420 myLegendXPos = 0 ; 00421 if ( mypSymbol->type() == QGis::Point ) 00422 { 00423 QImage myImage; 00424 myImage = mypSymbol->getPointSymbolAsImage( widthScale ); 00425 myPrintPainter.drawImage( myLegendXPos, myLegendYPos, myImage ); 00426 } 00427 else if ( mypSymbol->type() == QGis::Line ) 00428 { 00429 myPrintPainter.drawLine( myLegendXPos, myLegendYPos, 00430 myLegendXPos + myIconWidth, 00431 myLegendYPos + myIconWidth ); 00432 } 00433 else //polygon 00434 { 00435 myPrintPainter.drawRect( myLegendXPos, myLegendYPos, myIconWidth, myIconWidth ); 00436 } 00437 myLegendXPos += myIconWidth + myLegendSpacer; 00438 myPrintPainter.setPen( Qt::black ); 00439 QStringList myWrappedLayerNameList = wordWrap( myLayerName, 00440 myLegendFontMetrics, 00441 myLegendDimensionX - myIconWidth ); 00442 // 00443 // Loop through wrapped legend label lines 00444 // 00445 QStringListIterator myLineWrapIterator( myWrappedLayerNameList ); 00446 while ( myLineWrapIterator.hasNext() ) 00447 { 00448 QString myLine = myLineWrapIterator.next(); 00449 QRect myLegendItemRect( myLegendXPos, 00450 myLegendYPos, 00451 myLegendDimensionX - myIconWidth, 00452 myLegendFontHeight ); 00453 myPrintPainter.drawText( myLegendItemRect, Qt::AlignLeft, myLine ); 00454 myLegendYPos += myLegendVerticalSpacer + myLegendFontHeight; 00455 } 00456 } 00457 else //class breaks 00458 { 00459 // draw in the layer name first, after we loop for the class breaks 00460 QStringList myWrappedLayerNameList = wordWrap( myLayerName, 00461 myLegendFontMetrics, 00462 myLegendDimensionX - myIconWidth ); 00463 // Check the wrapped layer name wont overrun the space we have 00464 // for the legend ... 00465 int myLabelHeight = myLegendFontHeight * 00466 myWrappedLayerNameList.count(); 00467 if ( myLegendYPos + myLabelHeight > myLegendDimensionY ) 00468 { 00469 continue; 00470 } 00471 00472 // 00473 // Loop through wrapped legend label lines 00474 // 00475 QStringListIterator myLineWrapIterator( myWrappedLayerNameList ); 00476 while ( myLineWrapIterator.hasNext() ) 00477 { 00478 QString myLine = myLineWrapIterator.next(); 00479 myLegendXPos = myIconWidth; 00480 QRect myLegendItemRect( myLegendXPos, 00481 myLegendYPos, 00482 myLegendFontMetrics.width( myLine ), 00483 myLegendFontHeight ); 00484 myPrintPainter.setPen( Qt::black ); 00485 myPrintPainter.drawText( myLegendItemRect, Qt::AlignLeft, myLine ); 00486 myLegendYPos += myLegendVerticalSpacer + myLegendFontHeight; 00487 } 00488 // 00489 // Loop through the class breaks 00490 // 00491 QListIterator<QgsSymbol *> myIterator( mySymbolList ); 00492 while ( myIterator.hasNext() && myLegendYPos < myLegendDimensionY ) 00493 { 00494 QgsSymbol * mypSymbol = myIterator.next(); 00495 myPrintPainter.setPen( mypSymbol->pen() ); 00496 myPrintPainter.setBrush( mypSymbol->brush() ); 00497 myLegendXPos = myLegendSpacer * 3; //extra indent for class breaks 00498 if ( mypSymbol->type() == QGis::Point ) 00499 { 00500 QImage myImage; 00501 myImage = mypSymbol->getPointSymbolAsImage( widthScale ); 00502 myPrintPainter.drawImage( myLegendXPos, myLegendYPos, myImage ); 00503 } 00504 else if ( mypSymbol->type() == QGis::Line ) 00505 { 00506 myPrintPainter.drawLine( myLegendXPos, myLegendYPos, 00507 myLegendXPos + myIconWidth, 00508 myLegendYPos + myIconWidth ); 00509 } 00510 else //polygon 00511 { 00512 myPrintPainter.drawRect( 00513 myLegendXPos, myLegendYPos, myIconWidth, myIconWidth ); 00514 } 00515 // 00516 // Now work out the class break label 00517 // 00518 QString myLabel; 00519 QString myLower = mypSymbol->lowerValue(); 00520 if ( !myLower.isEmpty() ) 00521 { 00522 myLabel = myLower; 00523 } 00524 QString myUpper = mypSymbol->upperValue(); 00525 if ( !myUpper.isEmpty() ) 00526 { 00527 myLabel += " - "; 00528 myLabel += myUpper; 00529 } 00530 QString myText = mypSymbol->label(); 00531 if ( !myText.isEmpty() ) 00532 { 00533 myLabel += " "; 00534 myLabel += myText; 00535 } 00536 myLabel = myLabel.trimmed(); 00537 myLegendXPos += myIconWidth + myLegendSpacer; 00538 myPrintPainter.setPen( Qt::black ); 00539 00540 QStringList myWrappedLayerNameList = wordWrap( myLabel, 00541 myLegendFontMetrics, 00542 myLegendDimensionX - myLegendXPos ); 00543 // 00544 // Loop through wrapped legend label lines 00545 // 00546 QStringListIterator myLineWrapIterator( myWrappedLayerNameList ); 00547 while ( myLineWrapIterator.hasNext() ) 00548 { 00549 QString myLine = myLineWrapIterator.next(); 00550 // check if the text will overflow the space we have 00551 QRect myLegendItemRect( myLegendXPos, 00552 myLegendYPos, 00553 myLegendDimensionX - myIconWidth, 00554 myLegendFontHeight ); 00555 myPrintPainter.drawText( myLegendItemRect, Qt::AlignLeft, myLine ); 00556 myLegendYPos += myLegendVerticalSpacer + myLegendFontHeight; 00557 } //wordwrap loop 00558 } //symbol loop 00559 } //class breaks 00560 } //if vectorlayer 00561 } //if maplayer 00562 } //layer iterator 00563 00564 //reinstate the viewport 00565 myPrintPainter.setViewport( myOriginalViewport ); 00566 00567 00568 // 00569 // Draw the MapFrame (bottom) 00570 // 00571 myOriginX = myPrinter.pageRect().left() + myHorizontalSpacing; 00572 myOriginY += myMapDimensionY + ( myVerticalSpacing * 2 ); 00573 QLine myMapFrameBottomLine( myOriginX, 00574 myOriginY, 00575 myMapFrameWidth, 00576 myOriginY ); 00577 myPrintPainter.setPen( Qt::black ); 00578 myPrintPainter.drawLine( myMapFrameBottomLine ); 00579 00580 00581 // 00582 // Draw logo 1 00583 // 00584 int myLogoXDim = ( myDrawableWidth / 100 ) * myLogoWidthPercent; 00585 int myLogoYDim = ( myDrawableHeight / 100 ) * myLogoHeightPercent; 00586 QPixmap myLogo1; 00587 QgsDebugMsg( QString( "Logo1: %1" ).arg( mLogo1File ) ); 00588 myLogo1.fill( Qt::white ); 00589 myLogo1.load( mLogo1File ); 00590 myLogo1 = myLogo1.scaled( myLogoXDim, myLogoYDim, Qt::KeepAspectRatio ); 00591 myOriginX = myPrinter.pageRect().left() + myHorizontalSpacing; 00592 myOriginY += myVerticalSpacing ; 00593 myPrintPainter.drawPixmap( myOriginX, 00594 myOriginY, 00595 myLogo1 ); 00596 00597 // 00598 // Draw Copyright Text 00599 // 00600 myOriginX += myHorizontalSpacing + myLogoXDim; 00601 QRect myCopyrightRect( myOriginX, myOriginY, myLogoXDim, myLogoYDim ); 00602 myPrintPainter.setPen( Qt::black ); 00603 QFont myCopyrightFont( myFontFamily, myMapDateFontSize ); 00604 myPrintPainter.setFont( myCopyrightFont ); 00605 //myPrintPainter.drawRect( myCopyrightRect ); 00606 myPrintPainter.drawText( myCopyrightRect, Qt::AlignCenter | Qt::TextWordWrap, mCopyrightText ); 00607 00608 // 00609 // Draw logo 2 00610 // 00611 QPixmap myLogo2; 00612 myLogo2.fill( Qt::white ); 00613 myLogo2.load( mLogo2File ); 00614 myLogo2 = myLogo2.scaled( myLogoXDim, myLogoYDim, Qt::KeepAspectRatio ); 00615 myOriginX += myHorizontalSpacing + myLogoXDim; 00616 myPrintPainter.drawPixmap( myOriginX, 00617 myOriginY, 00618 myLogo2 ); 00619 00620 // 00621 // Draw the north arrow 00622 // 00623 myOriginX += myHorizontalSpacing + myLogoXDim; 00624 // use half the available space for the n.arrow 00625 // and the rest for the scale bar (see below) 00626 QPixmap myNorthArrow( myLogoYDim / 2, myLogoYDim / 2 ); 00627 myNorthArrow.fill( Qt::white ); 00628 QPainter myNorthPainter( &myNorthArrow ); 00629 QSvgRenderer mySvgRenderer( mNorthArrowFile ); 00630 mySvgRenderer.render( &myNorthPainter ); 00631 myPrintPainter.drawPixmap( myOriginX + (( myLogoXDim / 2 ) ), 00632 myOriginY, 00633 myNorthArrow ); 00634 00635 // 00636 // Draw the scale bar 00637 // 00638 myOriginY += myLogoYDim / 2 + myVerticalSpacing; 00639 myPrintPainter.setViewport( myOriginX, 00640 myOriginY, 00641 myOriginalViewport.width(), 00642 myOriginalViewport.height() ); 00643 renderPrintScaleBar( &myPrintPainter, mpMapRenderer, myLogoXDim ); 00644 myPrintPainter.setViewport( myOriginalViewport ); 00645 00646 // 00647 // Finish up 00648 // 00649 00650 00651 myPrintPainter.end(); 00652 #if 0 00653 mProgressDialog.setValue( 0 ); 00654 mProgressDialog.setLabelText( tr( "Please wait while your report is generated", "COMMENTED OUT" ) ); 00655 mProgressDialog.show(); 00656 mProgressDialog.setWindowModality( Qt::WindowModal ); 00657 mProgressDialog.setAutoClose( true ); 00658 #endif 00659 // 00660 // Restore the map render to its former glory 00661 // 00662 mpMapRenderer->setOutputSize( myOriginalSize, myOriginalDpi ); 00663 } 00664 00665 void QgsQuickPrint::scaleTextLabels( int theScaleFactor, SymbolScalingType theDirection ) 00666 { 00667 if ( 0 >= theScaleFactor ) 00668 { 00669 QgsDebugMsg( "invalid scale factor" ); 00670 return; 00671 } 00672 QStringList myLayerSet = mpMapRenderer->layerSet(); 00673 QStringListIterator myLayerIterator( myLayerSet ); 00674 while ( myLayerIterator.hasNext() ) 00675 { 00676 QString myLayerId = myLayerIterator.next(); 00677 QgsDebugMsg( "Scaling text labels for print for " + myLayerId ); 00678 QgsMapLayer * mypLayer = 00679 QgsMapLayerRegistry::instance()->mapLayer( myLayerId ); 00680 if ( mypLayer ) 00681 { 00682 QgsVectorLayer *mypVectorLayer = 00683 qobject_cast<QgsVectorLayer *>( mypLayer ); 00684 if ( mypVectorLayer ) 00685 { 00686 QgsLabel * mypLabel = mypVectorLayer->label(); 00687 QgsLabelAttributes * mypLabelAttributes = mypLabel->labelAttributes(); 00688 if ( theDirection == ScaleUp ) 00689 { 00690 mypLabelAttributes->setSize( 00691 mypLabelAttributes->size() * theScaleFactor, 00692 mypLabelAttributes->sizeType() ); 00693 } 00694 else //scale down 00695 { 00696 mypLabelAttributes->setSize( 00697 mypLabelAttributes->size() / theScaleFactor, 00698 mypLabelAttributes->sizeType() ); 00699 } 00700 } //if vectorlayer 00701 } //if maplayer 00702 } //layer iterator 00703 } 00704 00705 void QgsQuickPrint::scalePointSymbols( int theScaleFactor, SymbolScalingType theDirection ) 00706 { 00707 if ( 0 >= theScaleFactor ) 00708 { 00709 QgsDebugMsg( "invalid scale factor" ); 00710 return; 00711 } 00712 QStringList myLayerSet = mpMapRenderer->layerSet(); 00713 QStringListIterator myLayerIterator( myLayerSet ); 00714 while ( myLayerIterator.hasNext() ) 00715 { 00716 QString myLayerId = myLayerIterator.next(); 00717 QgsDebugMsg( "Scaling point symbols for print for " + myLayerId ); 00718 QgsMapLayer * mypLayer = 00719 QgsMapLayerRegistry::instance()->mapLayer( myLayerId ); 00720 if ( mypLayer ) 00721 { 00722 QgsVectorLayer *mypVectorLayer = 00723 qobject_cast<QgsVectorLayer *>( mypLayer ); 00724 if ( mypVectorLayer ) 00725 { 00726 const QgsRenderer* mypRenderer = mypVectorLayer->renderer(); 00727 const QList<QgsSymbol*> mySymbolList = mypRenderer->symbols(); 00728 // 00729 // Single symbol 00730 // 00731 if ( 1 == mySymbolList.size() ) 00732 { 00733 QgsSymbol * mypSymbol = mySymbolList.at( 0 ); 00734 if ( mypSymbol->type() == QGis::Point ) 00735 { 00736 if ( theDirection == ScaleUp ) 00737 { 00738 mypSymbol->setPointSize( mypSymbol->pointSize() * theScaleFactor ); 00739 } 00740 else //Scale Down 00741 { 00742 mypSymbol->setPointSize( mypSymbol->pointSize() / theScaleFactor ); 00743 } 00744 } 00745 } 00746 else //class breaks 00747 { 00748 QListIterator<QgsSymbol *> myIterator( mySymbolList ); 00749 while ( myIterator.hasNext() ) 00750 { 00751 QgsSymbol * mypSymbol = myIterator.next(); 00752 if ( mypSymbol->type() == QGis::Point ) 00753 { 00754 if ( theDirection == ScaleUp ) 00755 { 00756 mypSymbol->setPointSize( mypSymbol->pointSize() * theScaleFactor ); 00757 } 00758 else //Scale Down 00759 { 00760 mypSymbol->setPointSize( mypSymbol->pointSize() / theScaleFactor ); 00761 } 00762 } 00763 } //symbol loop 00764 } //class breaks 00765 } //if vectorlayer 00766 } //if maplayer 00767 } //layer iterator 00768 } 00769 00770 00771 00772 void QgsQuickPrint::renderPrintScaleBar( QPainter * thepPainter, 00773 QgsMapRenderer * thepMapRenderer, 00774 int theMaximumWidth ) 00775 { 00776 //hard coding some options for now 00777 bool mySnappingFlag = true; 00778 QColor mColor = Qt::black; 00779 // Hard coded sizes 00780 int myTextOffsetX = 0; 00781 int myTextOffsetY = 5; 00782 int myXMargin = 20; 00783 int myYMargin = 20; 00784 int myPreferredSize = theMaximumWidth - ( myXMargin * 2 ); 00785 double myActualSize = 0; 00786 int myBufferSize = 1; //softcode this later 00787 QColor myBackColor = Qt::white; //used for text 00788 QColor myForeColor = Qt::black; //used for text 00789 00790 //Get canvas dimensions 00791 //int myCanvasHeight = thepMapCanvas->height(); 00792 00793 //Get map units per pixel. This can be negative at times (to do with 00794 //projections) and that just confuses the rest of the code in this 00795 //function, so force to a positive number. 00796 double myMapUnitsPerPixelDouble = qAbs( thepMapRenderer->mapUnitsPerPixel() ); 00797 // 00798 // Exit if the canvas width is 0 or layercount is 0 or QGIS will freeze 00799 int myLayerCount = thepMapRenderer->layerSet().count(); 00800 if ( !myLayerCount || !myMapUnitsPerPixelDouble ) 00801 return; 00802 00803 //Calculate size of scale bar for preferred number of map units 00804 double myScaleBarWidth = myPreferredSize; 00805 myActualSize = myScaleBarWidth * myMapUnitsPerPixelDouble; 00806 00807 00808 // Work out the exponent for the number - e.g, 1234 will give 3, 00809 // and .001234 will give -3 00810 double myPowerOf10 = floor( log10( myActualSize ) ); 00811 00812 // snap to integer < 10 times power of 10 00813 if ( mySnappingFlag ) 00814 { 00815 double scaler = pow( 10.0, myPowerOf10 ); 00816 myActualSize = round( myActualSize / scaler ) * scaler; 00817 myScaleBarWidth = myActualSize / myMapUnitsPerPixelDouble; 00818 } 00819 00820 //Get type of map units and set scale bar unit label text 00821 QGis::UnitType myMapUnits = thepMapRenderer->mapUnits(); 00822 QString myScaleBarUnitLabel; 00823 switch ( myMapUnits ) 00824 { 00825 case QGis::Meters: 00826 if ( myActualSize > 1000.0 ) 00827 { 00828 myScaleBarUnitLabel = tr( " km" ); 00829 myActualSize = myActualSize / 1000; 00830 } 00831 else if ( myActualSize < 0.01 ) 00832 { 00833 myScaleBarUnitLabel = tr( " mm" ); 00834 myActualSize = myActualSize * 1000; 00835 } 00836 else if ( myActualSize < 0.1 ) 00837 { 00838 myScaleBarUnitLabel = tr( " cm" ); 00839 myActualSize = myActualSize * 100; 00840 } 00841 else 00842 myScaleBarUnitLabel = tr( " m" ); 00843 break; 00844 case QGis::Feet: 00845 if ( myActualSize > 5280.0 ) //5280 feet to the mile 00846 { 00847 myScaleBarUnitLabel = tr( " miles" ); 00848 myActualSize = myActualSize / 5280; 00849 } 00850 else if ( myActualSize == 5280.0 ) //5280 feet to the mile 00851 { 00852 myScaleBarUnitLabel = tr( " mile" ); 00853 myActualSize = myActualSize / 5280; 00854 } 00855 else if ( myActualSize < 1 ) 00856 { 00857 myScaleBarUnitLabel = tr( " inches" ); 00858 myActualSize = myActualSize * 12; 00859 } 00860 else if ( myActualSize == 1.0 ) 00861 { 00862 myScaleBarUnitLabel = tr( " foot" ); 00863 } 00864 else 00865 { 00866 myScaleBarUnitLabel = tr( " feet" ); 00867 } 00868 break; 00869 case QGis::Degrees: 00870 if ( myActualSize == 1.0 ) 00871 myScaleBarUnitLabel = tr( " degree" ); 00872 else 00873 myScaleBarUnitLabel = tr( " degrees" ); 00874 break; 00875 case QGis::UnknownUnit: 00876 myScaleBarUnitLabel = tr( " unknown" ); 00877 default: 00878 QgsDebugMsg( "Error: not picked up map units - actual value = " 00879 + QString::number( myMapUnits ) ); 00880 }; 00881 00882 //Set font and calculate width of unit label 00883 int myFontSize = 10; //we use this later for buffering 00884 QFont myFont( "helvetica", myFontSize ); 00885 thepPainter->setFont( myFont ); 00886 QFontMetrics myFontMetrics( myFont ); 00887 double myFontWidth = myFontMetrics.width( myScaleBarUnitLabel ); 00888 double myFontHeight = myFontMetrics.height(); 00889 00890 //Set the maximum label 00891 QString myScaleBarMaxLabel = QString::number( myActualSize ); 00892 00893 //Calculate total width of scale bar and label 00894 //we divide by 2 because the max scale label 00895 //will be centered over the endpoint of the scale bar 00896 double myTotalScaleBarWidth = myScaleBarWidth + ( myFontWidth / 2 ); 00897 00898 //determine the origin of scale bar (bottom right) 00899 //for x origin set things up so the scalebar is centered 00900 int myOriginX = ( theMaximumWidth - myTotalScaleBarWidth ) / 2; 00901 int myOriginY = myYMargin; 00902 00903 //Set pen to draw with 00904 QPen myForegroundPen( mColor, 2 ); 00905 QPen myBackgroundPen( Qt::white, 3 ); 00906 00907 //Cast myScaleBarWidth to int for drawing 00908 int myScaleBarWidthInt = ( int ) myScaleBarWidth; 00909 00910 //now draw the bar itself in user selected color 00911 thepPainter->setPen( myForegroundPen ); 00912 //make a glossygradient for the background 00913 QGradientStops myStops; 00914 myStops << QGradientStop( 0.0, QColor( "#616161" ) ); 00915 myStops << QGradientStop( 0.5, QColor( "#505050" ) ); 00916 myStops << QGradientStop( 0.6, QColor( "#434343" ) ); 00917 myStops << QGradientStop( 1.0, QColor( "#656565" ) ); 00918 //draw again with the brush in the revers direction to complete teh glossiness 00919 QLinearGradient myReverseGlossyBrush( 00920 QPointF( myOriginX, myOriginY + myFontHeight*3 ), 00921 QPointF( myOriginX, myOriginY ) ); 00922 thepPainter->setBrush( myReverseGlossyBrush ); 00923 thepPainter->drawRect( 00924 myOriginX, 00925 myOriginY, 00926 myOriginX + myScaleBarWidthInt, 00927 myOriginY + myFontHeight 00928 ); 00929 00930 // 00931 //Do drawing of scale bar text 00932 // 00933 00934 00935 //Draw the minimum label buffer 00936 thepPainter->setPen( myBackColor ); 00937 myFontWidth = myFontMetrics.width( "0" ); 00938 00939 for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ ) 00940 { 00941 for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ ) 00942 { 00943 thepPainter->drawText( int( i + ( myOriginX - ( myFontWidth / 2 ) ) ), 00944 int( j + ( myOriginY - ( myFontHeight / 4 ) ) ) - myTextOffsetY, 00945 "0" ); 00946 } 00947 } 00948 00949 //Draw minimum label 00950 thepPainter->setPen( myForeColor ); 00951 00952 thepPainter->drawText( 00953 int( myOriginX - ( myFontWidth / 2 ) ), 00954 int( myOriginY - ( myFontHeight / 4 ) ) - myTextOffsetY, 00955 "0" 00956 ); 00957 00958 // 00959 //Draw maximum label 00960 // 00961 thepPainter->setPen( myBackColor ); 00962 myFontWidth = myFontMetrics.width( myScaleBarMaxLabel ); 00963 myFontHeight = myFontMetrics.height(); 00964 //first the buffer 00965 for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ ) 00966 { 00967 for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ ) 00968 { 00969 thepPainter->drawText( int( i + ( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ) ), 00970 int( j + ( myOriginY - ( myFontHeight / 4 ) ) ) - myTextOffsetY, 00971 myScaleBarMaxLabel ); 00972 } 00973 } 00974 //then the text itself 00975 thepPainter->setPen( myForeColor ); 00976 thepPainter->drawText( 00977 int( myOriginX + myScaleBarWidthInt - ( myFontWidth / 2 ) ), 00978 int( myOriginY - ( myFontHeight / 4 ) ) - myTextOffsetY, 00979 myScaleBarMaxLabel 00980 ); 00981 00982 // 00983 //Draw unit label 00984 // 00985 thepPainter->setPen( myBackColor ); 00986 myFontWidth = myFontMetrics.width( myScaleBarUnitLabel ); 00987 //first the buffer 00988 for ( int i = 0 - myBufferSize; i <= myBufferSize; i++ ) 00989 { 00990 for ( int j = 0 - myBufferSize; j <= myBufferSize; j++ ) 00991 { 00992 thepPainter->drawText( i + ( myOriginX + myScaleBarWidthInt + myTextOffsetX ), 00993 j + myOriginY + myFontHeight + ( myFontHeight*2.5 ) + myTextOffsetY, 00994 myScaleBarUnitLabel ); 00995 } 00996 } 00997 //then the text itself 00998 thepPainter->setPen( myForeColor ); 00999 thepPainter->drawText( 01000 myOriginX + myScaleBarWidthInt + myTextOffsetX, 01001 myOriginY + myFontHeight + ( myFontHeight*2.5 ) + myTextOffsetY, 01002 myScaleBarUnitLabel 01003 ); 01004 } 01005 01006 QStringList QgsQuickPrint::wordWrap( QString theString, 01007 QFontMetrics theMetrics, 01008 int theWidth ) 01009 { 01010 //iterate the string 01011 QStringList myList; 01012 QString myCumulativeLine = ""; 01013 QString myStringToPreviousSpace = ""; 01014 int myPreviousSpacePos = 0; 01015 for ( int i = 0; i < theString.count(); ++i ) 01016 { 01017 QChar myChar = theString.at( i ); 01018 if ( myChar == QChar( ' ' ) ) 01019 { 01020 myStringToPreviousSpace = myCumulativeLine; 01021 myPreviousSpacePos = i; 01022 } 01023 myCumulativeLine += myChar; 01024 if ( theMetrics.width( myCumulativeLine ) >= theWidth ) 01025 { 01026 //time to wrap 01027 //@todo deal with long strings that have no spaces 01028 //forcing a break at current pos... 01029 myList << myStringToPreviousSpace.trimmed(); 01030 i = myPreviousSpacePos; 01031 myStringToPreviousSpace = ""; 01032 myCumulativeLine = ""; 01033 } 01034 }//end of i loop 01035 //add whatever is left in the string to the list 01036 if ( !myCumulativeLine.trimmed().isEmpty() ) 01037 { 01038 myList << myCumulativeLine.trimmed(); 01039 } 01040 01041 //qDebug("Wrapped legend entry: %s\n%s", theString, myList.join("\n").toLocal8Bit().constData() ); 01042 return myList; 01043 01044 } 01045 QString QgsQuickPrint::pageSizeToString( QPrinter::PageSize theSize ) 01046 { 01047 if ( theSize == QPrinter::A0 ) return "QPrinter::A0"; 01048 if ( theSize == QPrinter::A1 ) return "QPrinter::A1"; 01049 if ( theSize == QPrinter::A2 ) return "QPrinter::A2"; 01050 if ( theSize == QPrinter::A3 ) return "QPrinter::A3"; 01051 if ( theSize == QPrinter::A4 ) return "QPrinter::A4"; 01052 if ( theSize == QPrinter::A5 ) return "QPrinter::A5"; 01053 if ( theSize == QPrinter::A6 ) return "QPrinter::A6"; 01054 if ( theSize == QPrinter::A7 ) return "QPrinter::A7"; 01055 if ( theSize == QPrinter::A8 ) return "QPrinter::A8"; 01056 if ( theSize == QPrinter::A9 ) return "QPrinter::A9"; 01057 if ( theSize == QPrinter::B0 ) return "QPrinter::B0"; 01058 if ( theSize == QPrinter::B1 ) return "QPrinter::B1"; 01059 if ( theSize == QPrinter::B10 ) return "QPrinter::B10"; 01060 if ( theSize == QPrinter::B2 ) return "QPrinter::B2"; 01061 if ( theSize == QPrinter::B3 ) return "QPrinter::B3"; 01062 if ( theSize == QPrinter::B4 ) return "QPrinter::B4"; 01063 if ( theSize == QPrinter::B5 ) return "QPrinter::B5"; 01064 if ( theSize == QPrinter::B6 ) return "QPrinter::B6"; 01065 if ( theSize == QPrinter::B7 ) return "QPrinter::B7"; 01066 if ( theSize == QPrinter::B8 ) return "QPrinter::B8"; 01067 if ( theSize == QPrinter::B9 ) return "QPrinter::B9"; 01068 if ( theSize == QPrinter::C5E ) return "QPrinter::C5E"; 01069 if ( theSize == QPrinter::Comm10E ) return "QPrinter::Comm10E"; 01070 if ( theSize == QPrinter::DLE ) return "QPrinter::DLE"; 01071 if ( theSize == QPrinter::Executive ) return "QPrinter::Executive"; 01072 if ( theSize == QPrinter::Folio ) return "QPrinter::Folio"; 01073 if ( theSize == QPrinter::Ledger ) return "QPrinter::Ledger"; 01074 if ( theSize == QPrinter::Legal ) return "QPrinter::Legal"; 01075 if ( theSize == QPrinter::Letter ) return "QPrinter::Letter"; 01076 //fallback 01077 return "QPrinter::A4"; 01078 } 01079 01080 QPrinter::PageSize QgsQuickPrint::stringToPageSize( QString theSize ) 01081 { 01082 if ( theSize == "QPrinter::A0" ) return QPrinter::A0; 01083 if ( theSize == "QPrinter::A1" ) return QPrinter::A1; 01084 if ( theSize == "QPrinter::A2" ) return QPrinter::A2; 01085 if ( theSize == "QPrinter::A3" ) return QPrinter::A3; 01086 if ( theSize == "QPrinter::A4" ) return QPrinter::A4; 01087 if ( theSize == "QPrinter::A5" ) return QPrinter::A5; 01088 if ( theSize == "QPrinter::A6" ) return QPrinter::A6; 01089 if ( theSize == "QPrinter::A7" ) return QPrinter::A7; 01090 if ( theSize == "QPrinter::A8" ) return QPrinter::A8; 01091 if ( theSize == "QPrinter::A9" ) return QPrinter::A9; 01092 if ( theSize == "QPrinter::B0" ) return QPrinter::B0; 01093 if ( theSize == "QPrinter::B1" ) return QPrinter::B1; 01094 if ( theSize == "QPrinter::B10" ) return QPrinter::B10; 01095 if ( theSize == "QPrinter::B2" ) return QPrinter::B2; 01096 if ( theSize == "QPrinter::B3" ) return QPrinter::B3; 01097 if ( theSize == "QPrinter::B4" ) return QPrinter::B4; 01098 if ( theSize == "QPrinter::B5" ) return QPrinter::B5; 01099 if ( theSize == "QPrinter::B6" ) return QPrinter::B6; 01100 if ( theSize == "QPrinter::B7" ) return QPrinter::B7; 01101 if ( theSize == "QPrinter::B8" ) return QPrinter::B8; 01102 if ( theSize == "QPrinter::B9" ) return QPrinter::B9; 01103 if ( theSize == "QPrinter::C5E" ) return QPrinter::C5E; 01104 if ( theSize == "QPrinter::Comm10E" ) return QPrinter::Comm10E; 01105 if ( theSize == "QPrinter::DLE" ) return QPrinter::DLE; 01106 if ( theSize == "QPrinter::Executive" ) return QPrinter::Executive; 01107 if ( theSize == "QPrinter::Folio" ) return QPrinter::Folio; 01108 if ( theSize == "QPrinter::Ledger" ) return QPrinter::Ledger; 01109 if ( theSize == "QPrinter::Legal" ) return QPrinter::Legal; 01110 if ( theSize == "QPrinter::Letter" ) return QPrinter::Letter; 01111 //fallback 01112 return QPrinter::A4; 01113 }