Skip to content

Commit

Permalink
Port keyboard nudge of items from composer
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Oct 6, 2017
1 parent 9c8b96b commit aa7beaa
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 28 deletions.
9 changes: 7 additions & 2 deletions python/core/layout/qgslayoutitem.sip
Expand Up @@ -52,6 +52,11 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
LowerRight,
};

enum UndoCommand
{
UndoIncrementalMove,
};

explicit QgsLayoutItem( QgsLayout *layout, bool manageZValue = true );
%Docstring
Constructor for QgsLayoutItem, with the specified parent ``layout``.
Expand Down Expand Up @@ -445,9 +450,9 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt
Emitted on item rotation change.
%End

void sizeChanged();
void sizePositionChanged();
%Docstring
Emitted when the item's size changes.
Emitted when the item's size or position changes.
%End

protected:
Expand Down
4 changes: 2 additions & 2 deletions src/core/layout/qgslayoutitem.cpp
Expand Up @@ -293,8 +293,8 @@ void QgsLayoutItem::attemptResize( const QgsLayoutSize &size )
mItemSize = actualSizeTargetUnits;

setRect( 0, 0, actualSizeLayoutUnits.width(), actualSizeLayoutUnits.height() );
emit sizeChanged();
refreshItemPosition();
emit sizePositionChanged();
}

void QgsLayoutItem::attemptMove( const QgsLayoutPoint &point )
Expand All @@ -317,8 +317,8 @@ void QgsLayoutItem::attemptMove( const QgsLayoutPoint &point )

QgsLayoutPoint referencePointTargetUnits = mLayout->convertFromLayoutUnits( evaluatedPointLayoutUnits, point.units() );
mItemPosition = referencePointTargetUnits;

setScenePos( topLeftPointLayoutUnits );
emit sizePositionChanged();
}

void QgsLayoutItem::setScenePos( const QPointF &destinationPos )
Expand Down
10 changes: 8 additions & 2 deletions src/core/layout/qgslayoutitem.h
Expand Up @@ -79,6 +79,12 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
LowerRight, //!< Lower right corner of item
};

//! Layout item undo commands, used for collapsing undo commands
enum UndoCommand
{
UndoIncrementalMove = 1, //!< Layout item incremental movement, e.g. as a result of a keypress
};

/**
* Constructor for QgsLayoutItem, with the specified parent \a layout.
*
Expand Down Expand Up @@ -443,9 +449,9 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
void rotationChanged( double newRotation );

/**
* Emitted when the item's size changes.
* Emitted when the item's size or position changes.
*/
void sizeChanged();
void sizePositionChanged();

protected:

Expand Down
4 changes: 2 additions & 2 deletions src/gui/layout/qgslayoutmousehandles.cpp
Expand Up @@ -189,14 +189,14 @@ void QgsLayoutMouseHandles::selectionChanged()

