Skip to content

Commit

Permalink
[composer] Fix ctrl modifier not applying to wheel events when in mov…
Browse files Browse the repository at this point in the history
…e item

content mode, add missing undo merge command for item zoom (refs #7974)
  • Loading branch information
nyalldawson committed Sep 29, 2014
1 parent 583151a commit 8725c2d
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 44 deletions.
28 changes: 24 additions & 4 deletions python/core/composer/qgscomposeritem.sip
Expand Up @@ -133,6 +133,16 @@ class QgsComposerItem : QgsComposerObject, QGraphicsRectItem
LowerRight
};

/** Modes for zooming item content
*/
enum ZoomMode
{
Zoom = 0, /*< Zoom to center of content */
ZoomRecenter, /*< Zoom and recenter content to point */
ZoomToPoint, /*< Zoom while maintaining relative position of point */
NoZoom /*< No zoom */
};

/**Constructor
@param composition parent composition
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
Expand Down Expand Up @@ -183,10 +193,20 @@ class QgsComposerItem : QgsComposerObject, QGraphicsRectItem
virtual void moveContent( double dx, double dy );

/**Zoom content of item. Does nothing per default (but implemented in composer map)
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-position of mouse cursor (in item coordinates)
@param y y-position of mouse cursor (in item coordinates)*/
virtual void zoomContent( int delta, double x, double y );
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
virtual void zoomContent( int delta, double x, double y ) /Deprecated/;

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom );

/**Gets the page the item is currently on.
* @returns page number for item
Expand Down
18 changes: 14 additions & 4 deletions python/core/composer/qgscomposermap.sip
Expand Up @@ -130,10 +130,20 @@ class QgsComposerMap : QgsComposerItem
void moveContent( double dx, double dy );

/**Zoom content of map
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-coordinate of mouse position in item coordinates
@param y y-coordinate of mouse position in item coordinates*/
void zoomContent( int delta, double x, double y );
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
void zoomContent( int delta, double x, double y ) /Deprecated/;

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom );

/**Sets new scene rectangle bounds and recalculates hight and extent*/
void setSceneRect( const QRectF& rectangle );
Expand Down
30 changes: 26 additions & 4 deletions src/core/composer/qgscomposeritem.h
Expand Up @@ -89,6 +89,18 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
LowerRight
};

//note - must sync with QgsMapCanvas::WheelAction.
//TODO - QGIS 3.0 move QgsMapCanvas::WheelAction from GUI->CORE and remove this enum
/** Modes for zooming item content
*/
enum ZoomMode
{
Zoom = 0, /*< Zoom to center of content */
ZoomRecenter, /*< Zoom and recenter content to point */
ZoomToPoint, /*< Zoom while maintaining relative position of point */
NoZoom /*< No zoom */
};

/**Constructor
@param composition parent composition
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
Expand Down Expand Up @@ -139,10 +151,20 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
virtual void moveContent( double dx, double dy ) { Q_UNUSED( dx ); Q_UNUSED( dy ); }

/**Zoom content of item. Does nothing per default (but implemented in composer map)
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-position of mouse cursor (in item coordinates)
@param y y-position of mouse cursor (in item coordinates)*/
virtual void zoomContent( int delta, double x, double y ) { Q_UNUSED( delta ); Q_UNUSED( x ); Q_UNUSED( y ); }
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
Q_DECL_DEPRECATED virtual void zoomContent( int delta, double x, double y ) { Q_UNUSED( delta ); Q_UNUSED( x ); Q_UNUSED( y ); }

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom ) { Q_UNUSED( factor ); Q_UNUSED( point ); Q_UNUSED( mode ); }

