From 753f6f5050e6f522153c7ec56b562d90cddbd1b0 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Fri, 20 Oct 2017 17:23:12 +1000 Subject: [PATCH] Start hooking up map widget gui --- python/core/layout/qgslayoutitem.sip | 2 + .../gui/layout/qgslayoutitemguiregistry.sip | 17 ++ src/app/layout/qgslayoutapputils.cpp | 18 +- src/app/layout/qgslayoutmapwidget.cpp | 160 +++++++----------- src/app/layout/qgslayoutmapwidget.h | 2 - src/core/layout/qgslayoutitem.h | 2 + src/core/layout/qgslayoutitemmap.cpp | 3 + src/gui/layout/qgslayoutitemguiregistry.cpp | 19 +++ src/gui/layout/qgslayoutitemguiregistry.h | 33 ++++ src/gui/layout/qgslayoutviewtooladditem.cpp | 3 + 10 files changed, 158 insertions(+), 101 deletions(-) diff --git a/python/core/layout/qgslayoutitem.sip b/python/core/layout/qgslayoutitem.sip index 2506fc82d06b..31cd5a4100ae 100644 --- a/python/core/layout/qgslayoutitem.sip +++ b/python/core/layout/qgslayoutitem.sip @@ -63,6 +63,8 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem, QgsLayoutUndoObjectInt UndoShapeStyle, UndoShapeCornerRadius, UndoNodeMove, + UndoAtlasMargin, + UndoMapRotation, }; explicit QgsLayoutItem( QgsLayout *layout, bool manageZValue = true ); diff --git a/python/gui/layout/qgslayoutitemguiregistry.sip b/python/gui/layout/qgslayoutitemguiregistry.sip index 4dce8ba92019..e62a87194134 100644 --- a/python/gui/layout/qgslayoutitemguiregistry.sip +++ b/python/gui/layout/qgslayoutitemguiregistry.sip @@ -112,12 +112,21 @@ class QgsLayoutItemAbstractGuiMetadata :rtype: QgsLayoutItem %End + virtual void newItemAddedToLayout( QgsLayoutItem *item ); +%Docstring + Called when a newly created item of the associated type has been added to a layout. + + This is only called for additions which result from GUI operations - i.e. it is not + called for items added from templates. +%End + }; + class QgsLayoutItemGuiGroup { %Docstring @@ -230,6 +239,14 @@ class QgsLayoutItemGuiRegistry : QObject :rtype: QgsLayoutItem %End + void newItemAddedToLayout( int metadataId, QgsLayoutItem *item ); +%Docstring + Called when a newly created item of the associated metadata ``metadataId`` has been added to a layout. + + This is only called for additions which result from GUI operations - i.e. it is not + called for items added from templates. +%End + QgsLayoutItemBaseWidget *createItemWidget( QgsLayoutItem *item ) const /Factory/; %Docstring Creates a new instance of a layout item configuration widget for the specified ``item``. diff --git a/src/app/layout/qgslayoutapputils.cpp b/src/app/layout/qgslayoutapputils.cpp index 8ab425c32105..e730a292809a 100644 --- a/src/app/layout/qgslayoutapputils.cpp +++ b/src/app/layout/qgslayoutapputils.cpp @@ -27,6 +27,8 @@ #include "qgslayoutitempolyline.h" #include "qgslayoutpolygonwidget.h" #include "qgslayoutpolylinewidget.h" +#include "qgisapp.h" +#include "qgsmapcanvas.h" void QgsLayoutAppUtils::registerGuiForKnownItemTypes() { @@ -50,11 +52,21 @@ void QgsLayoutAppUtils::registerGuiForKnownItemTypes() registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutItem + 1002, QStringLiteral( "test" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddLabel.svg" ) ), nullptr, createRubberBand ) ); - registry->addLayoutItemGuiMetadata( new QgsLayoutItemGuiMetadata( QgsLayoutItemRegistry::LayoutMap, QObject::tr( "Map" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMap.svg" ) ), - [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget * + auto mapItemMetadata = qgis::make_unique< QgsLayoutItemGuiMetadata >( QgsLayoutItemRegistry::LayoutMap, QObject::tr( "Map" ), QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMap.svg" ) ), + [ = ]( QgsLayoutItem * item )->QgsLayoutItemBaseWidget * { return new QgsLayoutMapWidget( qobject_cast< QgsLayoutItemMap * >( item ) ); - }, createRubberBand ) ); + }, createRubberBand ); + mapItemMetadata->setItemAddedToLayoutFunction( [ = ]( QgsLayoutItem * item ) + { + QgsLayoutItemMap *map = qobject_cast< QgsLayoutItemMap * >( item ); + Q_ASSERT( map ); + if ( QgisApp::instance()->mapCanvas() ) + { + map->zoomToExtent( QgisApp::instance()->mapCanvas()->mapSettings().visibleExtent() ); + } + } ); + registry->addLayoutItemGuiMetadata( mapItemMetadata.release() ); auto createShapeWidget = []( QgsLayoutItem * item )->QgsLayoutItemBaseWidget * diff --git a/src/app/layout/qgslayoutmapwidget.cpp b/src/app/layout/qgslayoutmapwidget.cpp index 52ac254f5886..b09aa9305bd4 100644 --- a/src/app/layout/qgslayoutmapwidget.cpp +++ b/src/app/layout/qgslayoutmapwidget.cpp @@ -20,6 +20,11 @@ #include "qgslayoutitemmap.h" #include "qgsproject.h" #include "qgsmapthemecollection.h" +#include "qgsmapthemes.h" +#include "qgslayout.h" +#include "qgisapp.h" +#include "qgsmapcanvas.h" + #include #include @@ -167,6 +172,7 @@ void QgsLayoutMapWidget::populateDataDefinedButtons() void QgsLayoutMapWidget::compositionAtlasToggled( bool atlasEnabled ) { + Q_UNUSED( atlasEnabled ); #if 0 //TODO if ( atlasEnabled && mMapItem && mMapItem->composition() && mMapItem->composition()->atlasComposition().coverageLayer() @@ -215,15 +221,15 @@ void QgsLayoutMapWidget::followVisibilityPresetSelected( int currentIndex ) presetName = mFollowVisibilityPresetCombo->currentText(); } -#if 0 //TODO if ( presetName == mMapItem->followVisibilityPresetName() ) return; + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Preset" ) ); mFollowVisibilityPresetCheckBox->setChecked( true ); mMapItem->setFollowVisibilityPresetName( presetName ); + mMapItem->layout()->undoStack()->endCommand(); mMapItem->invalidateCache(); -#endif } void QgsLayoutMapWidget::keepLayersVisibilityPresetSelected() @@ -232,7 +238,6 @@ void QgsLayoutMapWidget::keepLayersVisibilityPresetSelected() if ( !action ) return; -#if 0 //TODO QString presetName = action->text(); QList lst = QgsMapThemes::instance()->orderedPresetVisibleLayers( presetName ); if ( mMapItem ) @@ -242,16 +247,16 @@ void QgsLayoutMapWidget::keepLayersVisibilityPresetSelected() mKeepLayerStylesCheckBox->setChecked( true ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Preset" ) ); mMapItem->setLayerStyleOverrides( QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverrides( presetName ) ); + mMapItem->layout()->undoStack()->endCommand(); mMapItem->invalidateCache(); } -#endif } void QgsLayoutMapWidget::onMapThemesChanged() { -#if 0 //TODO if ( QStringListModel *model = qobject_cast( mFollowVisibilityPresetCombo->model() ) ) { QStringList lst; @@ -265,7 +270,6 @@ void QgsLayoutMapWidget::onMapThemesChanged() mFollowVisibilityPresetCombo->setCurrentIndex( presetModelIndex != -1 ? presetModelIndex : 0 ); // 0 == none mFollowVisibilityPresetCombo->blockSignals( false ); } -#endif } void QgsLayoutMapWidget::updateOverviewFrameStyleFromWidget() @@ -285,6 +289,7 @@ void QgsLayoutMapWidget::updateOverviewFrameStyleFromWidget() void QgsLayoutMapWidget::cleanUpOverviewFrameStyleSelector( QgsPanelWidget *container ) { + Q_UNUSED( container ); #if 0 //TODO QgsSymbolSelectorWidget *w = qobject_cast( container ); if ( !w ) @@ -310,7 +315,6 @@ void QgsLayoutMapWidget::mapCrsChanged( const QgsCoordinateReferenceSystem &crs return; } -#if 0 //TODO if ( mMapItem->presetCrs() == crs ) return; @@ -322,7 +326,7 @@ void QgsLayoutMapWidget::mapCrsChanged( const QgsCoordinateReferenceSystem &crs try { QgsCoordinateTransform xForm( oldCrs, crs.isValid() ? crs : QgsProject::instance()->crs() ); - QgsRectangle prevExtent = *mMapItem->currentMapExtent(); + QgsRectangle prevExtent = mMapItem->extent(); newExtent = xForm.transformBoundingBox( prevExtent ); updateExtent = true; } @@ -331,13 +335,12 @@ void QgsLayoutMapWidget::mapCrsChanged( const QgsCoordinateReferenceSystem &crs //transform failed, don't update extent } - mMapItem->beginCommand( tr( "Map CRS changed" ) ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map CRS" ) ); mMapItem->setCrs( crs ); if ( updateExtent ) mMapItem->zoomToExtent( newExtent ); - mMapItem->endCommand(); + mMapItem->layout()->undoStack()->endCommand(); mMapItem->invalidateCache(); -#endif } void QgsLayoutMapWidget::mAtlasCheckBox_toggled( bool checked ) @@ -346,7 +349,7 @@ void QgsLayoutMapWidget::mAtlasCheckBox_toggled( bool checked ) { return; } -#if 0 //TODO + mAtlasFixedScaleRadio->setEnabled( checked ); mAtlasMarginRadio->setEnabled( checked ); @@ -364,8 +367,7 @@ void QgsLayoutMapWidget::mAtlasCheckBox_toggled( bool checked ) if ( checked ) { //check atlas coverage layer type - QgsComposition *composition = mMapItem->composition(); - if ( composition ) + if ( mMapItem->layout() ) { toggleAtlasScalingOptionsByLayerType(); } @@ -377,9 +379,10 @@ void QgsLayoutMapWidget::mAtlasCheckBox_toggled( bool checked ) mAtlasPredefinedScaleRadio->setEnabled( false ); } + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Set Atlas Driven" ) ); mMapItem->setAtlasDriven( checked ); + mMapItem->layout()->undoStack()->endCommand(); updateMapForAtlas(); -#endif } void QgsLayoutMapWidget::updateMapForAtlas() @@ -413,15 +416,15 @@ void QgsLayoutMapWidget::updateMapForAtlas() void QgsLayoutMapWidget::mAtlasMarginRadio_toggled( bool checked ) { -#if 0 //TODO mAtlasMarginSpinBox->setEnabled( checked ); if ( checked && mMapItem ) { - mMapItem->setAtlasScalingMode( QgsComposerMap::Auto ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Atlas Mode" ) ); + mMapItem->setAtlasScalingMode( QgsLayoutItemMap::Auto ); + mMapItem->layout()->undoStack()->endCommand(); updateMapForAtlas(); } -#endif } void QgsLayoutMapWidget::mAtlasMarginSpinBox_valueChanged( int value ) @@ -431,10 +434,10 @@ void QgsLayoutMapWidget::mAtlasMarginSpinBox_valueChanged( int value ) return; } -#if 0 //TODO + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Atlas Margin" ), QgsLayoutItem::UndoAtlasMargin ); mMapItem->setAtlasMargin( value / 100. ); + mMapItem->layout()->undoStack()->endCommand(); updateMapForAtlas(); -#endif } void QgsLayoutMapWidget::mAtlasFixedScaleRadio_toggled( bool checked ) @@ -444,13 +447,13 @@ void QgsLayoutMapWidget::mAtlasFixedScaleRadio_toggled( bool checked ) return; } -#if 0 //TODO if ( checked ) { - mMapItem->setAtlasScalingMode( QgsComposerMap::Fixed ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Atlas Mode" ) ); + mMapItem->setAtlasScalingMode( QgsLayoutItemMap::Fixed ); + mMapItem->layout()->undoStack()->endCommand(); updateMapForAtlas(); } -#endif } void QgsLayoutMapWidget::mAtlasPredefinedScaleRadio_toggled( bool checked ) @@ -460,24 +463,24 @@ void QgsLayoutMapWidget::mAtlasPredefinedScaleRadio_toggled( bool checked ) return; } -#if 0 //TODO if ( hasPredefinedScales() ) { if ( checked ) { - mMapItem->setAtlasScalingMode( QgsComposerMap::Predefined ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Atlas Scales" ) ); + mMapItem->setAtlasScalingMode( QgsLayoutItemMap::Predefined ); + mMapItem->layout()->undoStack()->endCommand(); updateMapForAtlas(); } } else { // restore to fixed scale if no predefined scales exist - mAtlasFixedScaleRadio->blockSignals( true ); - mAtlasFixedScaleRadio->setChecked( true ); - mAtlasFixedScaleRadio->blockSignals( false ); - mMapItem->setAtlasScalingMode( QgsComposerMap::Fixed ); + whileBlocking( mAtlasFixedScaleRadio )->setChecked( true ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Atlas Mode" ) ); + mMapItem->setAtlasScalingMode( QgsLayoutItemMap::Fixed ); + mMapItem->layout()->undoStack()->endCommand(); } -#endif } void QgsLayoutMapWidget::mScaleLineEdit_editingFinished() @@ -498,11 +501,9 @@ void QgsLayoutMapWidget::mScaleLineEdit_editingFinished() if ( std::round( scaleDenominator ) == std::round( mMapItem->scale() ) ) return; -#if 0 //TODO - mMapItem->beginCommand( tr( "Map scale changed" ) ); - mMapItem->setNewScale( scaleDenominator ); - mMapItem->endCommand(); -#endif + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Scale" ) ); + mMapItem->setScale( scaleDenominator ); + mMapItem->layout()->undoStack()->endCommand(); } void QgsLayoutMapWidget::rotationChanged( double value ) @@ -512,12 +513,10 @@ void QgsLayoutMapWidget::rotationChanged( double value ) return; } -#if 0 //TODO - mMapItem->beginCommand( tr( "Map rotation changed" ), QgsComposerMergeCommand::ComposerMapRotation ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Rotation" ), QgsLayoutItem::UndoMapRotation ); mMapItem->setMapRotation( value ); - mMapItem->endCommand(); + mMapItem->layout()->undoStack()->endCommand(); mMapItem->invalidateCache(); -#endif } void QgsLayoutMapWidget::mSetToMapCanvasExtentButton_clicked() @@ -527,7 +526,6 @@ void QgsLayoutMapWidget::mSetToMapCanvasExtentButton_clicked() return; } -#if 0 //TODO QgsRectangle newExtent = QgisApp::instance()->mapCanvas()->mapSettings().visibleExtent(); //transform? @@ -547,10 +545,9 @@ void QgsLayoutMapWidget::mSetToMapCanvasExtentButton_clicked() } } - mMapItem->beginCommand( tr( "Map extent changed" ) ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Extent" ) ); mMapItem->zoomToExtent( newExtent ); - mMapItem->endCommand(); -#endif + mMapItem->layout()->undoStack()->endCommand(); } void QgsLayoutMapWidget::mViewExtentInCanvasButton_clicked() @@ -560,8 +557,7 @@ void QgsLayoutMapWidget::mViewExtentInCanvasButton_clicked() return; } -#if 0 //TODO - QgsRectangle currentMapExtent = *( mMapItem->currentMapExtent() ); + QgsRectangle currentMapExtent = mMapItem->extent(); if ( !currentMapExtent.isEmpty() ) { @@ -585,7 +581,6 @@ void QgsLayoutMapWidget::mViewExtentInCanvasButton_clicked() QgisApp::instance()->mapCanvas()->setExtent( currentMapExtent ); QgisApp::instance()->mapCanvas()->refresh(); } -#endif } void QgsLayoutMapWidget::mXMinLineEdit_editingFinished() @@ -624,7 +619,6 @@ void QgsLayoutMapWidget::updateGuiElements() blockAllSignals( true ); -#if 0 //TODO whileBlocking( mCrsSelector )->setCrs( mMapItem->presetCrs() ); //width, height, scale @@ -648,13 +642,13 @@ void QgsLayoutMapWidget::updateGuiElements() } //composer map extent - QgsRectangle composerMapExtent = *( mMapItem->currentMapExtent() ); + QgsRectangle composerMapExtent = mMapItem->extent(); mXMinLineEdit->setText( QString::number( composerMapExtent.xMinimum(), 'f', 3 ) ); mXMaxLineEdit->setText( QString::number( composerMapExtent.xMaximum(), 'f', 3 ) ); mYMinLineEdit->setText( QString::number( composerMapExtent.yMinimum(), 'f', 3 ) ); mYMaxLineEdit->setText( QString::number( composerMapExtent.yMaximum(), 'f', 3 ) ); - mMapRotationSpinBox->setValue( mMapItem->mapRotation( QgsComposerObject::OriginalValue ) ); + mMapRotationSpinBox->setValue( mMapItem->mapRotation( QgsLayoutObject::OriginalValue ) ); // follow preset checkbox mFollowVisibilityPresetCheckBox->setCheckState( @@ -687,15 +681,15 @@ void QgsLayoutMapWidget::updateGuiElements() //atlas controls mAtlasCheckBox->setChecked( mMapItem->atlasDriven() ); - mAtlasMarginSpinBox->setValue( static_cast( mMapItem->atlasMargin( QgsComposerObject::OriginalValue ) * 100 ) ); + mAtlasMarginSpinBox->setValue( static_cast( mMapItem->atlasMargin( QgsLayoutObject::OriginalValue ) * 100 ) ); mAtlasFixedScaleRadio->setEnabled( mMapItem->atlasDriven() ); - mAtlasFixedScaleRadio->setChecked( mMapItem->atlasScalingMode() == QgsComposerMap::Fixed ); - mAtlasMarginSpinBox->setEnabled( mMapItem->atlasScalingMode() == QgsComposerMap::Auto ); + mAtlasFixedScaleRadio->setChecked( mMapItem->atlasScalingMode() == QgsLayoutItemMap::Fixed ); + mAtlasMarginSpinBox->setEnabled( mMapItem->atlasScalingMode() == QgsLayoutItemMap::Auto ); mAtlasMarginRadio->setEnabled( mMapItem->atlasDriven() ); - mAtlasMarginRadio->setChecked( mMapItem->atlasScalingMode() == QgsComposerMap::Auto ); + mAtlasMarginRadio->setChecked( mMapItem->atlasScalingMode() == QgsLayoutItemMap::Auto ); mAtlasPredefinedScaleRadio->setEnabled( mMapItem->atlasDriven() ); - mAtlasPredefinedScaleRadio->setChecked( mMapItem->atlasScalingMode() == QgsComposerMap::Predefined ); + mAtlasPredefinedScaleRadio->setChecked( mMapItem->atlasScalingMode() == QgsLayoutItemMap::Predefined ); if ( mMapItem->atlasDriven() ) { @@ -706,7 +700,6 @@ void QgsLayoutMapWidget::updateGuiElements() { mAtlasPredefinedScaleRadio->setEnabled( false ); } -#endif populateDataDefinedButtons(); loadGridEntries(); @@ -759,26 +752,24 @@ void QgsLayoutMapWidget::updateComposerExtentFromGui() double xmin, ymin, xmax, ymax; bool conversionSuccess; - xmin = mXMinLineEdit->text().toDouble( &conversionSuccess ); + xmin = QLocale::system().toDouble( mXMinLineEdit->text(), &conversionSuccess ); if ( !conversionSuccess ) return; - xmax = mXMaxLineEdit->text().toDouble( &conversionSuccess ); + xmax = QLocale::system().toDouble( mXMaxLineEdit->text(), &conversionSuccess ); if ( !conversionSuccess ) return; - ymin = mYMinLineEdit->text().toDouble( &conversionSuccess ); + ymin = QLocale::system().toDouble( mYMinLineEdit->text(), &conversionSuccess ); if ( !conversionSuccess ) return; - ymax = mYMaxLineEdit->text().toDouble( &conversionSuccess ); + ymax = QLocale::system().toDouble( mYMaxLineEdit->text(), &conversionSuccess ); if ( !conversionSuccess ) return; QgsRectangle newExtent( xmin, ymin, xmax, ymax ); -#if 0 //TODO - mMapItem->beginCommand( tr( "Map extent changed" ) ); - mMapItem->setNewExtent( newExtent ); - mMapItem->endCommand(); -#endif + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Extent" ) ); + mMapItem->setExtent( newExtent ); + mMapItem->layout()->undoStack()->endCommand(); } void QgsLayoutMapWidget::blockAllSignals( bool b ) @@ -861,18 +852,7 @@ void QgsLayoutMapWidget::mUpdatePreviewButton_clicked() { return; } - -#if 0 //TODO - if ( mMapItem->isDrawing() ) - { - return; - } - - mUpdatePreviewButton->setEnabled( false ); //prevent crashes because of many button clicks - mMapItem->invalidateCache(); -#endif - mUpdatePreviewButton->setEnabled( true ); } void QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged( int state ) @@ -881,7 +861,8 @@ void QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged( int state { return; } -#if 0 //TODO + + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Preset" ) ); if ( state == Qt::Checked ) { mMapItem->setFollowVisibilityPreset( true ); @@ -896,7 +877,7 @@ void QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged( int state { mMapItem->setFollowVisibilityPreset( false ); } -#endif + mMapItem->layout()->undoStack()->endCommand(); } void QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged( int state ) @@ -906,14 +887,15 @@ void QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged( int state ) return; } -#if 0 //TODO // update map + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Map Preset Changed" ) ); storeCurrentLayerSet(); mMapItem->setKeepLayerSet( state == Qt::Checked ); if ( state == Qt::Unchecked ) { mMapItem->setLayers( QList< QgsMapLayer * >() ); } + mMapItem->layout()->undoStack()->endCommand(); // update gui if ( state == Qt::Checked ) @@ -927,7 +909,6 @@ void QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged( int state ) mMapItem->invalidateCache(); } -#endif mKeepLayerStylesCheckBox->setEnabled( state == Qt::Checked ); } @@ -938,7 +919,7 @@ void QgsLayoutMapWidget::mKeepLayerStylesCheckBox_stateChanged( int state ) return; } -#if 0 //TODO + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Change Map Preset" ) ); if ( state == Qt::Checked ) { mMapItem->storeCurrentLayerStyles(); @@ -949,7 +930,7 @@ void QgsLayoutMapWidget::mKeepLayerStylesCheckBox_stateChanged( int state ) mMapItem->setLayerStyleOverrides( QMap() ); mMapItem->setKeepLayerStyles( false ); } -#endif + mMapItem->layout()->undoStack()->endCommand(); } void QgsLayoutMapWidget::mDrawCanvasItemsCheckBox_stateChanged( int state ) @@ -959,21 +940,10 @@ void QgsLayoutMapWidget::mDrawCanvasItemsCheckBox_stateChanged( int state ) return; } -#if 0 //TODO - mMapItem->beginCommand( tr( "Canvas items toggled" ) ); + mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr( "Toggle Map Item" ) ); mMapItem->setDrawAnnotations( state == Qt::Checked ); - mUpdatePreviewButton->setEnabled( false ); //prevent crashes because of many button clicks mMapItem->invalidateCache(); - mUpdatePreviewButton->setEnabled( true ); - mMapItem->endCommand(); -#endif -} - -void QgsLayoutMapWidget::addPageToToolbox( QWidget *widget, const QString &name ) -{ - Q_UNUSED( name ); - //TODO : wrap the widget in a collapsibleGroupBox to be more consistent with previous implementation - mainLayout->addWidget( widget ); + mMapItem->layout()->undoStack()->endCommand(); } void QgsLayoutMapWidget::insertAnnotationPositionEntries( QComboBox *c ) @@ -1587,7 +1557,6 @@ void QgsLayoutMapWidget::storeCurrentLayerSet() if ( !mMapItem ) return; -#if 0 //TODO QList layers = QgisApp::instance()->mapCanvas()->mapSettings().layers(); mMapItem->setLayers( layers ); @@ -1596,7 +1565,6 @@ void QgsLayoutMapWidget::storeCurrentLayerSet() // also store styles associated with the layers mMapItem->storeCurrentLayerStyles(); } -#endif } QListWidgetItem *QgsLayoutMapWidget::addOverviewListItem( const QString &id, const QString &name ) diff --git a/src/app/layout/qgslayoutmapwidget.h b/src/app/layout/qgslayoutmapwidget.h index fc4a550a7641..61cf1eec499f 100644 --- a/src/app/layout/qgslayoutmapwidget.h +++ b/src/app/layout/qgslayoutmapwidget.h @@ -91,8 +91,6 @@ class QgsLayoutMapWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutM protected: bool setNewItem( QgsLayoutItem *item ) override; - void addPageToToolbox( QWidget *widget, const QString &name ); - //! Sets the current composer map values to the GUI elements virtual void updateGuiElements(); diff --git a/src/core/layout/qgslayoutitem.h b/src/core/layout/qgslayoutitem.h index fdae744e8c91..138ba0a17b37 100644 --- a/src/core/layout/qgslayoutitem.h +++ b/src/core/layout/qgslayoutitem.h @@ -96,6 +96,8 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt UndoShapeStyle, //!< Shape symbol style UndoShapeCornerRadius, //!< Shape corner radius UndoNodeMove, //!< Node move + UndoAtlasMargin, //!< Map atlas margin changed + UndoMapRotation, //!< Map rotation changed }; /** diff --git a/src/core/layout/qgslayoutitemmap.cpp b/src/core/layout/qgslayoutitemmap.cpp index 9157dae93725..574bafd5d167 100644 --- a/src/core/layout/qgslayoutitemmap.cpp +++ b/src/core/layout/qgslayoutitemmap.cpp @@ -858,6 +858,9 @@ QgsRectangle QgsLayoutItemMap::requestedExtent() const void QgsLayoutItemMap::invalidateCache() { + if ( mDrawing ) + return; + mCacheInvalidated = true; update(); } diff --git a/src/gui/layout/qgslayoutitemguiregistry.cpp b/src/gui/layout/qgslayoutitemguiregistry.cpp index 238f3209e7b4..8ae9c3aba950 100644 --- a/src/gui/layout/qgslayoutitemguiregistry.cpp +++ b/src/gui/layout/qgslayoutitemguiregistry.cpp @@ -35,6 +35,11 @@ QgsLayoutItem *QgsLayoutItemAbstractGuiMetadata::createItem( QgsLayout * ) return nullptr; } +void QgsLayoutItemAbstractGuiMetadata::newItemAddedToLayout( QgsLayoutItem * ) +{ + +} + QgsLayoutItemGuiRegistry::QgsLayoutItemGuiRegistry( QObject *parent ) : QObject( parent ) { @@ -88,6 +93,14 @@ QgsLayoutItem *QgsLayoutItemGuiRegistry::createItem( int metadataId, QgsLayout * return QgsApplication::layoutItemRegistry()->createItem( type, layout ); } +void QgsLayoutItemGuiRegistry::newItemAddedToLayout( int metadataId, QgsLayoutItem *item ) +{ + if ( !mMetadata.contains( metadataId ) ) + return; + + mMetadata.value( metadataId )->newItemAddedToLayout( item ); +} + QgsLayoutItemBaseWidget *QgsLayoutItemGuiRegistry::createItemWidget( QgsLayoutItem *item ) const { if ( !item ) @@ -127,3 +140,9 @@ QgsLayoutItem *QgsLayoutItemGuiMetadata::createItem( QgsLayout *layout ) { return mCreateFunc ? mCreateFunc( layout ) : QgsLayoutItemAbstractGuiMetadata::createItem( layout ); } + +void QgsLayoutItemGuiMetadata::newItemAddedToLayout( QgsLayoutItem *item ) +{ + if ( mAddedToLayoutFunc ) + mAddedToLayoutFunc( item ); +} diff --git a/src/gui/layout/qgslayoutitemguiregistry.h b/src/gui/layout/qgslayoutitemguiregistry.h index 24e3d73b218b..c5f5c7e8462f 100644 --- a/src/gui/layout/qgslayoutitemguiregistry.h +++ b/src/gui/layout/qgslayoutitemguiregistry.h @@ -127,6 +127,14 @@ class GUI_EXPORT QgsLayoutItemAbstractGuiMetadata */ virtual QgsLayoutItem *createItem( QgsLayout *layout ) SIP_FACTORY; + /** + * Called when a newly created item of the associated type has been added to a layout. + * + * This is only called for additions which result from GUI operations - i.e. it is not + * called for items added from templates. + */ + virtual void newItemAddedToLayout( QgsLayoutItem *item ); + private: int mType = -1; @@ -146,6 +154,9 @@ typedef std::function QgsLayoutIte //! Layout node based rubber band creation function typedef std::function QgsLayoutNodeItemRubberBandFunc SIP_SKIP; +//! Layout item added to layout callback +typedef std::function QgsLayoutItemAddedToLayoutFunc SIP_SKIP; + #ifndef SIP_RUN /** @@ -230,11 +241,24 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad */ void setItemCreationFunction( QgsLayoutItemCreateFunc function ) { mCreateFunc = function; } + /** + * Returns the classes' item added to layout function. + * \see setItemAddedToLayoutFunction() + */ + QgsLayoutItemAddedToLayoutFunc itemAddToLayoutFunction() const { return mAddedToLayoutFunc; } + + /** + * Sets the classes' item creation \a function. + * \see itemAddToLayoutFunction() + */ + void setItemAddedToLayoutFunction( QgsLayoutItemAddedToLayoutFunc function ) { mAddedToLayoutFunc = function; } + QIcon creationIcon() const override { return mIcon.isNull() ? QgsLayoutItemAbstractGuiMetadata::creationIcon() : mIcon; } QgsLayoutItemBaseWidget *createItemWidget( QgsLayoutItem *item ) override { return mWidgetFunc ? mWidgetFunc( item ) : nullptr; } QgsLayoutViewRubberBand *createRubberBand( QgsLayoutView *view ) override { return mRubberBandFunc ? mRubberBandFunc( view ) : nullptr; } QAbstractGraphicsShapeItem *createNodeRubberBand( QgsLayoutView *view ) override { return mNodeRubberBandFunc ? mNodeRubberBandFunc( view ) : nullptr; } QgsLayoutItem *createItem( QgsLayout *layout ) override; + void newItemAddedToLayout( QgsLayoutItem *item ) override; protected: QIcon mIcon; @@ -242,6 +266,7 @@ class GUI_EXPORT QgsLayoutItemGuiMetadata : public QgsLayoutItemAbstractGuiMetad QgsLayoutItemRubberBandFunc mRubberBandFunc = nullptr; QgsLayoutNodeItemRubberBandFunc mNodeRubberBandFunc = nullptr; QgsLayoutItemCreateFunc mCreateFunc = nullptr; + QgsLayoutItemAddedToLayoutFunc mAddedToLayoutFunc = nullptr; }; @@ -359,6 +384,14 @@ class GUI_EXPORT QgsLayoutItemGuiRegistry : public QObject */ QgsLayoutItem *createItem( int metadataId, QgsLayout *layout ) const SIP_FACTORY; + /** + * Called when a newly created item of the associated metadata \a metadataId has been added to a layout. + * + * This is only called for additions which result from GUI operations - i.e. it is not + * called for items added from templates. + */ + void newItemAddedToLayout( int metadataId, QgsLayoutItem *item ); + /** * Creates a new instance of a layout item configuration widget for the specified \a item. */ diff --git a/src/gui/layout/qgslayoutviewtooladditem.cpp b/src/gui/layout/qgslayoutviewtooladditem.cpp index d45167bed559..5306f563f129 100644 --- a/src/gui/layout/qgslayoutviewtooladditem.cpp +++ b/src/gui/layout/qgslayoutviewtooladditem.cpp @@ -120,6 +120,9 @@ void QgsLayoutViewToolAddItem::layoutReleaseEvent( QgsLayoutViewMouseEvent *even settings.setValue( QStringLiteral( "LayoutDesigner/lastSizeUnit" ), static_cast< int >( item->sizeWithUnits().units() ) ); layout()->addLayoutItem( item ); + + QgsGui::layoutItemGuiRegistry()->newItemAddedToLayout( mItemMetadataId, item ); + layout()->setSelectedItem( item ); emit createdItem(); }