From 06650808b546721be028a8c9390bf6e69d4348eb Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 10 Oct 2017 19:27:52 +1000 Subject: [PATCH] Fix resize of grouped items with non-top left reference points --- src/app/layout/qgslayoutguidewidget.cpp | 18 +-- src/app/layout/qgslayoutguidewidget.h | 4 +- src/core/layout/qgslayoutitemgroup.cpp | 8 +- tests/src/core/testqgslayoutitemgroup.cpp | 136 ++++++++++++++++++++++ 4 files changed, 152 insertions(+), 14 deletions(-) diff --git a/src/app/layout/qgslayoutguidewidget.cpp b/src/app/layout/qgslayoutguidewidget.cpp index 71c50c51d23..7151794d6ad 100644 --- a/src/app/layout/qgslayoutguidewidget.cpp +++ b/src/app/layout/qgslayoutguidewidget.cpp @@ -39,11 +39,11 @@ QgsLayoutGuideWidget::QgsLayoutGuideWidget( QWidget *parent, QgsLayout *layout, mVertGuidesTableView->setEditTriggers( QAbstractItemView::AllEditTriggers ); - mHozGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mLayout, mHozProxyModel ) ); - mHozGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mLayout, mHozProxyModel ) ); + mHozGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mHozGuidesTableView, mLayout, mHozProxyModel ) ); + mHozGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mHozGuidesTableView, mLayout, mHozProxyModel ) ); - mVertGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mLayout, mVertProxyModel ) ); - mVertGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mLayout, mVertProxyModel ) ); + mVertGuidesTableView->setItemDelegateForColumn( 0, new QgsLayoutGuidePositionDelegate( mVertGuidesTableView, mLayout, mVertProxyModel ) ); + mVertGuidesTableView->setItemDelegateForColumn( 1, new QgsLayoutGuideUnitDelegate( mVertGuidesTableView, mLayout, mVertProxyModel ) ); connect( mAddHozGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addHorizontalGuide ); connect( mAddVertGuideButton, &QPushButton::clicked, this, &QgsLayoutGuideWidget::addVerticalGuide ); @@ -139,8 +139,9 @@ void QgsLayoutGuideWidget::applyToAll() } -QgsLayoutGuidePositionDelegate::QgsLayoutGuidePositionDelegate( QgsLayout *layout, QAbstractItemModel *model ) - : mLayout( layout ) +QgsLayoutGuidePositionDelegate::QgsLayoutGuidePositionDelegate( QObject *parent, QgsLayout *layout, QAbstractItemModel *model ) + : QStyledItemDelegate( parent ) + , mLayout( layout ) , mModel( model ) { @@ -172,8 +173,9 @@ void QgsLayoutGuidePositionDelegate::setModelData( const QModelIndex &index, con mModel->setData( index, value, role ); } -QgsLayoutGuideUnitDelegate::QgsLayoutGuideUnitDelegate( QgsLayout *layout, QAbstractItemModel *model ) - : mLayout( layout ) +QgsLayoutGuideUnitDelegate::QgsLayoutGuideUnitDelegate( QObject *parent, QgsLayout *layout, QAbstractItemModel *model ) + : QStyledItemDelegate( parent ) + , mLayout( layout ) , mModel( model ) { diff --git a/src/app/layout/qgslayoutguidewidget.h b/src/app/layout/qgslayoutguidewidget.h index e23ed7936ed..e893591995a 100644 --- a/src/app/layout/qgslayoutguidewidget.h +++ b/src/app/layout/qgslayoutguidewidget.h @@ -62,7 +62,7 @@ class QgsLayoutGuidePositionDelegate : public QStyledItemDelegate public: - QgsLayoutGuidePositionDelegate( QgsLayout *layout, QAbstractItemModel *model ); + QgsLayoutGuidePositionDelegate( QObject *parent, QgsLayout *layout, QAbstractItemModel *model ); protected: QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem & /*option*/, const QModelIndex &index ) const override; @@ -82,7 +82,7 @@ class QgsLayoutGuideUnitDelegate : public QStyledItemDelegate public: - QgsLayoutGuideUnitDelegate( QgsLayout *layout, QAbstractItemModel *model ); + QgsLayoutGuideUnitDelegate( QObject *parent, QgsLayout *layout, QAbstractItemModel *model ); protected: QWidget *createEditor( QWidget *parent, const QStyleOptionViewItem & /*option*/, const QModelIndex &index ) const override; diff --git a/src/core/layout/qgslayoutitemgroup.cpp b/src/core/layout/qgslayoutitemgroup.cpp index d614880e501..73aee54a012 100644 --- a/src/core/layout/qgslayoutitemgroup.cpp +++ b/src/core/layout/qgslayoutitemgroup.cpp @@ -204,13 +204,13 @@ void QgsLayoutItemGroup::attemptResize( const QgsLayoutSize &size ) itemRect = itemRect.normalized(); QPointF newPos = mapToScene( itemRect.topLeft() ); - // translate new position to current item units - QgsLayoutPoint itemPos = mLayout->convertFromLayoutUnits( newPos, item->positionWithUnits().units() ); - item->attemptMove( itemPos ); - QgsLayoutSize itemSize = mLayout->convertFromLayoutUnits( itemRect.size(), item->sizeWithUnits().units() ); item->attemptResize( itemSize ); + // translate new position to current item units + QgsLayoutPoint itemPos = mLayout->convertFromLayoutUnits( newPos, item->positionWithUnits().units() ); + item->attemptMove( itemPos, false ); + if ( command ) { command->saveAfterState(); diff --git a/tests/src/core/testqgslayoutitemgroup.cpp b/tests/src/core/testqgslayoutitemgroup.cpp index 42b409e9dc0..1f6bf9689df 100644 --- a/tests/src/core/testqgslayoutitemgroup.cpp +++ b/tests/src/core/testqgslayoutitemgroup.cpp @@ -48,7 +48,9 @@ class TestQgsLayoutItemGroup : public QObject void deleteGroup(); //test deleting group works void groupVisibility(); void moveGroup(); + void moveGroupReferencePos(); void resizeGroup(); + void resizeGroupReferencePos(); void undoRedo(); //test that group/ungroup undo/redo commands don't crash private: @@ -354,6 +356,69 @@ void TestQgsLayoutItemGroup::moveGroup() QCOMPARE( item2->positionWithUnits().units(), QgsUnitTypes::LayoutInches ); } +void TestQgsLayoutItemGroup::moveGroupReferencePos() +{ + QgsProject proj; + QgsLayout l( &proj ); + + QgsLayoutItemRectangularShape *item = new QgsLayoutItemRectangularShape( &l ); + l.addLayoutItem( item ); + item->attemptMove( QgsLayoutPoint( 5, 9 ) ); + item->attemptResize( QgsLayoutSize( 4, 7 ) ); + item->setReferencePoint( QgsLayoutItem::UpperRight ); + + QCOMPARE( item->positionWithUnits().x(), 9.0 ); + QCOMPARE( item->positionWithUnits().y(), 9.0 ); + QCOMPARE( item->scenePos().x(), 5.0 ); + QCOMPARE( item->scenePos().y(), 9.0 ); + + QgsLayoutItemRectangularShape *item2 = new QgsLayoutItemRectangularShape( &l ); + l.addLayoutItem( item2 ); + item2->attemptMove( QgsLayoutPoint( 15, 19 ) ); + item2->attemptResize( QgsLayoutSize( 6, 3 ) ); + item2->setReferencePoint( QgsLayoutItem::LowerLeft ); + + QCOMPARE( item2->positionWithUnits().x(), 15.0 ); + QCOMPARE( item2->positionWithUnits().y(), 22.0 ); + QCOMPARE( item2->scenePos().x(), 15.0 ); + QCOMPARE( item2->scenePos().y(), 19.0 ); + + //group items + QList groupItems; + groupItems << item << item2; + QgsLayoutItemGroup *group = l.groupItems( groupItems ); + + QCOMPARE( group->positionWithUnits().x(), 5.0 ); + QCOMPARE( group->positionWithUnits().y(), 9.0 ); + QCOMPARE( group->positionWithUnits().units(), QgsUnitTypes::LayoutMillimeters ); + QCOMPARE( group->sizeWithUnits().width(), 16.0 ); + QCOMPARE( group->sizeWithUnits().height(), 13.0 ); + QCOMPARE( group->scenePos().x(), 5.0 ); + QCOMPARE( group->scenePos().y(), 9.0 ); + QCOMPARE( group->rect().width(), 16.0 ); + QCOMPARE( group->rect().height(), 13.0 ); + + group->attemptMove( QgsLayoutPoint( 2, 4 ) ); + QCOMPARE( group->positionWithUnits().x(), 2.0 ); + QCOMPARE( group->positionWithUnits().y(), 4.0 ); + QCOMPARE( group->scenePos().x(), 2.0 ); + QCOMPARE( group->scenePos().y(), 4.0 ); + QCOMPARE( group->sizeWithUnits().width(), 16.0 ); + QCOMPARE( group->sizeWithUnits().height(), 13.0 ); + QCOMPARE( group->rect().width(), 16.0 ); + QCOMPARE( group->rect().height(), 13.0 ); + + QCOMPARE( item->pos().x(), 2.0 ); + QCOMPARE( item->pos().y(), 4.0 ); + QCOMPARE( item->positionWithUnits().x(), 6.0 ); + QCOMPARE( item->positionWithUnits().y(), 4.0 ); + + QCOMPARE( item2->pos().x(), 12.0 ); + QCOMPARE( item2->pos().y(), 14.0 ); + QCOMPARE( item2->positionWithUnits().x(), 12.0 ); + QCOMPARE( item2->positionWithUnits().y(), 17.0 ); +} + void TestQgsLayoutItemGroup::resizeGroup() { QgsProject proj; @@ -402,6 +467,77 @@ void TestQgsLayoutItemGroup::resizeGroup() QCOMPARE( item2->sizeWithUnits().units(), QgsUnitTypes::LayoutInches ); } +void TestQgsLayoutItemGroup::resizeGroupReferencePos() +{ + QgsProject proj; + QgsLayout l( &proj ); + + QgsLayoutItemRectangularShape *item = new QgsLayoutItemRectangularShape( &l ); + l.addLayoutItem( item ); + item->attemptMove( QgsLayoutPoint( 5, 9 ) ); + item->attemptResize( QgsLayoutSize( 4, 7 ) ); + item->setReferencePoint( QgsLayoutItem::UpperRight ); + + QCOMPARE( item->positionWithUnits().x(), 9.0 ); + QCOMPARE( item->positionWithUnits().y(), 9.0 ); + QCOMPARE( item->scenePos().x(), 5.0 ); + QCOMPARE( item->scenePos().y(), 9.0 ); + + QgsLayoutItemRectangularShape *item2 = new QgsLayoutItemRectangularShape( &l ); + l.addLayoutItem( item2 ); + item2->attemptMove( QgsLayoutPoint( 15, 19 ) ); + item2->attemptResize( QgsLayoutSize( 6, 3 ) ); + item2->setReferencePoint( QgsLayoutItem::LowerLeft ); + + QCOMPARE( item2->positionWithUnits().x(), 15.0 ); + QCOMPARE( item2->positionWithUnits().y(), 22.0 ); + QCOMPARE( item2->scenePos().x(), 15.0 ); + QCOMPARE( item2->scenePos().y(), 19.0 ); + + //group items + QList groupItems; + groupItems << item << item2; + QgsLayoutItemGroup *group = l.groupItems( groupItems ); + + QCOMPARE( group->positionWithUnits().x(), 5.0 ); + QCOMPARE( group->positionWithUnits().y(), 9.0 ); + QCOMPARE( group->positionWithUnits().units(), QgsUnitTypes::LayoutMillimeters ); + QCOMPARE( group->sizeWithUnits().width(), 16.0 ); + QCOMPARE( group->sizeWithUnits().height(), 13.0 ); + QCOMPARE( group->scenePos().x(), 5.0 ); + QCOMPARE( group->scenePos().y(), 9.0 ); + QCOMPARE( group->rect().width(), 16.0 ); + QCOMPARE( group->rect().height(), 13.0 ); + + group->attemptResize( QgsLayoutSize( 32.0, 26.0 ) ); + QCOMPARE( group->positionWithUnits().x(), 5.0 ); + QCOMPARE( group->positionWithUnits().y(), 9.0 ); + QCOMPARE( group->scenePos().x(), 5.0 ); + QCOMPARE( group->scenePos().y(), 9.0 ); + QCOMPARE( group->sizeWithUnits().width(), 32.0 ); + QCOMPARE( group->sizeWithUnits().height(), 26.0 ); + QCOMPARE( group->rect().width(), 32.0 ); + QCOMPARE( group->rect().height(), 26.0 ); + + QCOMPARE( item->pos().x(), 5.0 ); + QCOMPARE( item->pos().y(), 9.0 ); + QCOMPARE( item->positionWithUnits().x(), 13.0 ); + QCOMPARE( item->positionWithUnits().y(), 9.0 ); + QCOMPARE( item->sizeWithUnits().width(), 8.0 ); + QCOMPARE( item->sizeWithUnits().height(), 14.0 ); + QCOMPARE( item->rect().width(), 8.0 ); + QCOMPARE( item->rect().height(), 14.0 ); + + QCOMPARE( item2->pos().x(), 25.0 ); + QCOMPARE( item2->pos().y(), 29.0 ); + QCOMPARE( item2->positionWithUnits().x(), 25.0 ); + QCOMPARE( item2->positionWithUnits().y(), 35.0 ); + QCOMPARE( item2->sizeWithUnits().width(), 12.0 ); + QCOMPARE( item2->sizeWithUnits().height(), 6.0 ); + QCOMPARE( item2->rect().width(), 12.0 ); + QCOMPARE( item2->rect().height(), 6.0 ); +} + Q_DECLARE_METATYPE( QgsLayoutItemGroup * ) Q_DECLARE_METATYPE( QgsLayoutItemRectangularShape * ) Q_DECLARE_METATYPE( QgsLayoutItem * )