Skip to content

Commit

Permalink
Merge pull request #976 from nyalldawson/composer_zoom_marquee2
Browse files Browse the repository at this point in the history
Composer zoom improvements v2
  • Loading branch information
mhugent committed Oct 29, 2013
2 parents 9832ed9 + ab1766c commit e197b6f
Show file tree
Hide file tree
Showing 5 changed files with 239 additions and 6 deletions.
12 changes: 11 additions & 1 deletion src/app/composer/qgscomposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
QActionGroup* toggleActionGroup = new QActionGroup( this );
toggleActionGroup->addAction( mActionMoveItemContent );
toggleActionGroup->addAction( mActionPan );
toggleActionGroup->addAction( mActionMouseZoom );
toggleActionGroup->addAction( mActionAddNewMap );
toggleActionGroup->addAction( mActionAddNewLabel );
toggleActionGroup->addAction( mActionAddNewLegend );
Expand All @@ -158,7 +159,6 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
toggleActionGroup->addAction( mActionAddHtml );
toggleActionGroup->setExclusive( true );


mActionAddNewMap->setCheckable( true );
mActionAddNewLabel->setCheckable( true );
mActionAddNewLegend->setCheckable( true );
Expand All @@ -167,6 +167,7 @@ QgsComposer::QgsComposer( QgisApp *qgis, const QString& title )
mActionAddImage->setCheckable( true );
mActionMoveItemContent->setCheckable( true );
mActionPan->setCheckable( true );
mActionMouseZoom->setCheckable( true );
mActionAddArrow->setCheckable( true );

mActionShowGrid->setCheckable( true );
Expand Down Expand Up @@ -476,6 +477,7 @@ void QgsComposer::setupTheme()
mActionZoomAll->setIcon( QgsApplication::getThemeIcon( "/mActionZoomFullExtent.svg" ) );
mActionZoomIn->setIcon( QgsApplication::getThemeIcon( "/mActionZoomIn.svg" ) );
mActionZoomOut->setIcon( QgsApplication::getThemeIcon( "/mActionZoomOut.svg" ) );
mActionMouseZoom->setIcon( QgsApplication::getThemeIcon( "/mActionZoomToSelected.svg" ) );
mActionRefreshView->setIcon( QgsApplication::getThemeIcon( "/mActionDraw.svg" ) );
mActionUndo->setIcon( QgsApplication::getThemeIcon( "/mActionUndo.png" ) );
mActionRedo->setIcon( QgsApplication::getThemeIcon( "/mActionRedo.png" ) );
Expand Down Expand Up @@ -705,6 +707,14 @@ void QgsComposer::on_mActionZoomOut_triggered()
emit zoomLevelChanged();
}

void QgsComposer::on_mActionMouseZoom_triggered()
{
if ( mView )
{
mView->setCurrentTool( QgsComposerView::Zoom );
}
}

void QgsComposer::on_mActionRefreshView_triggered()
{
if ( !mComposition )
Expand Down
3 changes: 3 additions & 0 deletions src/app/composer/qgscomposer.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ class QgsComposer: public QMainWindow, private Ui::QgsComposerBase
//! Set tool to move item content
void on_mActionPan_triggered();

//! Set tool to mouse zoom
void on_mActionMouseZoom_triggered();

//! Group selected items
void on_mActionGroupItems_triggered();

Expand Down
196 changes: 192 additions & 4 deletions src/gui/qgscomposerview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,16 @@
#include "qgsaddremovemultiframecommand.h"
#include "qgspaperitem.h"
#include "qgsmapcanvas.h" //for QgsMapCanvas::WheelAction
#include "qgscursors.h"

QgsComposerView::QgsComposerView( QWidget* parent, const char* name, Qt::WFlags f )
: QGraphicsView( parent )
, mRubberBandItem( 0 )
, mRubberBandLineItem( 0 )
, mMoveContentItem( 0 )
, mMarqueeSelect( false )
, mMarqueeZoom( false )
, mTemporaryZoomStatus( QgsComposerView::Inactive )
, mPaintingEnabled( true )
, mHorizontalRuler( 0 )
, mVerticalRuler( 0 )
Expand Down Expand Up @@ -77,6 +80,15 @@ void QgsComposerView::setCurrentTool( QgsComposerView::Tool t )
composition()->setPreventCursorChange( true );
viewport()->setCursor( Qt::OpenHandCursor );
}
else if ( t == QgsComposerView::Zoom )
{
//lock cursor to prevent composer items changing it
composition()->setPreventCursorChange( true );
//set the cursor to zoom in
QPixmap myZoomQPixmap = QPixmap(( const char ** )( zoom_in ) );
QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 );
viewport()->setCursor( zoomCursor );
}
else
{
//not using pan tool, composer items can change cursor
Expand Down Expand Up @@ -206,6 +218,33 @@ void QgsComposerView::mousePressEvent( QMouseEvent* e )
break;
}

