Quantum GIS API Documentation
1.7.4
|
00001 /*************************************************************************** 00002 qgscomposerpicture.cpp 00003 ------------------- 00004 begin : September 2005 00005 copyright : (C) 2005 by Radim Blazek 00006 email : radim.blazek@gmail.com 00007 ***************************************************************************/ 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 /* $Id$ */ 00018 00019 #include "qgscomposerpicture.h" 00020 #include "qgscomposermap.h" 00021 #include "qgsproject.h" 00022 #include <QDomDocument> 00023 #include <QDomElement> 00024 #include <QFileInfo> 00025 #include <QImageReader> 00026 #include <QPainter> 00027 #include <QSvgRenderer> 00028 00029 00030 QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ): QgsComposerItem( composition ), mMode( Unknown ), \ 00031 mRotationMap( 0 ) 00032 { 00033 mPictureWidth = rect().width(); 00034 } 00035 00036 QgsComposerPicture::QgsComposerPicture(): QgsComposerItem( 0 ), mMode( Unknown ), mRotationMap( 0 ) 00037 { 00038 mPictureHeight = rect().height(); 00039 } 00040 00041 00042 QgsComposerPicture::~QgsComposerPicture() 00043 { 00044 00045 } 00046 00047 void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget ) 00048 { 00049 if ( !painter ) 00050 { 00051 return; 00052 } 00053 00054 drawBackground( painter ); 00055 00056 int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2; 00057 00058 if ( mMode != Unknown ) 00059 { 00060 double rectPixelWidth = /*rect().width()*/mPictureWidth * newDpi / 25.4; 00061 double rectPixelHeight = /*rect().height()*/ mPictureHeight * newDpi / 25.4; 00062 QRectF boundRect; 00063 if ( mMode == SVG ) 00064 { 00065 boundRect = boundedSVGRect( rectPixelWidth, rectPixelHeight ); 00066 } 00067 else if ( mMode == RASTER ) 00068 { 00069 boundRect = boundedImageRect( rectPixelWidth, rectPixelHeight ); 00070 } 00071 00072 double boundRectWidthMM = boundRect.width() / newDpi * 25.4; 00073 double boundRectHeightMM = boundRect.height() / newDpi * 25.4; 00074 00075 painter->save(); 00076 painter->translate( rect().width() / 2.0, rect().height() / 2.0 ); 00077 painter->rotate( mRotation ); 00078 painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 ); 00079 00080 if ( mMode == SVG ) 00081 { 00082 mSVG.render( painter, QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ) ); 00083 } 00084 else if ( mMode == RASTER ) 00085 { 00086 painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, QRectF( 0, 0, mImage.width(), mImage.height() ) ); 00087 } 00088 00089 painter->restore(); 00090 } 00091 00092 //frame and selection boxes 00093 drawFrame( painter ); 00094 if ( isSelected() ) 00095 { 00096 drawSelectionBoxes( painter ); 00097 } 00098 } 00099 00100 void QgsComposerPicture::setPictureFile( const QString& path ) 00101 { 00102 mSourceFile.setFileName( path ); 00103 if ( !mSourceFile.exists() ) 00104 { 00105 mMode = Unknown; 00106 } 00107 00108 QFileInfo sourceFileInfo( mSourceFile ); 00109 QString sourceFileSuffix = sourceFileInfo.suffix(); 00110 if ( sourceFileSuffix.compare( "svg", Qt::CaseInsensitive ) == 0 ) 00111 { 00112 //try to open svg 00113 mSVG.load( mSourceFile.fileName() ); 00114 if ( mSVG.isValid() ) 00115 { 00116 mMode = SVG; 00117 QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size 00118 mDefaultSvgSize.setWidth( viewBox.width() ); 00119 mDefaultSvgSize.setHeight( viewBox.height() ); 00120 } 00121 else 00122 { 00123 mMode = Unknown; 00124 } 00125 } 00126 else 00127 { 00128 //try to open raster with QImageReader 00129 QImageReader imageReader( mSourceFile.fileName() ); 00130 if ( imageReader.read( &mImage ) ) 00131 { 00132 mMode = RASTER; 00133 } 00134 else 00135 { 00136 mMode = Unknown; 00137 } 00138 } 00139 00140 if ( mMode != Unknown ) //make sure we start with a new QImage 00141 { 00142 setSceneRect( QRectF( transform().dx(), transform().dy(), rect().width(), rect().height() ) ); 00143 } 00144 emit itemChanged(); 00145 } 00146 00147 QRectF QgsComposerPicture::boundedImageRect( double deviceWidth, double deviceHeight ) 00148 { 00149 double imageToDeviceRatio; 00150 if ( mImage.width() / deviceWidth > mImage.height() / deviceHeight ) 00151 { 00152 imageToDeviceRatio = deviceWidth / mImage.width(); 00153 double height = imageToDeviceRatio * mImage.height(); 00154 return QRectF( 0, 0, deviceWidth, height ); 00155 } 00156 else 00157 { 00158 imageToDeviceRatio = deviceHeight / mImage.height(); 00159 double width = imageToDeviceRatio * mImage.width(); 00160 return QRectF( 0, 0, width, deviceHeight ); 00161 } 00162 } 00163 00164 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight ) 00165 { 00166 double imageToSvgRatio; 00167 if ( deviceWidth / mDefaultSvgSize.width() > deviceHeight / mDefaultSvgSize.height() ) 00168 { 00169 imageToSvgRatio = deviceHeight / mDefaultSvgSize.height(); 00170 double width = mDefaultSvgSize.width() * imageToSvgRatio; 00171 return QRectF( 0, 0, width, deviceHeight ); 00172 } 00173 else 00174 { 00175 imageToSvgRatio = deviceWidth / mDefaultSvgSize.width(); 00176 double height = mDefaultSvgSize.height() * imageToSvgRatio; 00177 return QRectF( 0, 0, deviceWidth, height ); 00178 } 00179 } 00180 00181 #if 0 00182 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight ) 00183 { 00184 double imageToSvgRatio; 00185 if ( deviceWidth / mDefaultSvgSize.width() < deviceHeight / mDefaultSvgSize.height() ) 00186 { 00187 imageToSvgRatio = deviceWidth / mDefaultSvgSize.width(); 00188 double height = mDefaultSvgSize.height() * imageToSvgRatio; 00189 return QRectF( 0, 0, deviceWidth, height ); 00190 } 00191 else 00192 { 00193 imageToSvgRatio = deviceHeight / mDefaultSvgSize.height(); 00194 double width = mDefaultSvgSize.width() * imageToSvgRatio; 00195 return QRectF( 0, 0, width, deviceHeight ); 00196 } 00197 } 00198 #endif //0 00199 00200 void QgsComposerPicture::setSceneRect( const QRectF& rectangle ) 00201 { 00202 QgsComposerItem::setSceneRect( rectangle ); 00203 00204 //consider to change size of the shape if the rectangle changes width and/or height 00205 double newPictureWidth = rectangle.width(); 00206 double newPictureHeight = rectangle.height(); 00207 imageSizeConsideringRotation( newPictureWidth, newPictureHeight ); 00208 mPictureWidth = newPictureWidth; 00209 mPictureHeight = newPictureHeight; 00210 00211 emit itemChanged(); 00212 } 00213 00214 void QgsComposerPicture::setRotation( double r ) 00215 { 00216 //adapt rectangle size 00217 double width = mPictureWidth; 00218 double height = mPictureHeight; 00219 sizeChangedByRotation( width, height ); 00220 00221 //adapt scene rect to have the same center and the new width / height 00222 double x = transform().dx() + rect().width() / 2.0 - width / 2.0; 00223 double y = transform().dy() + rect().height() / 2.0 - height / 2.0; 00224 QgsComposerItem::setSceneRect( QRectF( x, y, width, height ) ); 00225 00226 QgsComposerItem::setRotation( r ); 00227 } 00228 00229 void QgsComposerPicture::setRotationMap( int composerMapId ) 00230 { 00231 if ( !mComposition ) 00232 { 00233 return; 00234 } 00235 00236 if ( composerMapId == -1 ) //disable rotation from map 00237 { 00238 QObject::disconnect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) ); 00239 mRotationMap = 0; 00240 } 00241 00242 const QgsComposerMap* map = mComposition->getComposerMapById( composerMapId ); 00243 if ( !map ) 00244 { 00245 return; 00246 } 00247 if ( mRotationMap ) 00248 { 00249 QObject::disconnect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) ); 00250 } 00251 mRotation = map->rotation(); 00252 QObject::connect( map, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) ); 00253 mRotationMap = map; 00254 setRotation( map->rotation() ); 00255 } 00256 00257 QString QgsComposerPicture::pictureFile() const 00258 { 00259 return mSourceFile.fileName(); 00260 } 00261 00262 bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const 00263 { 00264 if ( elem.isNull() ) 00265 { 00266 return false; 00267 } 00268 QDomElement composerPictureElem = doc.createElement( "ComposerPicture" ); 00269 composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourceFile.fileName() ) ); 00270 composerPictureElem.setAttribute( "pictureWidth", mPictureWidth ); 00271 composerPictureElem.setAttribute( "pictureHeight", mPictureHeight ); 00272 if ( !mRotationMap ) 00273 { 00274 composerPictureElem.setAttribute( "mapId", -1 ); 00275 } 00276 else 00277 { 00278 composerPictureElem.setAttribute( "mapId", mRotationMap->id() ); 00279 } 00280 00281 _writeXML( composerPictureElem, doc ); 00282 elem.appendChild( composerPictureElem ); 00283 return true; 00284 } 00285 00286 bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocument& doc ) 00287 { 00288 if ( itemElem.isNull() ) 00289 { 00290 return false; 00291 } 00292 00293 mPictureWidth = itemElem.attribute( "pictureWidth", "10" ).toDouble(); 00294 mPictureHeight = itemElem.attribute( "pictureHeight", "10" ).toDouble(); 00295 00296 QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" ); 00297 if ( composerItemList.size() > 0 ) 00298 { 00299 _readXML( composerItemList.at( 0 ).toElement(), doc ); 00300 } 00301 00302 00303 mDefaultSvgSize = QSize( 0, 0 ); 00304 00305 QString fileName = QgsProject::instance()->readPath( itemElem.attribute( "file" ) ); 00306 setPictureFile( fileName ); 00307 00308 //rotation map 00309 int rotationMapId = itemElem.attribute( "mapId", "-1" ).toInt(); 00310 if ( rotationMapId == -1 ) 00311 { 00312 mRotationMap = 0; 00313 } 00314 else if ( mComposition ) 00315 { 00316 00317 if ( mRotationMap ) 00318 { 00319 QObject::disconnect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) ); 00320 } 00321 mRotationMap = mComposition->getComposerMapById( rotationMapId ); 00322 QObject::connect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) ); 00323 } 00324 00325 emit itemChanged(); 00326 return true; 00327 } 00328 00329 int QgsComposerPicture::rotationMap() const 00330 { 00331 if ( !mRotationMap ) 00332 { 00333 return -1; 00334 } 00335 else 00336 { 00337 return mRotationMap->id(); 00338 } 00339 }