[QGIS Commit] r12262 - in trunk/qgis: python/core src/core
src/core/composer
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Thu Nov 26 08:56:09 EST 2009
Author: mhugent
Date: 2009-11-26 08:56:08 -0500 (Thu, 26 Nov 2009)
New Revision: 12262
Modified:
trunk/qgis/python/core/qgscomposeritem.sip
trunk/qgis/python/core/qgscomposerpicture.sip
trunk/qgis/src/core/CMakeLists.txt
trunk/qgis/src/core/composer/qgscomposeritem.cpp
trunk/qgis/src/core/composer/qgscomposeritem.h
trunk/qgis/src/core/composer/qgscomposermap.cpp
trunk/qgis/src/core/composer/qgscomposermap.h
trunk/qgis/src/core/composer/qgscomposerpicture.cpp
trunk/qgis/src/core/composer/qgscomposerpicture.h
trunk/qgis/src/core/composer/qgscomposershape.cpp
trunk/qgis/src/core/composer/qgscomposershape.h
Log:
Keep shape and composer picture size during rotation. Adapt the item size instead
Modified: trunk/qgis/python/core/qgscomposeritem.sip
===================================================================
--- trunk/qgis/python/core/qgscomposeritem.sip 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/python/core/qgscomposeritem.sip 2009-11-26 13:56:08 UTC (rev 12262)
@@ -145,7 +145,7 @@
double rotation() const;
public slots:
- void setRotation( double r);
+ virtual void setRotation( double r);
protected:
@@ -200,6 +200,13 @@
bool cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const;
/**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
+ /**Calculates width / height of the bounding box of a rotated rectangle (mRotation)*/
+ void sizeChangedByRotation(double& width, double& height);
+ /**Rotates a point / vector
+ @param angle rotation angle in degrees, counterclockwise
+ @param x in/out: x coordinate before / after the rotation
+ @param y in/out: y cooreinate before / after the rotation*/
+ void rotate( double angle, double& x, double& y ) const;
signals:
/**Is emitted on rotation change to notify north arrow pictures*/
Modified: trunk/qgis/python/core/qgscomposerpicture.sip
===================================================================
--- trunk/qgis/python/core/qgscomposerpicture.sip 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/python/core/qgscomposerpicture.sip 2009-11-26 13:56:08 UTC (rev 12262)
@@ -41,7 +41,10 @@
/**True if the rotation is taken from a map item*/
bool useRotationMap() const;
+ public slots:
+ virtual void setRotation( double r );
+
signals:
/**Tell the configuration widget that the settings need to be updated*/
void settingsChanged();
Modified: trunk/qgis/src/core/CMakeLists.txt
===================================================================
--- trunk/qgis/src/core/CMakeLists.txt 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/CMakeLists.txt 2009-11-26 13:56:08 UTC (rev 12262)
@@ -202,6 +202,7 @@
composer/qgscomposerscalebar.h
composer/qgscomposeritem.h
composer/qgscomposeritemgroup.h
+composer/qgscomposershape.h
composer/qgscomposition.h
composer/qgslegendmodel.h
symbology/qgsmarkercatalogue.h
Modified: trunk/qgis/src/core/composer/qgscomposeritem.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposeritem.cpp 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposeritem.cpp 2009-11-26 13:56:08 UTC (rev 12262)
@@ -948,3 +948,50 @@
double scaleFactor = distance / length;
return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
}
+
+void QgsComposerItem::sizeChangedByRotation( double& width, double& height )
+{
+ if ( mRotation == 0.0 )
+ {
+ return;
+ }
+
+ //vector to p1
+ double x1 = -width / 2.0;
+ double y1 = -height / 2.0;
+ rotate( mRotation, x1, y1 );
+ //vector to p2
+ double x2 = width / 2.0;
+ double y2 = -height / 2.0;
+ rotate( mRotation, x2, y2 );
+ //vector to p3
+ double x3 = width / 2.0;
+ double y3 = height / 2.0;
+ rotate( mRotation, x3, y3 );
+ //vector to p4
+ double x4 = -width / 2.0;
+ double y4 = height / 2.0;
+ rotate( mRotation, x4, y4 );
+
+ //double midpoint
+ QPointF midpoint( width / 2.0, height / 2.0 );
+
+ QPolygonF rotatedRectPoly;
+ rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
+ rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
+ rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
+ rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
+ QRectF boundingRect = rotatedRectPoly.boundingRect();
+ width = boundingRect.width();
+ height = boundingRect.height();
+}
+
+void QgsComposerItem::rotate( double angle, double& x, double& y ) const
+{
+ double rotToRad = angle * M_PI / 180.0;
+ double xRot, yRot;
+ xRot = x * cos( rotToRad ) - y * sin( rotToRad );
+ yRot = x * sin( rotToRad ) + y * cos( rotToRad );
+ x = xRot;
+ y = yRot;
+}
Modified: trunk/qgis/src/core/composer/qgscomposeritem.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposeritem.h 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposeritem.h 2009-11-26 13:56:08 UTC (rev 12262)
@@ -172,7 +172,7 @@
double rotation() const {return mRotation;}
public slots:
- void setRotation( double r );
+ virtual void setRotation( double r );
protected:
@@ -245,12 +245,21 @@
@note: this function was introduced in version 1.2*/
double horizontalViewScaleFactor() const;
+ //some utility functions
+
/**Calculates width and hight of the picture (in mm) such that it fits into the item frame with the given rotation*/
bool imageSizeConsideringRotation( double& width, double& height ) const;
/**Calculates corner point after rotation and scaling*/
bool cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const;
/**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
+ /**Calculates width / height of the bounding box of a rotated rectangle (mRotation)*/
+ void sizeChangedByRotation( double& width, double& height );
+ /**Rotates a point / vector
+ @param angle rotation angle in degrees, counterclockwise
+ @param x in/out: x coordinate before / after the rotation
+ @param y in/out: y cooreinate before / after the rotation*/
+ void rotate( double angle, double& x, double& y ) const;
signals:
/**Is emitted on rotation change to notify north arrow pictures*/
Modified: trunk/qgis/src/core/composer/qgscomposermap.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposermap.cpp 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposermap.cpp 2009-11-26 13:56:08 UTC (rev 12262)
@@ -1383,24 +1383,3 @@
return Bottom;
}
}
-
-void QgsComposerMap::rotate( double angle, double& x, double& y ) const
-{
- double rotToRad = angle * M_PI / 180.0;
- double xRot, yRot;
- xRot = x * cos( rotToRad ) - y * sin( rotToRad );
- yRot = x * sin( rotToRad ) + y * cos( rotToRad );
- x = xRot;
- y = yRot;
-}
-
-#if 0
-QPointF QgsComposerMap::pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const
-{
- double dx = directionPoint.x() - startPoint.x();
- double dy = directionPoint.y() - startPoint.y();
- double length = sqrt( dx * dx + dy * dy );
- double scaleFactor = distance / length;
- return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
-}
-#endif //0
Modified: trunk/qgis/src/core/composer/qgscomposermap.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposermap.h 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposermap.h 2009-11-26 13:56:08 UTC (rev 12262)
@@ -381,15 +381,6 @@
QPointF mapToItemCoords( const QPointF& mapCoords ) const;
/**Returns the item border of a point (in item coordinates)*/
Border borderForLineCoord( const QPointF& p ) const;
- /**Rotates a point / vector
- @param angle rotation angle in degrees, counterclockwise
- @param x in/out: x coordinate before / after the rotation
- @param y in/out: y cooreinate before / after the rotation*/
- void rotate( double angle, double& x, double& y ) const;
-#if 0
- /**Returns a point on the line from startPoint to directionPoint that is a certain distance away from the starting point*/
- QPointF pointOnLineWithDistance( const QPointF& startPoint, const QPointF& directionPoint, double distance ) const;
-#endif //0
};
#endif
Modified: trunk/qgis/src/core/composer/qgscomposerpicture.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerpicture.cpp 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposerpicture.cpp 2009-11-26 13:56:08 UTC (rev 12262)
@@ -30,11 +30,12 @@
QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ): QgsComposerItem( composition ), mMode( Unknown ), \
mSvgCacheUpToDate( false ), mCachedDpi( 0 ), mCachedRotation( 0 ), mCachedViewScaleFactor( -1 ), mRotationMap( 0 )
{
+ mPictureWidth = rect().width();
}
QgsComposerPicture::QgsComposerPicture(): QgsComposerItem( 0 ), mMode( Unknown ), mSvgCacheUpToDate( false ), mCachedRotation( 0 ), mCachedViewScaleFactor( -1 ), mRotationMap( 0 )
{
-
+ mPictureHeight = rect().height();
}
QgsComposerPicture::~QgsComposerPicture()
@@ -61,8 +62,8 @@
if ( mMode != Unknown )
{
- double rectPixelWidth = rect().width() * newDpi / 25.4;
- double rectPixelHeight = rect().height() * newDpi / 25.4;
+ double rectPixelWidth = /*rect().width()*/mPictureWidth * newDpi / 25.4;
+ double rectPixelHeight = /*rect().height()*/ mPictureHeight * newDpi / 25.4;
QRectF boundRect;
if ( mMode == SVG )
{
@@ -75,11 +76,8 @@
double boundRectWidthMM = boundRect.width() / newDpi * 25.4;
double boundRectHeightMM = boundRect.height() / newDpi * 25.4;
- double rotatedBoundImageWidth = boundRect.width();
- double rotatedBoundImageHeight = boundRect.height();
- imageSizeConsideringRotation( rotatedBoundImageWidth, rotatedBoundImageHeight );
- double rotatedBoundImageWidthMM = rotatedBoundImageWidth / newDpi * 25.4;
- double rotatedBoundImageHeightMM = rotatedBoundImageHeight / newDpi * 25.4;
+ double boundImageWidth = boundRect.width();
+ double boundImageHeight = boundRect.height();
if ( mMode == SVG )
{
@@ -88,20 +86,20 @@
//make nicer preview
if ( mComposition && mComposition->plotStyle() == QgsComposition::Preview )
{
- rotatedBoundImageWidth *= std::min( viewScaleFactor, 10.0 );
- rotatedBoundImageHeight *= std::min( viewScaleFactor, 10.0 );
+ boundImageWidth *= std::min( viewScaleFactor, 10.0 );
+ boundImageHeight *= std::min( viewScaleFactor, 10.0 );
}
- mImage = QImage( rotatedBoundImageWidth, rotatedBoundImageHeight, QImage::Format_ARGB32 );
+ mImage = QImage( boundImageWidth, boundImageHeight, QImage::Format_ARGB32 );
updateImageFromSvg();
}
}
painter->save();
- painter->translate( boundRectWidthMM / 2.0, boundRectHeightMM / 2.0 );
+ painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
painter->rotate( mRotation );
- painter->translate( -rotatedBoundImageWidthMM / 2.0, -rotatedBoundImageHeightMM / 2.0 );
+ painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
- painter->drawImage( QRectF( 0, 0, rotatedBoundImageWidthMM, rotatedBoundImageHeightMM ), mImage, QRectF( 0, 0, mImage.width(), mImage.height() ) );
+ painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, QRectF( 0, 0, mImage.width(), mImage.height() ) );
painter->restore();
}
@@ -186,6 +184,24 @@
QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
{
double imageToSvgRatio;
+ if ( deviceWidth / mDefaultSvgSize.width() > deviceHeight / mDefaultSvgSize.height() )
+ {
+ imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
+ double width = mDefaultSvgSize.width() * imageToSvgRatio;
+ return QRectF( 0, 0, width, deviceHeight );
+ }
+ else
+ {
+ imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
+ double height = mDefaultSvgSize.height() * imageToSvgRatio;
+ return QRectF( 0, 0, deviceWidth, height );
+ }
+}
+
+#if 0
+QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
+{
+ double imageToSvgRatio;
if ( deviceWidth / mDefaultSvgSize.width() < deviceHeight / mDefaultSvgSize.height() )
{
imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
@@ -199,6 +215,7 @@
return QRectF( 0, 0, width, deviceHeight );
}
}
+#endif //0
void QgsComposerPicture::updateImageFromSvg()
{
@@ -216,9 +233,32 @@
{
mSvgCacheUpToDate = false;
QgsComposerItem::setSceneRect( rectangle );
+
+ //consider to change size of the shape if the rectangle changes width and/or height
+ double newPictureWidth = rectangle.width();
+ double newPictureHeight = rectangle.height();
+ imageSizeConsideringRotation( newPictureWidth, newPictureHeight );
+ mPictureWidth = newPictureWidth;
+ mPictureHeight = newPictureHeight;
+
emit settingsChanged();
}
+void QgsComposerPicture::setRotation( double r )
+{
+ //adapt rectangle size
+ double width = mPictureWidth;
+ double height = mPictureHeight;
+ sizeChangedByRotation( width, height );
+
+ //adapt scene rect to have the same center and the new width / height
+ double x = transform().dx() + rect().width() / 2.0 - width / 2.0;
+ double y = transform().dy() + rect().height() / 2.0 - height / 2.0;
+ QgsComposerItem::setSceneRect( QRectF( x, y, width, height ) );
+
+ QgsComposerItem::setRotation( r );
+}
+
void QgsComposerPicture::setRotationMap( int composerMapId )
{
if ( !mComposition )
@@ -260,6 +300,8 @@
}
QDomElement composerPictureElem = doc.createElement( "ComposerPicture" );
composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourceFile.fileName() ) );
+ composerPictureElem.setAttribute( "pictureWidth", mPictureWidth );
+ composerPictureElem.setAttribute( "pictureHeight", mPictureHeight );
if ( !mRotationMap )
{
composerPictureElem.setAttribute( "mapId", -1 );
@@ -281,6 +323,9 @@
return false;
}
+ mPictureWidth = itemElem.attribute( "pictureWidth", "10" ).toDouble();
+ mPictureHeight = itemElem.attribute( "pictureHeight", "10" ).toDouble();
+
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
if ( composerItemList.size() > 0 )
{
Modified: trunk/qgis/src/core/composer/qgscomposerpicture.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerpicture.h 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposerpicture.h 2009-11-26 13:56:08 UTC (rev 12262)
@@ -39,7 +39,7 @@
QString pictureFile() const;
/**Sets this items bound in scene coordinates such that 1 item size units
- corresponds to 1 scene size unit*/
+ corresponds to 1 scene size unit and resizes the svg symbol / image*/
void setSceneRect( const QRectF& rectangle );
/** stores state in Dom node
@@ -60,6 +60,10 @@
/**True if the rotation is taken from a map item*/
bool useRotationMap() const {return mRotationMap;}
+ public slots:
+ /**Sets the rotation and adapts the item rect*/
+ virtual void setRotation( double r );
+
private:
enum Mode //SVG or raster graphic format
@@ -94,8 +98,11 @@
QSize mDefaultSvgSize;
/**Map that sets the rotation (or 0 if this picture uses map independent rotation)*/
const QgsComposerMap* mRotationMap;
+ /**Width of the picture (in mm)*/
+ double mPictureWidth;
+ /**Height of the picture (in mm)*/
+ double mPictureHeight;
-
signals:
/**Tell the configuration widget that the settings need to be updated*/
void settingsChanged();
Modified: trunk/qgis/src/core/composer/qgscomposershape.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposershape.cpp 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposershape.cpp 2009-11-26 13:56:08 UTC (rev 12262)
@@ -26,6 +26,8 @@
QgsComposerShape::QgsComposerShape( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition ): QgsComposerItem( x, y, width, height, composition ), mShape( Ellipse )
{
setSceneRect( QRectF( x, y, width, height ) );
+ mShapeWidth = width;
+ mShapeHeight = height;
initGraphicsSettings();
}
@@ -44,7 +46,6 @@
double width = rect().width();
double height = rect().height();
- imageSizeConsideringRotation( width, height );
painter->save();
painter->setRenderHint( QPainter::Antialiasing );
@@ -53,23 +54,23 @@
painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
painter->rotate( mRotation );
- painter->translate( -width / 2.0, -height / 2.0 );
+ painter->translate( -mShapeWidth / 2.0, -mShapeHeight / 2.0 );
double halfPenWidth = mPen.widthF() / 2.0;
switch ( mShape )
{
case Ellipse:
- painter->drawEllipse( QRectF( halfPenWidth, halfPenWidth , width - mPen.widthF(), height - mPen.widthF() ) );
+ painter->drawEllipse( QRectF( halfPenWidth, halfPenWidth , mShapeWidth - mPen.widthF(), mShapeHeight - mPen.widthF() ) );
break;
case Rectangle:
- painter->drawRect( QRectF( halfPenWidth, halfPenWidth , width - mPen.widthF(), height - mPen.widthF() ) );
+ painter->drawRect( QRectF( halfPenWidth, halfPenWidth , mShapeWidth - mPen.widthF(), mShapeHeight - mPen.widthF() ) );
break;
case Triangle:
QPolygonF triangle;
- triangle << QPointF( halfPenWidth, height - halfPenWidth );
- triangle << QPointF( width - halfPenWidth, height - halfPenWidth );
- triangle << QPointF( width / 2.0, halfPenWidth );
+ triangle << QPointF( halfPenWidth, mShapeHeight - halfPenWidth );
+ triangle << QPointF( mShapeWidth - halfPenWidth, mShapeHeight - halfPenWidth );
+ triangle << QPointF( mShapeWidth / 2.0, halfPenWidth );
painter->drawPolygon( triangle );
break;
}
@@ -89,6 +90,8 @@
composerShapeElem.setAttribute( "shapeType", mShape );
composerShapeElem.setAttribute( "outlineWidth", mPen.widthF() );
composerShapeElem.setAttribute( "transparentFill", mBrush.style() == Qt::NoBrush );
+ composerShapeElem.setAttribute( "shapeWidth", mShapeWidth );
+ composerShapeElem.setAttribute( "shapeHeight", mShapeHeight );
QDomElement outlineColorElem = doc.createElement( "OutlineColor" );
outlineColorElem.setAttribute( "red", mPen.color().red() );
outlineColorElem.setAttribute( "green", mPen.color().green() );
@@ -108,6 +111,8 @@
bool QgsComposerShape::readXML( const QDomElement& itemElem, const QDomDocument& doc )
{
mShape = QgsComposerShape::Shape( itemElem.attribute( "shapeType", "0" ).toInt() );
+ mShapeWidth = itemElem.attribute( "shapeWidth", "10" ).toDouble();
+ mShapeHeight = itemElem.attribute( "shapeHeight", "10" ).toDouble();
mPen.setWidthF( itemElem.attribute( "outlineWidth", "0.4" ).toDouble() );
//transparent fill
@@ -215,3 +220,30 @@
setPen( QPen( QColor( 255, 255, 255, 0 ) ) );
setBrush( QBrush( QColor( 255, 255, 255, 0 ) ) );
}
+
+void QgsComposerShape::setRotation( double r )
+{
+ //adapt rectangle size
+ double width = mShapeWidth;
+ double height = mShapeHeight;
+ sizeChangedByRotation( width, height );
+
+ //adapt scene rect to have the same center and the new width / height
+ double x = transform().dx() + rect().width() / 2.0 - width / 2.0;
+ double y = transform().dy() + rect().height() / 2.0 - height / 2.0;
+ QgsComposerItem::setSceneRect( QRectF( x, y, width, height ) );
+
+ QgsComposerItem::setRotation( r );
+}
+
+void QgsComposerShape::setSceneRect( const QRectF& rectangle )
+{
+ QgsComposerItem::setSceneRect( rectangle );
+
+ //consider to change size of the shape if the rectangle changes width and/or height
+ double newShapeWidth = rectangle.width();
+ double newShapeHeight = rectangle.height();
+ imageSizeConsideringRotation( newShapeWidth, newShapeHeight );
+ mShapeWidth = newShapeWidth;
+ mShapeHeight = newShapeHeight;
+}
Modified: trunk/qgis/src/core/composer/qgscomposershape.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposershape.h 2009-11-26 08:21:22 UTC (rev 12261)
+++ trunk/qgis/src/core/composer/qgscomposershape.h 2009-11-26 13:56:08 UTC (rev 12262)
@@ -23,6 +23,7 @@
/**A composer items that draws common shapes (ellipse, triangle, rectangle)*/
class CORE_EXPORT QgsComposerShape: public QgsComposerItem
{
+ Q_OBJECT
public:
enum Shape
@@ -62,7 +63,15 @@
bool transparentFill() const;
void setTransparentFill( bool transparent );
+ /**Sets this items bound in scene coordinates such that 1 item size units
+ corresponds to 1 scene size unit. Also, the shape is scaled*/
+ void setSceneRect( const QRectF& rectangle );
+ public slots:
+ /**Sets item rotation and resizes item bounds such that the shape always has the same size*/
+ virtual void setRotation( double r );
+
+
private:
/**Ellipse, rectangle or triangle*/
Shape mShape;
@@ -70,6 +79,8 @@
QPen mPen;
/**Shape fill*/
QBrush mBrush;
+ double mShapeWidth;
+ double mShapeHeight;
/**Apply default graphics settings*/
void initGraphicsSettings();
More information about the QGIS-commit
mailing list