if ( item->isSelected() )
{
connect( item, &QgsLayoutItem::sizeChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
connect( item, &QgsLayoutItem::sizePositionChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
connect( item, &QgsLayoutItem::rotationChanged, this, &QgsLayoutMouseHandles::selectedItemRotationChanged );
connect( item, &QgsLayoutItem::frameChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
connect( item, &QgsLayoutItem::lockChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
}
else
{
disconnect( item, &QgsLayoutItem::sizeChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
disconnect( item, &QgsLayoutItem::sizePositionChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
disconnect( item, &QgsLayoutItem::rotationChanged, this, &QgsLayoutMouseHandles::selectedItemRotationChanged );
disconnect( item, &QgsLayoutItem::frameChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
disconnect( item, &QgsLayoutItem::lockChanged, this, &QgsLayoutMouseHandles::selectedItemSizeChanged );
Expand Down
86 changes: 75 additions & 11 deletions src/gui/layout/qgslayoutview.cpp
Expand Up @@ -731,22 +731,86 @@ void QgsLayoutView::keyPressEvent( QKeyEvent *event )
mTool->keyPressEvent( event );
}

if ( !mTool || !event->isAccepted() )
if ( mTool && event->isAccepted() )
return;

if ( event->key() == Qt::Key_Space && ! event->isAutoRepeat() )
{
if ( event->key() == Qt::Key_Space && ! event->isAutoRepeat() )
if ( !( event->modifiers() & Qt::ControlModifier ) )
{
if ( !( event->modifiers() & Qt::ControlModifier ) )
{
// Pan layout with space bar
setTool( mSpacePanTool );
}
else
// Pan layout with space bar
setTool( mSpacePanTool );
}
else
{
//ctrl+space pressed, so switch to temporary keyboard based zoom tool
setTool( mSpaceZoomTool );
}
event->accept();
}
else if ( event->key() == Qt::Key_Left
|| event->key() == Qt::Key_Right
|| event->key() == Qt::Key_Up
|| event->key() == Qt::Key_Down )
{
QgsLayout *l = currentLayout();
const QList<QgsLayoutItem *> layoutItemList = l->selectedLayoutItems();

// increment used for cursor key item movement
double increment = 1.0;
if ( event->modifiers() & Qt::ShiftModifier )
{
//holding shift while pressing cursor keys results in a big step
increment = 10.0;
}
else if ( event->modifiers() & Qt::AltModifier )
{
//holding alt while pressing cursor keys results in a 1 pixel step
double viewScale = transform().m11();
if ( viewScale > 0 )
{
//ctrl+space pressed, so switch to temporary keyboard based zoom tool
setTool( mSpaceZoomTool );
increment = 1 / viewScale;
}
event->accept();
}

double deltaX = 0;
double deltaY = 0;
switch ( event->key() )
{
case Qt::Key_Left:
deltaX = -increment;
break;
case Qt::Key_Right:
deltaX = increment;
break;
case Qt::Key_Up:
deltaY = -increment;
break;
case Qt::Key_Down:
deltaY = increment;
break;
default:
break;
}

auto moveItem = [ l, deltaX, deltaY ]( QgsLayoutItem * item )
{
QgsLayoutPoint itemPos = item->positionWithUnits();
QgsLayoutPoint deltaPos = l->convertFromLayoutUnits( QPointF( deltaX, deltaY ), itemPos.units() );
itemPos.setX( itemPos.x() + deltaPos.x() );
itemPos.setY( itemPos.y() + deltaPos.y() );
item->attemptMove( itemPos );
};

l->undoStack()->beginMacro( tr( "Item moved" ) );
for ( QgsLayoutItem *item : layoutItemList )
{
l->undoStack()->beginCommand( item, tr( "Item moved" ), QgsLayoutItem::UndoIncrementalMove );
moveItem( item );
l->undoStack()->endCommand();
}
l->undoStack()->endMacro();
event->accept();
}
}

Expand Down
19 changes: 10 additions & 9 deletions tests/src/core/testqgslayoutitem.cpp
Expand Up @@ -691,58 +691,59 @@ void TestQgsLayoutItem::resize()
//resize test item (no restrictions), same units as layout
l.setUnits( QgsUnitTypes::LayoutMillimeters );
TestItem *item = new TestItem( &l );
QSignalSpy spySizeChanged( item, &QgsLayoutItem::sizeChanged );
QSignalSpy spySizeChanged( item, &QgsLayoutItem::sizePositionChanged );

item->setRect( 0, 0, 55, 45 );
item->attemptMove( QgsLayoutPoint( 27, 29 ) );
QCOMPARE( spySizeChanged.count(), 1 );
item->attemptResize( QgsLayoutSize( 100.0, 200.0, QgsUnitTypes::LayoutMillimeters ) );
QCOMPARE( spySizeChanged.count(), 2 );
QCOMPARE( item->rect().width(), 100.0 );
QCOMPARE( item->rect().height(), 200.0 );
QCOMPARE( item->scenePos().x(), 27.0 ); //item should not move
QCOMPARE( item->scenePos().y(), 29.0 );
QCOMPARE( spySizeChanged.count(), 1 );

//test conversion of units
l.setUnits( QgsUnitTypes::LayoutCentimeters );
item->setRect( 0, 0, 100, 200 );
item->attemptResize( QgsLayoutSize( 0.30, 0.45, QgsUnitTypes::LayoutMeters ) );
QCOMPARE( item->rect().width(), 30.0 );
QCOMPARE( item->rect().height(), 45.0 );
QCOMPARE( spySizeChanged.count(), 2 );
QCOMPARE( spySizeChanged.count(), 4 );

//test pixel -> page conversion
l.setUnits( QgsUnitTypes::LayoutInches );
l.context().setDpi( 100.0 );
item->refresh();
QCOMPARE( spySizeChanged.count(), 3 );
QCOMPARE( spySizeChanged.count(), 6 );
item->setRect( 0, 0, 1, 2 );
item->attemptResize( QgsLayoutSize( 140, 280, QgsUnitTypes::LayoutPixels ) );
QCOMPARE( item->rect().width(), 1.4 );
QCOMPARE( item->rect().height(), 2.8 );
QCOMPARE( spySizeChanged.count(), 4 );
QCOMPARE( spySizeChanged.count(), 7 );
//changing the dpi should resize the item
l.context().setDpi( 200.0 );
item->refresh();
QCOMPARE( item->rect().width(), 0.7 );
QCOMPARE( item->rect().height(), 1.4 );
QCOMPARE( spySizeChanged.count(), 5 );
QCOMPARE( spySizeChanged.count(), 8 );

//test page -> pixel conversion
l.setUnits( QgsUnitTypes::LayoutPixels );
l.context().setDpi( 100.0 );
item->refresh();
item->setRect( 0, 0, 2, 2 );
QCOMPARE( spySizeChanged.count(), 6 );
QCOMPARE( spySizeChanged.count(), 10 );
item->attemptResize( QgsLayoutSize( 1, 3, QgsUnitTypes::LayoutInches ) );
QCOMPARE( item->rect().width(), 100.0 );
QCOMPARE( item->rect().height(), 300.0 );
QCOMPARE( spySizeChanged.count(), 7 );
QCOMPARE( spySizeChanged.count(), 11 );
//changing dpi results in item resize
l.context().setDpi( 200.0 );
item->refresh();
QCOMPARE( item->rect().width(), 200.0 );
QCOMPARE( item->rect().height(), 600.0 );
QCOMPARE( spySizeChanged.count(), 8 );
QCOMPARE( spySizeChanged.count(), 13 );

l.setUnits( QgsUnitTypes::LayoutMillimeters );
}
Expand Down

0 comments on commit aa7beaa

Please sign in to comment.