/**Gets the page the item is currently on.
* @returns page number for item
Expand Down
3 changes: 2 additions & 1 deletion src/core/composer/qgscomposeritemcommand.h
Expand Up @@ -119,7 +119,8 @@ class CORE_EXPORT QgsComposerMergeCommand: public QgsComposerItemCommand
ItemOutlineWidth,
ItemMove,
ItemRotation,
ItemTransparency
ItemTransparency,
ItemZoomContent
};

QgsComposerMergeCommand( Context c, QgsComposerItem* item, const QString& text );
Expand Down
58 changes: 33 additions & 25 deletions src/core/composer/qgscomposermap.cpp
Expand Up @@ -605,55 +605,63 @@ void QgsComposerMap::moveContent( double dx, double dy )

void QgsComposerMap::zoomContent( int delta, double x, double y )
{
if ( mDrawing )
QSettings settings;

//read zoom mode
QgsComposerItem::ZoomMode zoomMode = ( QgsComposerItem::ZoomMode )settings.value( "/qgis/wheel_action", 2 ).toInt();
if ( zoomMode == QgsComposerItem::NoZoom )
{
//do nothing
return;
}

QSettings settings;
double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
zoomFactor = delta > 0 ? zoomFactor : 1 / zoomFactor;

//read zoom mode
//0: zoom, 1: zoom and recenter, 2: zoom to cursor, 3: nothing
int zoomMode = settings.value( "/qgis/wheel_action", 2 ).toInt();
if ( zoomMode == 3 ) //do nothing
zoomContent( zoomFactor, QPointF( x, y ), zoomMode );
}

void QgsComposerMap::zoomContent( const double factor, const QPointF point, const ZoomMode mode )
{
if ( mDrawing )
{
return;
}

double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
if ( mode == QgsComposerItem::NoZoom )
{
//do nothing
return;
}

//find out map coordinates of position
double mapX = currentMapExtent()->xMinimum() + ( point.x() / rect().width() ) * ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() );
double mapY = currentMapExtent()->yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() );

//find out new center point
double centerX = ( currentMapExtent()->xMaximum() + currentMapExtent()->xMinimum() ) / 2;
double centerY = ( currentMapExtent()->yMaximum() + currentMapExtent()->yMinimum() ) / 2;

if ( zoomMode != 0 )
if ( mode != QgsComposerItem::Zoom )
{
//find out map coordinates of mouse position
double mapMouseX = currentMapExtent()->xMinimum() + ( x / rect().width() ) * ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() );
double mapMouseY = currentMapExtent()->yMinimum() + ( 1 - ( y / rect().height() ) ) * ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() );
if ( zoomMode == 1 ) //zoom and recenter
if ( mode == QgsComposerItem::ZoomRecenter )
{
centerX = mapMouseX;
centerY = mapMouseY;
centerX = mapX;
centerY = mapY;
}
else if ( zoomMode == 2 ) //zoom to cursor
else if ( mode == QgsComposerItem::ZoomToPoint )
{
centerX = mapMouseX + ( centerX - mapMouseX ) * ( 1.0 / zoomFactor );
centerY = mapMouseY + ( centerY - mapMouseY ) * ( 1.0 / zoomFactor );
centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
}
}

double newIntervalX, newIntervalY;

if ( delta > 0 )
{
newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) / zoomFactor;
newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) / zoomFactor;
}
else if ( delta < 0 )
if ( factor > 0 )
{
newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) * zoomFactor;
newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) * zoomFactor;
newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) / factor;
newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) / factor;
}
else //no need to zoom
{
Expand Down
18 changes: 14 additions & 4 deletions src/core/composer/qgscomposermap.h
Expand Up @@ -170,10 +170,20 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem
void moveContent( double dx, double dy );

/**Zoom content of map
@param delta value from wheel event that describes magnitude and direction (positive /negative number)
@param x x-coordinate of mouse position in item coordinates
@param y y-coordinate of mouse position in item coordinates*/
void zoomContent( int delta, double x, double y );
* @param delta value from wheel event that describes direction (positive /negative number)
* @param x x-position of mouse cursor (in item coordinates)
* @param y y-position of mouse cursor (in item coordinates)
* @deprecated use zoomContent( double, QPointF, ZoomMode ) instead
*/
Q_DECL_DEPRECATED void zoomContent( int delta, double x, double y );

/**Zoom content of item. Does nothing per default (but implemented in composer map)
* @param factor zoom factor, where > 1 results in a zoom in and < 1 results in a zoom out
* @param point item point for zoom center
* @param mode zoom mode
* @note added in QGIS 2.5
*/
virtual void zoomContent( const double factor, const QPointF point, const ZoomMode mode = QgsComposerItem::Zoom );

/**Sets new scene rectangle bounds and recalculates hight and extent*/
void setSceneRect( const QRectF& rectangle );
Expand Down
21 changes: 19 additions & 2 deletions src/gui/qgscomposerview.cpp
Expand Up @@ -1558,9 +1558,26 @@ void QgsComposerView::wheelEvent( QWheelEvent* event )
{
if ( theItem->isSelected() )
{
QSettings settings;
//read zoom mode
QgsComposerItem::ZoomMode zoomMode = ( QgsComposerItem::ZoomMode )settings.value( "/qgis/wheel_action", 2 ).toInt();
if ( zoomMode == QgsComposerItem::NoZoom )
{
//do nothing
return;
}

double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
if ( event->modifiers() & Qt::ControlModifier )
{
//holding ctrl while wheel zooming results in a finer zoom
zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
}
zoomFactor = event->delta() > 0 ? zoomFactor : 1 / zoomFactor;

QPointF itemPoint = theItem->mapFromScene( scenePoint );
theItem->beginCommand( tr( "Zoom item content" ) );
theItem->zoomContent( event->delta(), itemPoint.x(), itemPoint.y() );
theItem->beginCommand( tr( "Zoom item content" ), QgsComposerMergeCommand::ItemZoomContent );
theItem->zoomContent( zoomFactor, itemPoint, zoomMode );
theItem->endCommand();
}
}
Expand Down

0 comments on commit 8725c2d

Please sign in to comment.