Port keyboard nudge of items from composer

This commit is contained in:
Nyall Dawson 2017-10-06 16:26:01 +10:00
parent 9c8b96be39
commit aa7beaad6a
6 changed files with 106 additions and 30 deletions

View File

@ -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``.
@ -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:

View File

@ -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 )
@ -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 )

View File

@ -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.
*
@ -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:

View File

@ -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 );

View File

@ -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
{
//ctrl+space pressed, so switch to temporary keyboard based zoom tool
setTool( mSpaceZoomTool );
}
event->accept();
// 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 )
{
increment = 1 / viewScale;
}
}
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();
}
}

View File

@ -691,16 +691,17 @@ 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 );
@ -708,41 +709,41 @@ void TestQgsLayoutItem::resize()
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 );
}