case Zoom:
{
if ( !( e->modifiers() & Qt::ShiftModifier ) )
{
//zoom in action
startMarqueeZoom( scenePoint );
}
else
{
//zoom out action, so zoom out and recenter on clicked point
double scaleFactor = 2;
//get current visible part of scene
QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );

//transform the mouse pos to scene coordinates
QPointF scenePoint = mapToScene( e->pos() );

visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() );
QRectF boundsRect = visibleRect.toRectF();

//zoom view to fit desired bounds
fitInView( boundsRect, Qt::KeepAspectRatio );
}
break;
}

case Pan:
{
//pan action
Expand Down Expand Up @@ -473,6 +512,63 @@ void QgsComposerView::endMarqueeSelect( QMouseEvent* e )
}
}

void QgsComposerView::startMarqueeZoom( QPointF & scenePoint )
{
mMarqueeZoom = true;

QTransform t;
mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 );
mRubberBandItem->setBrush( QBrush( QColor( 70, 50, 255, 25 ) ) );
mRubberBandItem->setPen( QPen( QColor( 70, 50, 255, 100 ) ) );
mRubberBandStartPos = QPointF( scenePoint.x(), scenePoint.y() );
t.translate( scenePoint.x(), scenePoint.y() );
mRubberBandItem->setTransform( t );
mRubberBandItem->setZValue( 1000 );
scene()->addItem( mRubberBandItem );
scene()->update();
}

void QgsComposerView::endMarqueeZoom( QMouseEvent* e )
{
mMarqueeZoom = false;

QRectF boundsRect;

if ( !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) )
{
//just a click, so zoom to clicked point and recenter
double scaleFactor = 0.5;
//get current visible part of scene
QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() );
QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() );

//transform the mouse pos to scene coordinates
QPointF scenePoint = mapToScene( e->pos() );

visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() );
boundsRect = visibleRect.toRectF();
}
else
{
//marquee zoom
//zoom bounds are size marquee object
boundsRect = QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(),
mRubberBandItem->rect().width(), mRubberBandItem->rect().height() );
}

removeRubberBand();
//zoom view to fit desired bounds
fitInView( boundsRect, Qt::KeepAspectRatio );

if ( mTemporaryZoomStatus == QgsComposerView::ActiveUntilMouseRelease )
{
//user was using the temporary keyboard activated zoom tool
//and the control or space key was released before mouse button, so end temporary zoom
mTemporaryZoomStatus = QgsComposerView::Inactive;
setCurrentTool( mPreviousTool );
}
}

void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
{
if ( !composition() )
Expand Down Expand Up @@ -516,6 +612,15 @@ void QgsComposerView::mouseReleaseEvent( QMouseEvent* e )
break;
}

case Zoom:
{
if ( mMarqueeZoom )
{
endMarqueeZoom( e );
}
break;
}

case MoveItemContent:
{
if ( mMoveContentItem )
Expand Down Expand Up @@ -635,7 +740,7 @@ void QgsComposerView::mouseMoveEvent( QMouseEvent* e )
{
QPointF scenePoint = mapToScene( e->pos() );

if ( mMarqueeSelect )
if ( mMarqueeSelect || mMarqueeZoom )
{
updateRubberBand( scenePoint );
return;
Expand Down Expand Up @@ -919,11 +1024,43 @@ void QgsComposerView::keyPressEvent( QKeyEvent * e )
if ( mPanning )
return;

if ( e->key() == Qt::Key_Space )
if ( mTemporaryZoomStatus != QgsComposerView::Inactive )
{
// Pan composer with space bar
if ( ! e->isAutoRepeat() )
//temporary keyboard based zoom is active
if ( e->isAutoRepeat() )
{
return;
}

//respond to changes in ctrl key status
if ( !( e->modifiers() & Qt::ControlModifier ) && !mMarqueeZoom )
{
//space pressed, but control key was released, end of temporary zoom tool
mTemporaryZoomStatus = QgsComposerView::Inactive;
setCurrentTool( mPreviousTool );
}
else if ( !( e->modifiers() & Qt::ControlModifier ) && mMarqueeZoom )
{
//control key released, but user is mid-way through a marquee zoom
//so end temporary zoom when user releases the mouse button
mTemporaryZoomStatus = QgsComposerView::ActiveUntilMouseRelease;
}
else
{
//both control and space pressed
//set cursor to zoom in/out depending on shift key status
QPixmap myZoomQPixmap = QPixmap(( const char ** )( e->modifiers() & Qt::ShiftModifier ? zoom_out : zoom_in ) );
QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 );
viewport()->setCursor( zoomCursor );
}
return;
}

if ( e->key() == Qt::Key_Space && ! e->isAutoRepeat() )
{
if ( !( e->modifiers() & Qt::ControlModifier ) )
{
// Pan composer with space bar
mPanning = true;
mMouseLastXY = mMouseCurrentXY;
if ( composition() )
Expand All @@ -932,6 +1069,30 @@ void QgsComposerView::keyPressEvent( QKeyEvent * e )
composition()->setPreventCursorChange( true );
}
viewport()->setCursor( Qt::ClosedHandCursor );
return;
}
else
{
//ctrl+space pressed, so switch to temporary keyboard based zoom tool
mTemporaryZoomStatus = QgsComposerView::Active;
mPreviousTool = mCurrentTool;
setCurrentTool( Zoom );
//set cursor to zoom in/out depending on shift key status
QPixmap myZoomQPixmap = QPixmap(( const char ** )( e->modifiers() & Qt::ShiftModifier ? zoom_out : zoom_in ) );
QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 );
viewport()->setCursor( zoomCursor );
return;
}
}

