[QGIS Commit] r11894 - in trunk/qgis/src: app/composer
core/composer ui
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Mon Nov 2 12:26:18 EST 2009
Author: mhugent
Date: 2009-11-02 12:26:17 -0500 (Mon, 02 Nov 2009)
New Revision: 11894
Modified:
trunk/qgis/src/app/composer/qgscomposerpicturewidget.cpp
trunk/qgis/src/app/composer/qgscomposerpicturewidget.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/ui/qgscomposerpicturewidgetbase.ui
Log:
[FEATURE]: Improve the rotation of composer pictures and added the possibility to synchronize composer map rotation and composer picture rotation (e.g. usefull for north arrows)
Modified: trunk/qgis/src/app/composer/qgscomposerpicturewidget.cpp
===================================================================
--- trunk/qgis/src/app/composer/qgscomposerpicturewidget.cpp 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/app/composer/qgscomposerpicturewidget.cpp 2009-11-02 17:26:17 UTC (rev 11894)
@@ -17,6 +17,7 @@
#include "qgscomposerpicturewidget.h"
#include "qgsapplication.h"
+#include "qgscomposermap.h"
#include "qgscomposerpicture.h"
#include "qgscomposeritemwidget.h"
#include <QDoubleValidator>
@@ -34,18 +35,16 @@
//add widget for general composer item properties
QgsComposerItemWidget* itemPropertiesWidget = new QgsComposerItemWidget( this, picture );
- gridLayout->addWidget( itemPropertiesWidget, 6, 0, 1, 4 );
+ gridLayout->addWidget( itemPropertiesWidget, 8, 0, 1, 4 );
mWidthLineEdit->setValidator( new QDoubleValidator( this ) );
mHeightLineEdit->setValidator( new QDoubleValidator( this ) );
-
setGuiElementValues();
mPreviewListWidget->setIconSize( QSize( 30, 30 ) );
//add preview icons
addStandardDirectoriesToPreview();
-
connect( mPicture, SIGNAL( settingsChanged() ), this, SLOT( setGuiElementValues() ) );
}
@@ -198,6 +197,118 @@
}
}
+void QgsComposerPictureWidget::on_mRotationFromComposerMapCheckBox_stateChanged( int state )
+{
+ if ( !mPicture )
+ {
+ return;
+ }
+
+ if ( state == Qt::Unchecked )
+ {
+ mPicture->setRotationMap( -1 );
+ mRotationSpinBox->setEnabled( true );
+ mComposerMapComboBox->setEnabled( false );
+ }
+ else
+ {
+ int currentItemIndex = mComposerMapComboBox->currentIndex();
+ if ( currentItemIndex == -1 )
+ {
+ return;
+ }
+ int composerId = mComposerMapComboBox->itemData( currentItemIndex, Qt::UserRole ).toInt();
+ mPicture->setRotationMap( composerId );
+ mRotationSpinBox->setEnabled( false );
+ mComposerMapComboBox->setEnabled( true );
+ }
+}
+
+void QgsComposerPictureWidget::showEvent( QShowEvent * event )
+{
+ refreshMapComboBox();
+ QWidget::showEvent( event );
+}
+
+void QgsComposerPictureWidget::on_mComposerMapComboBox_activated( const QString & text )
+{
+ if ( !mPicture || text.isEmpty() || !mPicture->useRotationMap() )
+ {
+ return;
+ }
+
+ //get composition
+ const QgsComposition* composition = mPicture->composition();
+ if ( !composition )
+ {
+ return;
+ }
+
+ //extract id
+ int id;
+ bool conversionOk;
+ QStringList textSplit = text.split( " " );
+ if ( textSplit.size() < 1 )
+ {
+ return;
+ }
+
+ QString idString = textSplit.at( textSplit.size() - 1 );
+ id = idString.toInt( &conversionOk );
+
+ if ( !conversionOk )
+ {
+ return;
+ }
+
+ const QgsComposerMap* composerMap = composition->getComposerMapById( id );
+ if ( !composerMap )
+ {
+ return;
+ }
+ mPicture->setRotationMap( id );
+ mPicture->update();
+}
+
+void QgsComposerPictureWidget::refreshMapComboBox()
+{
+ mComposerMapComboBox->blockSignals( true );
+ //save the current entry in case it is still present after refresh
+ QString saveCurrentComboText = mComposerMapComboBox->currentText();
+
+ mComposerMapComboBox->clear();
+
+ if ( mPicture )
+ {
+ //insert available maps into mMapComboBox
+ const QgsComposition* composition = mPicture->composition();
+ if ( composition )
+ {
+ QList<const QgsComposerMap*> availableMaps = composition->composerMapItems();
+ QList<const QgsComposerMap*>::const_iterator mapItemIt = availableMaps.constBegin();
+ for ( ; mapItemIt != availableMaps.constEnd(); ++mapItemIt )
+ {
+ mComposerMapComboBox->addItem( tr( "Map %1" ).arg(( *mapItemIt )->id() ), ( *mapItemIt )->id() );
+ }
+ }
+ }
+
+ if ( !saveCurrentComboText.isEmpty() )
+ {
+ if ( mComposerMapComboBox->findText( saveCurrentComboText ) == -1 )
+ {
+ //the former entry is no longer present. Inform the scalebar about the changed composer map
+ on_mComposerMapComboBox_activated( mComposerMapComboBox->currentText() );
+ }
+ else
+ {
+ //the former entry is still present. Make it the current entry again
+ mComposerMapComboBox->setCurrentIndex( mComposerMapComboBox->findText( saveCurrentComboText ) );
+ }
+ }
+ mComposerMapComboBox->blockSignals( false );
+}
+
void QgsComposerPictureWidget::setGuiElementValues()
{
//set initial gui values
@@ -207,6 +318,8 @@
mHeightLineEdit->blockSignals( true );
mRotationSpinBox->blockSignals( true );
mPictureLineEdit->blockSignals( true );
+ mComposerMapComboBox->blockSignals( true );
+ mRotationFromComposerMapCheckBox->blockSignals( true );
mPictureLineEdit->setText( mPicture->pictureFile() );
QRectF pictureRect = mPicture->rect();
@@ -214,10 +327,34 @@
mHeightLineEdit->setText( QString::number( pictureRect.height() ) );
mRotationSpinBox->setValue( mPicture->rotation() );
+ refreshMapComboBox();
+
+ if ( mPicture->useRotationMap() )
+ {
+ mRotationFromComposerMapCheckBox->setCheckState( Qt::Checked );
+ mRotationSpinBox->setEnabled( false );
+ mComposerMapComboBox->setEnabled( true );
+ QString mapText = tr( "Map %1" ).arg( mPicture->rotationMap() );
+ int itemId = mComposerMapComboBox->findText( mapText );
+ if ( itemId >= 0 )
+ {
+ mComposerMapComboBox->setCurrentIndex( itemId );
+ }
+ }
+ else
+ {
+ mRotationFromComposerMapCheckBox->setCheckState( Qt::Unchecked );
+ mRotationSpinBox->setEnabled( true );
+ mComposerMapComboBox->setEnabled( false );
+ }
+
+
+ mRotationFromComposerMapCheckBox->blockSignals( false );
mWidthLineEdit->blockSignals( false );
mHeightLineEdit->blockSignals( false );
mRotationSpinBox->blockSignals( false );
mPictureLineEdit->blockSignals( false );
+ mComposerMapComboBox->blockSignals( false );
}
}
@@ -302,7 +439,8 @@
{
//list all directories in $prefix/share/qgis/svg
QStringList svgPaths = QgsApplication::svgPaths();
- for(int i=0; i<svgPaths.size(); i++) {
+ for ( int i = 0; i < svgPaths.size(); i++ )
+ {
QDir svgDirectory( svgPaths[i] );
if ( !svgDirectory.exists() || !svgDirectory.isReadable() )
{
@@ -315,7 +453,7 @@
{
if ( addDirectoryToPreview( dirIt->absoluteFilePath() ) == 0 )
{
- mSearchDirectoriesComboBox->addItem( dirIt->absoluteFilePath() );
+ mSearchDirectoriesComboBox->addItem( dirIt->absoluteFilePath() );
}
}
}
Modified: trunk/qgis/src/app/composer/qgscomposerpicturewidget.h
===================================================================
--- trunk/qgis/src/app/composer/qgscomposerpicturewidget.h 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/app/composer/qgscomposerpicturewidget.h 2009-11-02 17:26:17 UTC (rev 11894)
@@ -42,9 +42,15 @@
void on_mPreviewListWidget_currentItemChanged( QListWidgetItem* current, QListWidgetItem* previous );
void on_mAddDirectoryButton_clicked();
void on_mRemoveDirectoryButton_clicked();
+ void on_mRotationFromComposerMapCheckBox_stateChanged( int state );
+ void on_mComposerMapComboBox_activated( const QString & text );
+
/**Sets the GUI elements to the values of mPicture*/
void setGuiElementValues();
+ protected:
+ void showEvent( QShowEvent * event );
+
private:
QgsComposerPicture* mPicture;
/**Add the icons of a directory to the preview. Returns 0 in case of success*/
@@ -55,6 +61,8 @@
bool testSvgFile( const QString& filename ) const;
/**Tests if a file is a valid pixel format*/
bool testImageFile( const QString& filename ) const;
+ /**Updates the map combo box with the current composer map ids*/
+ void refreshMapComboBox();
};
#endif
Modified: trunk/qgis/src/core/composer/qgscomposermap.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposermap.cpp 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/core/composer/qgscomposermap.cpp 2009-11-02 17:26:17 UTC (rev 11894)
@@ -505,6 +505,12 @@
mYOffset = yOffset;
}
+void QgsComposerMap::setRotation( double r )
+{
+ mRotation = r;
+ emit rotationChanged( r );
+}
+
bool QgsComposerMap::containsWMSLayer() const
{
if ( !mMapRenderer )
Modified: trunk/qgis/src/core/composer/qgscomposermap.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposermap.h 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/core/composer/qgscomposermap.h 2009-11-02 17:26:17 UTC (rev 11894)
@@ -241,7 +241,7 @@
/**Sets the rotation of the map content
@note this function was added in version 1.4*/
- void setRotation( double r ) { mRotation = r; }
+ void setRotation( double r );
double rotation() const { return mRotation; }
/**Sets length of the cros segments (if grid style is cross)
@@ -259,6 +259,8 @@
signals:
/**Is emitted when width/height is changed as a result of user interaction*/
void extentChanged();
+ /**Is emitted on rotation change to notify north arrow pictures*/
+ void rotationChanged( double newRotation );
private:
Modified: trunk/qgis/src/core/composer/qgscomposerpicture.cpp
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerpicture.cpp 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/core/composer/qgscomposerpicture.cpp 2009-11-02 17:26:17 UTC (rev 11894)
@@ -17,6 +17,7 @@
/* $Id$ */
#include "qgscomposerpicture.h"
+#include "qgscomposermap.h"
#include "qgsproject.h"
#include <QDomDocument>
#include <QDomElement>
@@ -25,11 +26,18 @@
#include <QPainter>
#include <QSvgRenderer>
-QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ): QObject( 0 ), QgsComposerItem( composition ), mRotation( 0.0 ), mMode( Unknown ), mSvgCacheUpToDate( false ), mCachedDpi( 0 )
+#ifndef Q_OS_MACX
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ): QObject( 0 ), QgsComposerItem( composition ), mRotation( 0.0 ), mMode( Unknown ), \
+ mSvgCacheUpToDate( false ), mCachedDpi( 0 ), mRotationMap( 0 )
{
}
-QgsComposerPicture::QgsComposerPicture(): QgsComposerItem( 0 ), mRotation( 0.0 ), mMode( Unknown ), mSvgCacheUpToDate( false )
+QgsComposerPicture::QgsComposerPicture(): QgsComposerItem( 0 ), mRotation( 0.0 ), mMode( Unknown ), mSvgCacheUpToDate( false ), mRotationMap( 0 )
{
}
@@ -46,52 +54,61 @@
return;
}
- if ( mMode == SVG )
+ drawBackground( painter );
+
+ int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
+ if ( mMode != Unknown )
{
- int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
- if ( newDpi != mCachedDpi )
+ double rectPixelWidth = rect().width() * newDpi / 25.4;
+ double rectPixelHeight = rect().height() * newDpi / 25.4;
+ QRectF boundRect;
+ if ( mMode == SVG )
{
- mSvgCacheUpToDate = false;
- mCachedDpi = newDpi;
- mImage = QImage( rect().width() * newDpi / 25.4, rect().height() * newDpi / 25.4, QImage::Format_ARGB32 );
+ boundRect = boundedSVGRect( rectPixelWidth, rectPixelHeight );
}
-
- if ( !mSvgCacheUpToDate )
+ else if ( mMode == RASTER )
{
- updateImageFromSvg();
+ boundRect = boundedImageRect( rectPixelWidth, rectPixelHeight );
}
- }
- painter->save();
- painter->rotate( mRotation );
- drawBackground( painter );
+ double boundRectWidthMM = boundRect.width() / newDpi * 25.4;
+ double boundRectHeightMM = boundRect.height() / newDpi * 25.4;
+ double unrotatedBoundImageWidth = boundRect.width();
+ double unrotatedBoundImageHeight = boundRect.height();
+ double unrotatedBoundImageWidthMM = unrotatedBoundImageWidth / newDpi * 25.4;
+ double unrotatedBoundImageHeightMM = unrotatedBoundImageHeight / 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;
- if ( mMode != Unknown )
- {
- double widthRatio = mImage.width() / rect().width();
- double heightRatio = mImage.height() / rect().height();
- double targetWidth, targetHeight;
- if ( widthRatio > heightRatio )
+ if ( mMode == SVG )
{
- targetWidth = rect().width();
- targetHeight = mImage.height() / widthRatio;
+ if ( !mSvgCacheUpToDate )
+ {
+ mImage = QImage( rotatedBoundImageWidth, rotatedBoundImageHeight, QImage::Format_ARGB32 );
+ updateImageFromSvg();
+ }
}
- else
- {
- targetHeight = rect().height();
- targetWidth = mImage.width() / heightRatio;
- }
- painter->drawImage( QRectF( 0, 0, targetWidth, targetHeight ), mImage, QRectF( 0, 0, mImage.width(), mImage.height() ) );
+
+ painter->save();
+ painter->translate( boundRectWidthMM / 2.0, boundRectHeightMM / 2.0 );
+ painter->rotate( mRotation );
+ painter->translate( -rotatedBoundImageWidthMM / 2.0, -rotatedBoundImageHeightMM / 2.0 );
+ painter->drawImage( QRectF( 0, 0, rotatedBoundImageWidthMM, rotatedBoundImageHeightMM ), mImage, QRectF( 0, 0, mImage.width(), mImage.height() ) );
+
+ painter->restore();
}
+ mCachedDpi = newDpi;
+
//frame and selection boxes
drawFrame( painter );
if ( isSelected() )
{
drawSelectionBoxes( painter );
}
-
- painter->restore();
}
void QgsComposerPicture::setPictureFile( const QString& path )
@@ -102,9 +119,6 @@
mMode = Unknown;
}
- //mImage = QImage(mImage.width(), mImage.height(), QImage::Format_ARGB32 );
- //setSceneRect
-
QFileInfo sourceFileInfo( mSourceFile );
QString sourceFileSuffix = sourceFileInfo.suffix();
if ( sourceFileSuffix.compare( "svg", Qt::CaseInsensitive ) == 0 )
@@ -145,43 +159,124 @@
emit settingsChanged();
}
+QRectF QgsComposerPicture::boundedImageRect( double deviceWidth, double deviceHeight )
+{
+ double imageToDeviceRatio;
+ if ( mImage.width() / deviceWidth > mImage.height() / deviceHeight )
+ {
+ imageToDeviceRatio = deviceWidth / mImage.width();
+ double height = imageToDeviceRatio * mImage.height();
+ return QRectF( 0, 0, deviceWidth, height );
+ }
+ else
+ {
+ imageToDeviceRatio = deviceHeight / mImage.height();
+ double width = imageToDeviceRatio * mImage.width();
+ return QRectF( 0, 0, width, deviceHeight );
+ }
+}
+
+QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
+{
+ double imageToSvgRatio;
+ if ( deviceWidth / mDefaultSvgSize.width() < deviceHeight / mDefaultSvgSize.height() )
+ {
+ imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
+ double height = mDefaultSvgSize.height() * imageToSvgRatio;
+ return QRectF( 0, 0, deviceWidth, height );
+ }
+ else
+ {
+ imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
+ double width = mDefaultSvgSize.width() * imageToSvgRatio;
+ return QRectF( 0, 0, width, deviceHeight );
+ }
+}
+
void QgsComposerPicture::updateImageFromSvg()
{
mImage.fill( 0 );
QPainter p( &mImage );
p.setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing, true );
QSvgRenderer theRenderer( mSourceFile.fileName() );
- if ( theRenderer.isValid() )
- {
- theRenderer.render( &p );
- }
+ theRenderer.render( &p );
mSvgCacheUpToDate = true;
}
-void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
+bool QgsComposerPicture::imageSizeConsideringRotation( double& width, double& height ) const
{
- mSvgCacheUpToDate = false;
- if ( mMode == SVG )
+ double x1 = 0;
+ double y1 = 0;
+ double x2 = width;
+ double y2 = 0;
+ double x3 = width;
+ double y3 = height;
+ double x4 = 0;
+ double y4 = height;
+
+ if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height ) )
{
- //keep aspect ratio
- double widthRatio = rectangle.width() / mDefaultSvgSize.width();
- double heightRatio = rectangle.height() / mDefaultSvgSize.height();
+ return false;
+ }
+ if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height ) )
+ {
+ return false;
+ }
+ if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height ) )
+ {
+ return false;
+ }
+ /*
+ if(!cornerPointOnRotatedAndScaledRect(x4, y4, width, height))
+ {
+ return false;
+ }*/
- double newImageWidth;
- double newImageHeight;
+ width = sqrt(( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
+ height = sqrt(( x3 - x2 ) * ( x3 - x2 ) + ( y3 - y2 ) * ( y3 - y2 ) );
+ return true;
+}
- if ( widthRatio > heightRatio )
+bool QgsComposerPicture::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
+{
+ //first rotate point clockwise
+ double rotToRad = mRotation * M_PI / 180.0;
+ QPointF midpoint( width / 2.0, height / 2.0 );
+ double xVector = x - midpoint.x();
+ double yVector = y - midpoint.y();
+ //double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
+ //double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
+ double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
+ double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
+
+ //create line from midpoint to rotated point
+ QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
+
+ //intersect with all four borders and return result
+ QList<QLineF> borders;
+ borders << QLineF( 0, 0, width, 0 );
+ borders << QLineF( width, 0, width, height );
+ borders << QLineF( width, height, 0, height );
+ borders << QLineF( 0, height, 0, 0 );
+
+ QList<QLineF>::const_iterator it = borders.constBegin();
+ QPointF intersectionPoint;
+
+ for ( ; it != borders.constEnd(); ++it )
+ {
+ if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
{
- newImageWidth = rectangle.width() * mCachedDpi / 25.4;
- newImageHeight = mDefaultSvgSize.height() * widthRatio * mCachedDpi / 25.4;
+ x = intersectionPoint.x();
+ y = intersectionPoint.y();
+ return true;
}
- else
- {
- newImageHeight = rectangle.height() * mCachedDpi / 25.4;
- newImageWidth = mDefaultSvgSize.width() * heightRatio * mCachedDpi / 25.4;
- }
- mImage = QImage( newImageWidth, newImageHeight, QImage::Format_ARGB32 );
}
+ return false;
+}
+
+void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
+{
+ mSvgCacheUpToDate = false;
QgsComposerItem::setSceneRect( rectangle );
emit settingsChanged();
}
@@ -196,8 +291,37 @@
{
mRotation = rotation;
}
+ emit settingsChanged();
+ update();
}
+void QgsComposerPicture::setRotationMap( int composerMapId )
+{
+ if ( !mComposition )
+ {
+ return;
+ }
+
+ if ( composerMapId == -1 ) //disable rotation from map
+ {
+ QObject::disconnect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
+ mRotationMap = 0;
+ }
+
+ const QgsComposerMap* map = mComposition->getComposerMapById( composerMapId );
+ if ( !map )
+ {
+ return;
+ }
+ if ( mRotationMap )
+ {
+ QObject::disconnect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
+ }
+ mRotation = map->rotation();
+ QObject::connect( map, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
+ mRotationMap = map;
+}
+
QString QgsComposerPicture::pictureFile() const
{
return mSourceFile.fileName();
@@ -212,6 +336,15 @@
QDomElement composerPictureElem = doc.createElement( "ComposerPicture" );
composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourceFile.fileName() ) );
composerPictureElem.setAttribute( "rotation", QString::number( mRotation ) );
+ if ( !mRotationMap )
+ {
+ composerPictureElem.setAttribute( "mapId", -1 );
+ }
+ else
+ {
+ composerPictureElem.setAttribute( "mapId", mRotationMap->id() );
+ }
+
_writeXML( composerPictureElem, doc );
elem.appendChild( composerPictureElem );
return true;
@@ -230,6 +363,7 @@
_readXML( composerItemList.at( 0 ).toElement(), doc );
}
+
mSvgCacheUpToDate = false;
mDefaultSvgSize = QSize( 0, 0 );
mCachedDpi = 0;
@@ -239,5 +373,34 @@
mRotation = itemElem.attribute( "rotation" ).toDouble();
+ //rotation map
+ int rotationMapId = itemElem.attribute( "mapId", "-1" ).toInt();
+ if ( rotationMapId == -1 )
+ {
+ mRotationMap = 0;
+ }
+ else if ( mComposition )
+ {
+
+ if ( mRotationMap )
+ {
+ QObject::disconnect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
+ }
+ mRotationMap = mComposition->getComposerMapById( rotationMapId );
+ QObject::connect( mRotationMap, SIGNAL( rotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
+ }
+
return true;
}
+
+int QgsComposerPicture::rotationMap() const
+{
+ if ( !mRotationMap )
+ {
+ return -1;
+ }
+ else
+ {
+ return mRotationMap->id();
+ }
+}
Modified: trunk/qgis/src/core/composer/qgscomposerpicture.h
===================================================================
--- trunk/qgis/src/core/composer/qgscomposerpicture.h 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/core/composer/qgscomposerpicture.h 2009-11-02 17:26:17 UTC (rev 11894)
@@ -43,8 +43,6 @@
corresponds to 1 scene size unit*/
void setSceneRect( const QRectF& rectangle );
- void setRotation( double rotation );
-
double rotation() const {return mRotation;}
/** stores state in Dom node
@@ -58,6 +56,17 @@
*/
bool readXML( const QDomElement& itemElem, const QDomDocument& doc );
+ /**Sets the map object for rotation (by id). A value of -1 disables the map rotation*/
+ void setRotationMap( int composerMapId );
+ /**Returns the id of the rotation map*/
+ int rotationMap() const;
+ /**True if the rotation is taken from a map item*/
+ bool useRotationMap() const {return mRotationMap;}
+
+ public slots:
+
+ void setRotation( double rotation );
+
private:
enum Mode //SVG or raster graphic format
@@ -69,8 +78,19 @@
//default constructor is forbidden
QgsComposerPicture();
- /**Updates content of current image using svg generator*/
+ /**Calculates bounding rect for svg file (mSourcefile) such that aspect ratio is correct*/
+ QRectF boundedSVGRect( double deviceWidth, double deviceHeight );
+ /**Calculates bounding rect for image such that aspect ratio is correct*/
+ QRectF boundedImageRect( double deviceWidth, double deviceHeight );
+
+ /**Updates content of mImage using svg generator
+ @param out: boundWidth width of mImage that is used by the svg renderer. May different from mImage.width() to preserve aspect ratio
+ @param out: boundHeight height of mImage that is used by the svg renderer*/
void updateImageFromSvg();
+ /**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;
QImage mImage;
double mRotation;
@@ -80,7 +100,10 @@
bool mSvgCacheUpToDate;
int mCachedDpi; //store dpis for which the svg cache is valid
QSize mDefaultSvgSize;
+ /**Map that sets the rotation (or 0 if this picture uses map independent rotation)*/
+ const QgsComposerMap* mRotationMap;
+
signals:
/**Tell the configuration widget that the settings need to be updated*/
void settingsChanged();
Modified: trunk/qgis/src/ui/qgscomposerpicturewidgetbase.ui
===================================================================
--- trunk/qgis/src/ui/qgscomposerpicturewidgetbase.ui 2009-11-02 13:58:09 UTC (rev 11893)
+++ trunk/qgis/src/ui/qgscomposerpicturewidgetbase.ui 2009-11-02 17:26:17 UTC (rev 11894)
@@ -1,52 +1,53 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>QgsComposerPictureWidgetBase</class>
- <widget class="QWidget" name="QgsComposerPictureWidgetBase" >
- <property name="geometry" >
+ <widget class="QWidget" name="QgsComposerPictureWidgetBase">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
- <width>342</width>
+ <width>299</width>
<height>613</height>
</rect>
</property>
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>Picture Options</string>
</property>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="4" >
- <widget class="QGroupBox" name="mSearchDirectoriesGroupBox" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="mSearchDirectoriesGroupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="title" >
+ <property name="title">
<string>Search directories</string>
</property>
- <layout class="QGridLayout" >
- <item row="0" column="0" colspan="3" >
- <widget class="QComboBox" name="mSearchDirectoriesComboBox" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <layout class="QGridLayout">
+ <item row="0" column="0" colspan="3">
+ <widget class="QComboBox" name="mSearchDirectoriesComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
- <item row="1" column="0" >
+ <item row="1" column="0">
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0">
<size>
<width>101</width>
<height>20</height>
@@ -54,16 +55,16 @@
</property>
</spacer>
</item>
- <item row="1" column="1" >
- <widget class="QPushButton" name="mAddDirectoryButton" >
- <property name="text" >
+ <item row="1" column="1">
+ <widget class="QPushButton" name="mAddDirectoryButton">
+ <property name="text">
<string>Add...</string>
</property>
</widget>
</item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="mRemoveDirectoryButton" >
- <property name="text" >
+ <item row="1" column="2">
+ <widget class="QPushButton" name="mRemoveDirectoryButton">
+ <property name="text">
<string>Remove</string>
</property>
</widget>
@@ -71,45 +72,45 @@
</layout>
</widget>
</item>
- <item row="1" column="0" colspan="4" >
- <widget class="QGroupBox" name="mPreviewGroupBox" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+ <item row="1" column="0" colspan="2">
+ <widget class="QGroupBox" name="mPreviewGroupBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="title" >
+ <property name="title">
<string>Preview</string>
</property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QListWidget" name="mPreviewListWidget" >
- <property name="showDropIndicator" stdset="0" >
+ <layout class="QGridLayout">
+ <item row="0" column="0">
+ <widget class="QListWidget" name="mPreviewListWidget">
+ <property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
- <property name="dragDropMode" >
+ <property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
- <property name="movement" >
+ <property name="movement">
<enum>QListView::Free</enum>
</property>
- <property name="flow" >
+ <property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
- <property name="isWrapping" stdset="0" >
+ <property name="isWrapping" stdset="0">
<bool>true</bool>
</property>
- <property name="gridSize" >
+ <property name="gridSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
- <property name="viewMode" >
+ <property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
- <property name="wordWrap" >
+ <property name="wordWrap">
<bool>true</bool>
</property>
</widget>
@@ -117,107 +118,121 @@
</layout>
</widget>
</item>
- <item row="2" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Load</string>
- </property>
- <property name="buddy" >
- <cstring>mPictureLineEdit</cstring>
- </property>
- </widget>
+ <item row="2" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Load</string>
+ </property>
+ <property name="buddy">
+ <cstring>mPictureLineEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="mPictureLineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="mPictureBrowseButton">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>150</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
- <item row="2" column="1" colspan="2" >
- <widget class="QLineEdit" name="mPictureLineEdit" />
- </item>
- <item row="2" column="3" >
- <widget class="QPushButton" name="mPictureBrowseButton" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <item row="3" column="0">
+ <widget class="QLabel" name="textLabel3">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="maximumSize" >
- <size>
- <width>150</width>
- <height>32767</height>
- </size>
- </property>
- <property name="text" >
- <string>...</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" >
- <widget class="QLabel" name="textLabel3" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text" >
+ <property name="text">
<string>Width</string>
</property>
- <property name="wordWrap" >
+ <property name="wordWrap">
<bool>true</bool>
</property>
- <property name="buddy" >
+ <property name="buddy">
<cstring>mWidthLineEdit</cstring>
</property>
</widget>
</item>
- <item row="3" column="1" colspan="3" >
- <widget class="QLineEdit" name="mWidthLineEdit" />
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="mWidthLineEdit"/>
</item>
- <item row="4" column="0" >
- <widget class="QLabel" name="textLabel4" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
+ <item row="4" column="0">
+ <widget class="QLabel" name="textLabel4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text" >
+ <property name="text">
<string>Height</string>
</property>
- <property name="wordWrap" >
+ <property name="wordWrap">
<bool>true</bool>
</property>
- <property name="buddy" >
+ <property name="buddy">
<cstring>mHeightLineEdit</cstring>
</property>
</widget>
</item>
- <item row="4" column="1" colspan="3" >
- <widget class="QLineEdit" name="mHeightLineEdit" />
+ <item row="4" column="1">
+ <widget class="QLineEdit" name="mHeightLineEdit"/>
</item>
- <item row="5" column="0" colspan="2" >
- <widget class="QLabel" name="mRotationLabel" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
+ <item row="5" column="0">
+ <widget class="QLabel" name="mRotationLabel">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text" >
+ <property name="text">
<string>Rotation</string>
</property>
- <property name="wordWrap" >
+ <property name="wordWrap">
<bool>true</bool>
</property>
- <property name="buddy" >
+ <property name="buddy">
<cstring>mRotationSpinBox</cstring>
</property>
</widget>
</item>
- <item row="5" column="2" colspan="2" >
- <widget class="QDoubleSpinBox" name="mRotationSpinBox" />
+ <item row="5" column="1">
+ <widget class="QDoubleSpinBox" name="mRotationSpinBox"/>
</item>
+ <item row="6" column="0" colspan="2">
+ <widget class="QCheckBox" name="mRotationFromComposerMapCheckBox">
+ <property name="text">
+ <string>Take rotation from composer map</string>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="0" colspan="2">
+ <widget class="QComboBox" name="mComposerMapComboBox"/>
+ </item>
</layout>
</widget>
- <layoutdefault spacing="6" margin="11" />
+ <layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>mSearchDirectoriesComboBox</tabstop>
<tabstop>mAddDirectoryButton</tabstop>
More information about the QGIS-commit
mailing list