if ( mCurrentTool == QgsComposerView::Zoom )
{
//using the zoom tool, respond to changes in shift key status and update mouse cursor accordingly
if ( ! e->isAutoRepeat() )
{
QPixmap myZoomQPixmap = QPixmap(( const char ** )( e->modifiers() & Qt::ShiftModifier ? zoom_out : zoom_in ) );
QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 );
viewport()->setCursor( zoomCursor );
}
return;
}
Expand Down Expand Up @@ -1008,6 +1169,33 @@ void QgsComposerView::keyReleaseEvent( QKeyEvent * e )
}
return;
}
else if ( e->key() == Qt::Key_Space && !e->isAutoRepeat() && mTemporaryZoomStatus != QgsComposerView::Inactive )
{
//temporary keyboard-based zoom tool is active and space key has been released
if ( mMarqueeZoom )
{
//currently in the middle of a marquee operation, so don't switch tool back immediately
//instead, wait until mouse button has been released before switching tool back
mTemporaryZoomStatus = QgsComposerView::ActiveUntilMouseRelease;
}
else
{
//switch tool back
mTemporaryZoomStatus = QgsComposerView::Inactive;
setCurrentTool( mPreviousTool );
}
}
else if ( mCurrentTool == QgsComposerView::Zoom )
{
//if zoom tool is active, respond to changes in the shift key status and update cursor accordingly
if ( ! e->isAutoRepeat() )
{
QPixmap myZoomQPixmap = QPixmap(( const char ** )( e->modifiers() & Qt::ShiftModifier ? zoom_out : zoom_in ) );
QCursor zoomCursor = QCursor( myZoomQPixmap, 7, 7 );
viewport()->setCursor( zoomCursor );
}
return;
}
}

void QgsComposerView::wheelEvent( QWheelEvent* event )
Expand Down
21 changes: 20 additions & 1 deletion src/gui/qgscomposerview.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
AddTriangle,
AddTable, //add attribute table
MoveItemContent, //move content of item (e.g. content of map)
Pan
Pan,
Zoom
};

enum ClipboardMode
Expand All @@ -82,6 +83,13 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
PasteModeInPlace
};

enum ToolStatus
{
Inactive,
Active,
ActiveUntilMouseRelease
};

QgsComposerView( QWidget* parent = 0, const char* name = 0, Qt::WFlags f = 0 );

/**Add an item group containing the selected items*/
Expand Down Expand Up @@ -150,6 +158,9 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
private:
/**Current composer tool*/
QgsComposerView::Tool mCurrentTool;
/**Previous composer tool*/
QgsComposerView::Tool mPreviousTool;

/**Rubber band item*/
QGraphicsRectItem* mRubberBandItem;
/**Rubber band item for arrows*/
Expand All @@ -163,6 +174,10 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView

/**True if user is currently selecting by marquee*/
bool mMarqueeSelect;
/**True if user is currently zooming by marquee*/
bool mMarqueeZoom;
/**True if user is currently temporarily activating the zoom tool by holding control+space*/
QgsComposerView::ToolStatus mTemporaryZoomStatus;

bool mPaintingEnabled;

Expand All @@ -187,6 +202,10 @@ class GUI_EXPORT QgsComposerView: public QGraphicsView
void startMarqueeSelect( QPointF & scenePoint );
/**Finalises a marquee selection*/
void endMarqueeSelect( QMouseEvent* e );
/**Starts a zoom in marquee*/
void startMarqueeZoom( QPointF & scenePoint );
/**Finalises a marquee zoom*/
void endMarqueeZoom( QMouseEvent* e );

//void connectAddRemoveCommandSignals( QgsAddRemoveItemCommand* c );

Expand Down
Loading

0 comments on commit e197b6f

Please sign in to comment.