40#include <QStringListModel>
45 , mMapCanvas( mapCanvas )
50 connect( mScaleLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mScaleLineEdit_editingFinished );
51 connect( mActionSetToCanvasExtent, &QAction::triggered,
this, &QgsLayoutMapWidget::setToMapCanvasExtent );
52 connect( mActionViewExtentInCanvas, &QAction::triggered,
this, &QgsLayoutMapWidget::viewExtentInCanvas );
53 connect( mActionSetToCanvasScale, &QAction::triggered,
this, &QgsLayoutMapWidget::setToMapCanvasScale );
54 connect( mActionViewScaleInCanvas, &QAction::triggered,
this, &QgsLayoutMapWidget::viewScaleInCanvas );
55 connect( mActionUpdatePreview, &QAction::triggered,
this, &QgsLayoutMapWidget::updatePreview );
56 connect( mFollowVisibilityPresetCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged );
57 connect( mKeepLayerListCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged );
58 connect( mKeepLayerStylesCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mKeepLayerStylesCheckBox_stateChanged );
59 connect( mDrawCanvasItemsCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mDrawCanvasItemsCheckBox_stateChanged );
60 connect( mOverviewBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutMapWidget::mOverviewBlendModeComboBox_currentIndexChanged );
61 connect( mOverviewInvertCheckbox, &QCheckBox::toggled,
this, &QgsLayoutMapWidget::mOverviewInvertCheckbox_toggled );
62 connect( mOverviewCenterCheckbox, &QCheckBox::toggled,
this, &QgsLayoutMapWidget::mOverviewCenterCheckbox_toggled );
63 connect( mOverviewPositionComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutMapWidget::overviewStackingChanged );
65 connect( mXMinLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mXMinLineEdit_editingFinished );
66 connect( mXMaxLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mXMaxLineEdit_editingFinished );
67 connect( mYMinLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mYMinLineEdit_editingFinished );
68 connect( mYMaxLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mYMaxLineEdit_editingFinished );
69 connect( mAtlasMarginRadio, &QRadioButton::toggled,
this, &QgsLayoutMapWidget::mAtlasMarginRadio_toggled );
70 connect( mAtlasCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mAtlasCheckBox_toggled );
71 connect( mAtlasMarginSpinBox,
static_cast < void ( QSpinBox::* )(
int )
> ( &QSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::mAtlasMarginSpinBox_valueChanged );
72 connect( mAtlasFixedScaleRadio, &QRadioButton::toggled,
this, &QgsLayoutMapWidget::mAtlasFixedScaleRadio_toggled );
73 connect( mAtlasPredefinedScaleRadio, &QRadioButton::toggled,
this, &QgsLayoutMapWidget::mAtlasPredefinedScaleRadio_toggled );
74 connect( mAddGridPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mAddGridPushButton_clicked );
75 connect( mRemoveGridPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mRemoveGridPushButton_clicked );
76 connect( mGridUpButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mGridUpButton_clicked );
77 connect( mGridDownButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mGridDownButton_clicked );
78 connect( mGridListWidget, &QListWidget::currentItemChanged,
this, &QgsLayoutMapWidget::mGridListWidget_currentItemChanged );
79 connect( mGridListWidget, &QListWidget::itemChanged,
this, &QgsLayoutMapWidget::mGridListWidget_itemChanged );
80 connect( mGridPropertiesButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mGridPropertiesButton_clicked );
81 connect( mAddOverviewPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mAddOverviewPushButton_clicked );
82 connect( mRemoveOverviewPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mRemoveOverviewPushButton_clicked );
83 connect( mOverviewUpButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mOverviewUpButton_clicked );
84 connect( mOverviewDownButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mOverviewDownButton_clicked );
85 connect( mOverviewCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mOverviewCheckBox_toggled );
86 connect( mOverviewListWidget, &QListWidget::currentItemChanged,
this, &QgsLayoutMapWidget::mOverviewListWidget_currentItemChanged );
87 connect( mOverviewListWidget, &QListWidget::itemChanged,
this, &QgsLayoutMapWidget::mOverviewListWidget_itemChanged );
88 connect( mActionLabelSettings, &QAction::triggered,
this, &QgsLayoutMapWidget::showLabelSettings );
89 connect( mActionClipSettings, &QAction::triggered,
this, &QgsLayoutMapWidget::showClipSettings );
91 connect( mTemporalCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mTemporalCheckBox_toggled );
92 connect( mStartDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsLayoutMapWidget::updateTemporalExtent );
93 connect( mEndDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsLayoutMapWidget::updateTemporalExtent );
95 mZLowerSpin->setClearValueMode( QgsDoubleSpinBox::ClearValueMode::MinimumValue, tr(
"Not set" ) );
96 mZUpperSpin->setClearValueMode( QgsDoubleSpinBox::ClearValueMode::MinimumValue, tr(
"Not set" ) );
97 connect( mElevationRangeCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mElevationRangeCheckBox_toggled );
98 connect( mZLowerSpin, qOverload< double >( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::updateZRange );
99 connect( mZUpperSpin, qOverload< double >( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::updateZRange );
101 mStartDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
102 mEndDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
103 mStartDateTime->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
104 mEndDateTime->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
106 connect( mActionMoveContent, &QAction::triggered,
this, &QgsLayoutMapWidget::switchToMoveContentTool );
108 mMapRotationSpinBox->setClearValue( 0 );
112 mBookmarkMenu =
new QMenu(
this );
113 QToolButton *btnBookmarks =
new QToolButton(
this );
114 btnBookmarks->setAutoRaise(
true );
115 btnBookmarks->setToolTip( tr(
"Bookmarks" ) );
117 btnBookmarks->setPopupMode( QToolButton::InstantPopup );
118 btnBookmarks->setMenu( mBookmarkMenu );
120 mDockToolbar->insertWidget( mActionMoveContent, btnBookmarks );
121 connect( mBookmarkMenu, &QMenu::aboutToShow,
this, &QgsLayoutMapWidget::aboutToShowBookmarkMenu );
125 mainLayout->addWidget( mItemPropertiesWidget );
127 mScaleLineEdit->setValidator(
new QDoubleValidator( mScaleLineEdit ) );
129 mXMinLineEdit->setValidator(
new QDoubleValidator( mXMinLineEdit ) );
130 mXMaxLineEdit->setValidator(
new QDoubleValidator( mXMaxLineEdit ) );
131 mYMinLineEdit->setValidator(
new QDoubleValidator( mYMinLineEdit ) );
132 mYMaxLineEdit->setValidator(
new QDoubleValidator( mYMaxLineEdit ) );
140 blockAllSignals(
true );
143 mCrsSelector->setNotSetText( tr(
"Use Project CRS" ) );
144 mCrsSelector->setDialogTitle( tr(
"Map Item CRS" ) );
149 mFollowVisibilityPresetCombo->setModel(
new QStringListModel( mFollowVisibilityPresetCombo ) );
150 connect( mFollowVisibilityPresetCombo,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutMapWidget::followVisibilityPresetSelected );
152 this, &QgsLayoutMapWidget::onMapThemesChanged );
153 onMapThemesChanged();
156 QMenu *menuKeepLayers =
new QMenu(
this );
157 mLayerListFromPresetButton->setMenu( menuKeepLayers );
159 mLayerListFromPresetButton->setToolTip( tr(
"Set layer list from a map theme" ) );
160 connect( menuKeepLayers, &QMenu::aboutToShow,
this, &QgsLayoutMapWidget::aboutToShowKeepLayersVisibilityPresetsMenu );
165 this, &QgsLayoutMapWidget::atlasLayerChanged );
169 compositionAtlasToggled( atlas->enabled() );
172 mOverviewFrameMapComboBox->setCurrentLayout( item->
layout() );
174 mOverviewFrameStyleButton->registerExpressionContextGenerator( item );
180 mOverviewFrameStyleButton->registerExpressionContextGenerator( item );
205 loadOverviewEntries();
207 connect( mMapRotationSpinBox,
static_cast < void (
QgsDoubleSpinBox::* )(
double )
> ( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::rotationChanged );
211 blockAllSignals(
false );
216 if ( mItemPropertiesWidget )
222 mReportTypeString = string;
223 mAtlasCheckBox->setTitle( tr(
"Controlled by %1" ).arg(
string == tr(
"atlas" ) ? tr(
"Atlas" ) : tr(
"Report" ) ) );
224 mAtlasPredefinedScaleRadio->setToolTip( tr(
"Use one of the predefined scales of the project where the %1 feature best fits." ).arg(
string ) );
227 mClipWidget->setReportTypeString(
string );
229 mLabelWidget->setReportTypeString(
string );
250 mMapItem = qobject_cast< QgsLayoutItemMap * >( item );
251 mItemPropertiesWidget->
setItem( mMapItem );
253 mLabelWidget->setItem( mMapItem );
255 mClipWidget->setItem( mMapItem );
262 mOverviewFrameStyleButton->registerExpressionContextGenerator( mMapItem );
286void QgsLayoutMapWidget::compositionAtlasToggled(
bool atlasEnabled )
289 mMapItem && mMapItem->layout() && mMapItem->layout()->reportContext().layer()
292 mAtlasCheckBox->setEnabled(
true );
296 mAtlasCheckBox->setEnabled(
false );
297 mAtlasCheckBox->setChecked(
false );
301void QgsLayoutMapWidget::aboutToShowKeepLayersVisibilityPresetsMenu()
306 QMenu *menu = qobject_cast<QMenu *>( sender() );
312 for (
const QString &presetName : constMapThemes )
314 menu->addAction( presetName,
this, &QgsLayoutMapWidget::keepLayersVisibilityPresetSelected );
317 if ( menu->actions().isEmpty() )
318 menu->addAction( tr(
"No presets defined" ) )->setEnabled(
false );
321void QgsLayoutMapWidget::followVisibilityPresetSelected(
int currentIndex )
326 if ( mBlockThemeComboChanges != 0 )
329 if ( currentIndex == -1 )
333 if ( currentIndex != 0 )
335 presetName = mFollowVisibilityPresetCombo->currentText();
338 if ( presetName == mMapItem->followVisibilityPresetName() )
341 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
342 mFollowVisibilityPresetCheckBox->setChecked(
true );
343 mMapItem->setFollowVisibilityPresetName( presetName );
344 mMapItem->layout()->undoStack()->endCommand();
346 mMapItem->invalidateCache();
349void QgsLayoutMapWidget::keepLayersVisibilityPresetSelected()
351 QAction *action = qobject_cast<QAction *>( sender() );
355 const QString presetName = action->text();
356 const QList<QgsMapLayer *> lst = orderedPresetVisibleLayers( presetName );
359 mKeepLayerListCheckBox->setChecked(
true );
360 mMapItem->setLayers( lst );
362 mKeepLayerStylesCheckBox->setChecked(
true );
364 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
365 mMapItem->setLayerStyleOverrides(
QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverrides( presetName ) );
366 mMapItem->layout()->undoStack()->endCommand();
368 mMapItem->invalidateCache();
372void QgsLayoutMapWidget::onMapThemesChanged()
374 if ( QStringListModel *model = qobject_cast<QStringListModel *>( mFollowVisibilityPresetCombo->model() ) )
376 mBlockThemeComboChanges++;
378 lst.append( tr(
"(none)" ) );
380 model->setStringList( lst );
383 const int presetModelIndex = mFollowVisibilityPresetCombo->findText( mMapItem->followVisibilityPresetName() );
384 mFollowVisibilityPresetCombo->blockSignals(
true );
385 mFollowVisibilityPresetCombo->setCurrentIndex( presetModelIndex != -1 ? presetModelIndex : 0 );
386 mFollowVisibilityPresetCombo->blockSignals(
false );
387 mBlockThemeComboChanges--;
398 if ( mMapItem->presetCrs() ==
crs )
404 bool updateExtent =
false;
409 xForm.setBallparkTransformsAreAppropriate(
true );
411 newExtent = xForm.transformBoundingBox( prevExtent );
419 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map CRS" ) );
420 mMapItem->setCrs(
crs );
422 mMapItem->zoomToExtent( newExtent );
423 mMapItem->layout()->undoStack()->endCommand();
424 mMapItem->invalidateCache();
427void QgsLayoutMapWidget::overviewSymbolChanged()
435 mMapItem->endCommand();
436 mMapItem->invalidateCache();
439void QgsLayoutMapWidget::showLabelSettings()
443 if ( !mReportTypeString.isEmpty() )
444 mLabelWidget->setReportTypeString( mReportTypeString );
449void QgsLayoutMapWidget::showClipSettings()
452 if ( !mReportTypeString.isEmpty() )
453 mClipWidget->setReportTypeString( mReportTypeString );
457void QgsLayoutMapWidget::switchToMoveContentTool()
463void QgsLayoutMapWidget::aboutToShowBookmarkMenu()
465 mBookmarkMenu->clear();
469 if ( !mBookmarkModel )
472 QMap< QString, QMenu * > groupMenus;
473 for (
int i = 0; i < mBookmarkModel->rowCount(); ++i )
476 QMenu *destMenu = mBookmarkMenu;
477 if ( !group.isEmpty() )
479 destMenu = groupMenus.value( group );
482 destMenu =
new QMenu( group, mBookmarkMenu );
483 groupMenus[ group ] = destMenu;
488 connect( action, &QAction::triggered,
this, [ = ]
498 if ( extent.
crs() != mMapItem->crs() )
502 QgsCoordinateTransform xForm( extent.crs(), mMapItem->crs(), QgsProject::instance() );
503 xForm.setBallparkTransformsAreAppropriate( true );
504 newExtent = xForm.transformBoundingBox( newExtent );
513 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Extent" ) );
514 mMapItem->zoomToExtent( newExtent );
515 mMapItem->layout()->undoStack()->endCommand();
517 destMenu->addAction( action );
520 QStringList groupKeys = groupMenus.keys();
521 groupKeys.sort( Qt::CaseInsensitive );
522 for (
int i = 0; i < groupKeys.count(); ++i )
524 if ( mBookmarkMenu->actions().value( i ) )
525 mBookmarkMenu->insertMenu( mBookmarkMenu->actions().at( i ), groupMenus.value( groupKeys.at( i ) ) );
527 mBookmarkMenu->addMenu( groupMenus.value( groupKeys.at( i ) ) );
531void QgsLayoutMapWidget::mTemporalCheckBox_toggled(
bool checked )
538 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Toggle Temporal Range" ) );
539 mMapItem->setIsTemporal( checked );
540 mMapItem->layout()->undoStack()->endCommand();
544 whileBlocking( mStartDateTime )->setDateTime( mMapItem->temporalRange().begin() );
545 whileBlocking( mEndDateTime )->setDateTime( mMapItem->temporalRange().end() );
551void QgsLayoutMapWidget::updateTemporalExtent()
558 const QDateTime begin = mStartDateTime->dateTime();
559 const QDateTime end = mEndDateTime->dateTime();
562 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Set Temporal Range" ) );
563 mMapItem->setTemporalRange( range );
564 mMapItem->layout()->undoStack()->endCommand();
569void QgsLayoutMapWidget::mElevationRangeCheckBox_toggled(
bool checked )
576 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Toggle Z Range" ) );
577 mMapItem->setZRangeEnabled( checked );
578 mMapItem->layout()->undoStack()->endCommand();
583void QgsLayoutMapWidget::updateZRange()
590 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Set Z Range" ) );
591 double zLower = mZLowerSpin->value();
592 if ( zLower == mZLowerSpin->clearValue() )
593 zLower = std::numeric_limits< double >::lowest();
594 double zUpper = mZUpperSpin->value();
595 if ( zUpper == mZUpperSpin->clearValue() )
596 zUpper = std::numeric_limits< double >::max();
599 mMapItem->layout()->undoStack()->endCommand();
604void QgsLayoutMapWidget::mAtlasCheckBox_toggled(
bool checked )
611 mAtlasFixedScaleRadio->setEnabled( checked );
612 mAtlasMarginRadio->setEnabled( checked );
614 if ( mAtlasMarginRadio->isEnabled() && mAtlasMarginRadio->isChecked() )
616 mAtlasMarginSpinBox->setEnabled(
true );
620 mAtlasMarginSpinBox->setEnabled(
false );
623 mAtlasPredefinedScaleRadio->setEnabled( checked );
628 if ( mMapItem->layout() )
630 toggleAtlasScalingOptionsByLayerType();
635 if ( !hasPredefinedScales() )
637 mAtlasPredefinedScaleRadio->setEnabled(
false );
640 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Set Atlas Driven" ) );
641 mMapItem->setAtlasDriven( checked );
642 mMapItem->layout()->undoStack()->endCommand();
646void QgsLayoutMapWidget::updateMapForAtlas()
649 if ( mMapItem->atlasDriven() )
656 mMapItem->invalidateCache();
660void QgsLayoutMapWidget::mAtlasMarginRadio_toggled(
bool checked )
662 mAtlasMarginSpinBox->setEnabled( checked );
664 if ( checked && mMapItem )
666 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Mode" ) );
668 mMapItem->layout()->undoStack()->endCommand();
673void QgsLayoutMapWidget::mAtlasMarginSpinBox_valueChanged(
int value )
681 mMapItem->setAtlasMargin( value / 100. );
682 mMapItem->layout()->undoStack()->endCommand();
686void QgsLayoutMapWidget::mAtlasFixedScaleRadio_toggled(
bool checked )
695 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Mode" ) );
697 mMapItem->layout()->undoStack()->endCommand();
702void QgsLayoutMapWidget::mAtlasPredefinedScaleRadio_toggled(
bool checked )
709 if ( hasPredefinedScales() )
713 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Scales" ) );
715 mMapItem->layout()->undoStack()->endCommand();
723 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Mode" ) );
725 mMapItem->layout()->undoStack()->endCommand();
729void QgsLayoutMapWidget::mScaleLineEdit_editingFinished()
736 bool conversionSuccess =
false;
737 const double scaleDenominator = QLocale().toDouble( mScaleLineEdit->text(), &conversionSuccess );
738 if ( !conversionSuccess )
746 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Scale" ) );
747 mMapItem->setScale( scaleDenominator );
748 mMapItem->layout()->undoStack()->endCommand();
751void QgsLayoutMapWidget::rotationChanged(
double value )
759 mMapItem->setMapRotation( value );
760 mMapItem->layout()->undoStack()->endCommand();
761 mMapItem->invalidateCache();
764void QgsLayoutMapWidget::setToMapCanvasExtent()
781 xForm.setBallparkTransformsAreAppropriate(
true );
782 newExtent = xForm.transformBoundingBox( newExtent );
791 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Extent" ) );
792 mMapItem->zoomToExtent( newExtent );
793 mMapItem->layout()->undoStack()->endCommand();
796void QgsLayoutMapWidget::setToMapCanvasScale()
803 const double newScale = mMapCanvas->
scale();
805 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Scale" ) );
806 mMapItem->setScale( newScale );
807 mMapItem->layout()->undoStack()->endCommand();
810void QgsLayoutMapWidget::viewExtentInCanvas()
817 const QgsRectangle currentMapExtent = mMapItem->extent();
819 if ( !currentMapExtent.
isEmpty() )
834void QgsLayoutMapWidget::viewScaleInCanvas()
841 const double currentScale = mMapItem->scale();
842 mMapCanvas->
zoomScale( currentScale,
true );
845void QgsLayoutMapWidget::mXMinLineEdit_editingFinished()
847 updateComposerExtentFromGui();
850void QgsLayoutMapWidget::mXMaxLineEdit_editingFinished()
852 updateComposerExtentFromGui();
855void QgsLayoutMapWidget::mYMinLineEdit_editingFinished()
857 updateComposerExtentFromGui();
860void QgsLayoutMapWidget::mYMaxLineEdit_editingFinished()
862 updateComposerExtentFromGui();
865void QgsLayoutMapWidget::updateGuiElements()
872 blockAllSignals(
true );
873 mLabel->setText( mMapItem->displayName() );
875 whileBlocking( mCrsSelector )->setCrs( mMapItem->presetCrs() );
878 const double scale = mMapItem->scale();
881 if ( scale >= 10000 )
884 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 0 ) );
886 else if ( scale >= 10 )
888 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 3 ) );
890 else if ( scale >= 1 )
893 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 4 ) );
898 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 10 ) );
902 const QgsRectangle composerMapExtent = mMapItem->extent();
903 mXMinLineEdit->setText( QLocale().toString( composerMapExtent.
xMinimum(),
'f', 3 ) );
904 mXMaxLineEdit->setText( QLocale().toString( composerMapExtent.
xMaximum(),
'f', 3 ) );
905 mYMinLineEdit->setText( QLocale().toString( composerMapExtent.
yMinimum(),
'f', 3 ) );
906 mYMaxLineEdit->setText( QLocale().toString( composerMapExtent.
yMaximum(),
'f', 3 ) );
911 mFollowVisibilityPresetCheckBox->setCheckState(
912 mMapItem->followVisibilityPreset() ? Qt::Checked : Qt::Unchecked );
913 const int presetModelIndex = mFollowVisibilityPresetCombo->findText( mMapItem->followVisibilityPresetName() );
914 mFollowVisibilityPresetCombo->setCurrentIndex( presetModelIndex != -1 ? presetModelIndex : 0 );
917 if ( mMapItem->keepLayerSet() )
919 mKeepLayerListCheckBox->setCheckState( Qt::Checked );
923 mKeepLayerListCheckBox->setCheckState( Qt::Unchecked );
926 mKeepLayerStylesCheckBox->setEnabled( mMapItem->keepLayerSet() );
927 mKeepLayerStylesCheckBox->setCheckState( mMapItem->keepLayerStyles() ? Qt::Checked : Qt::Unchecked );
930 if ( mMapItem->drawAnnotations() )
932 mDrawCanvasItemsCheckBox->setCheckState( Qt::Checked );
936 mDrawCanvasItemsCheckBox->setCheckState( Qt::Unchecked );
940 mAtlasCheckBox->setChecked( mMapItem->atlasDriven() );
943 mAtlasFixedScaleRadio->setEnabled( mMapItem->atlasDriven() );
946 mAtlasMarginRadio->setEnabled( mMapItem->atlasDriven() );
948 mAtlasPredefinedScaleRadio->setEnabled( mMapItem->atlasDriven() );
951 if ( mMapItem->atlasDriven() )
953 toggleAtlasScalingOptionsByLayerType();
956 if ( !hasPredefinedScales() )
958 mAtlasPredefinedScaleRadio->setEnabled(
false );
961 mTemporalCheckBox->setChecked( mMapItem->isTemporal() );
962 mTemporalCheckBox->setCollapsed( !mMapItem->isTemporal() );
963 mStartDateTime->setEnabled( mMapItem->isTemporal() );
964 mEndDateTime->setEnabled( mMapItem->isTemporal() );
965 if ( mMapItem->isTemporal() )
967 mStartDateTime->setDateTime( mMapItem->temporalRange().begin() );
968 mEndDateTime->setDateTime( mMapItem->temporalRange().end() );
971 whileBlocking( mElevationRangeCheckBox )->setChecked( mMapItem->zRangeEnabled() );
972 mElevationRangeCheckBox->setCollapsed( !mMapItem->zRangeEnabled() );
973 if ( mMapItem->zRange().lower() != std::numeric_limits< double >::lowest() )
974 whileBlocking( mZLowerSpin )->setValue( mMapItem->zRange().lower() );
977 if ( mMapItem->zRange().upper() != std::numeric_limits< double >::max() )
978 whileBlocking( mZUpperSpin )->setValue( mMapItem->zRange().upper() );
984 loadOverviewEntries();
986 blockAllSignals(
false );
989void QgsLayoutMapWidget::toggleAtlasScalingOptionsByLayerType()
1007 mAtlasFixedScaleRadio->setChecked(
true );
1008 mAtlasMarginRadio->setEnabled(
false );
1013 mAtlasMarginRadio->setEnabled(
true );
1017void QgsLayoutMapWidget::updateComposerExtentFromGui()
1024 double xmin, ymin, xmax, ymax;
1025 bool conversionSuccess;
1027 xmin = QLocale().toDouble( mXMinLineEdit->text(), &conversionSuccess );
1028 if ( !conversionSuccess )
1030 xmax = QLocale().toDouble( mXMaxLineEdit->text(), &conversionSuccess );
1031 if ( !conversionSuccess )
1033 ymin = QLocale().toDouble( mYMinLineEdit->text(), &conversionSuccess );
1034 if ( !conversionSuccess )
1036 ymax = QLocale().toDouble( mYMaxLineEdit->text(), &conversionSuccess );
1037 if ( !conversionSuccess )
1040 const QgsRectangle newExtent( xmin, ymin, xmax, ymax );
1042 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Extent" ) );
1043 mMapItem->setExtent( newExtent );
1044 mMapItem->layout()->undoStack()->endCommand();
1047void QgsLayoutMapWidget::blockAllSignals(
bool b )
1049 mScaleLineEdit->blockSignals( b );
1050 mXMinLineEdit->blockSignals( b );
1051 mXMaxLineEdit->blockSignals( b );
1052 mYMinLineEdit->blockSignals( b );
1053 mYMaxLineEdit->blockSignals( b );
1054 mDrawCanvasItemsCheckBox->blockSignals( b );
1055 mOverviewFrameMapComboBox->blockSignals( b );
1056 mOverviewFrameStyleButton->blockSignals( b );
1057 mOverviewBlendModeComboBox->blockSignals( b );
1058 mOverviewInvertCheckbox->blockSignals( b );
1059 mOverviewCenterCheckbox->blockSignals( b );
1060 mAtlasCheckBox->blockSignals( b );
1061 mAtlasMarginSpinBox->blockSignals( b );
1062 mAtlasFixedScaleRadio->blockSignals( b );
1063 mAtlasMarginRadio->blockSignals( b );
1064 mFollowVisibilityPresetCheckBox->blockSignals( b );
1065 mFollowVisibilityPresetCombo->blockSignals( b );
1066 mKeepLayerListCheckBox->blockSignals( b );
1067 mKeepLayerStylesCheckBox->blockSignals( b );
1068 mActionSetToCanvasExtent->blockSignals( b );
1069 mActionUpdatePreview->blockSignals( b );
1070 mTemporalCheckBox->blockSignals( b );
1071 mStartDateTime->blockSignals( b );
1072 mEndDateTime->blockSignals( b );
1074 blockOverviewItemsSignals( b );
1077void QgsLayoutMapWidget::updatePreview()
1083 mMapItem->refresh();
1086void QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged(
int state )
1093 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
1094 if ( state == Qt::Checked )
1096 mMapItem->setFollowVisibilityPreset(
true );
1099 mKeepLayerListCheckBox->setCheckState( Qt::Unchecked );
1100 mKeepLayerStylesCheckBox->setCheckState( Qt::Unchecked );
1102 mMapItem->invalidateCache();
1106 mMapItem->setFollowVisibilityPreset(
false );
1108 mMapItem->layout()->undoStack()->endCommand();
1111void QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged(
int state )
1119 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Map Preset Changed" ) );
1120 storeCurrentLayerSet();
1121 mMapItem->setKeepLayerSet( state == Qt::Checked );
1122 if ( state == Qt::Unchecked )
1124 mMapItem->setLayers( QList< QgsMapLayer * >() );
1126 mMapItem->layout()->undoStack()->endCommand();
1129 if ( state == Qt::Checked )
1132 mFollowVisibilityPresetCheckBox->setCheckState( Qt::Unchecked );
1136 mKeepLayerStylesCheckBox->setChecked( Qt::Unchecked );
1137 mMapItem->invalidateCache();
1140 mKeepLayerStylesCheckBox->setEnabled( state == Qt::Checked );
1143void QgsLayoutMapWidget::mKeepLayerStylesCheckBox_stateChanged(
int state )
1150 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
1151 if ( state == Qt::Checked )
1153 mMapItem->storeCurrentLayerStyles();
1154 mMapItem->setKeepLayerStyles(
true );
1158 mMapItem->setLayerStyleOverrides( QMap<QString, QString>() );
1159 mMapItem->setKeepLayerStyles(
false );
1161 mMapItem->layout()->undoStack()->endCommand();
1164void QgsLayoutMapWidget::mDrawCanvasItemsCheckBox_stateChanged(
int state )
1171 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Toggle Map Item" ) );
1172 mMapItem->setDrawAnnotations( state == Qt::Checked );
1173 mMapItem->invalidateCache();
1174 mMapItem->layout()->undoStack()->endCommand();
1177void QgsLayoutMapWidget::atlasLayerChanged(
QgsVectorLayer *layer )
1182 mAtlasCheckBox->setChecked(
false );
1183 mAtlasCheckBox->setEnabled(
false );
1188 mAtlasCheckBox->setEnabled(
true );
1192 if ( mAtlasCheckBox->isChecked() )
1193 toggleAtlasScalingOptionsByLayerType();
1196bool QgsLayoutMapWidget::hasPredefinedScales()
const
1201 if ( !hasProjectScales || scales.isEmpty() )
1206 return !scales.isEmpty() && !scales[0].isEmpty();
1211void QgsLayoutMapWidget::mAddGridPushButton_clicked()
1218 const QString itemName = tr(
"Grid %1" ).arg( mMapItem->grids()->size() + 1 );
1220 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Add Map Grid" ) );
1221 mMapItem->grids()->addGrid( grid );
1222 mMapItem->layout()->undoStack()->endCommand();
1223 mMapItem->updateBoundingRect();
1226 addGridListItem( grid->
id(), grid->
name() );
1227 mGridListWidget->setCurrentRow( 0 );
1228 mGridListWidget_currentItemChanged( mGridListWidget->currentItem(),
nullptr );
1231void QgsLayoutMapWidget::mRemoveGridPushButton_clicked()
1233 QListWidgetItem *item = mGridListWidget->currentItem();
1239 mMapItem->beginCommand( tr(
"Remove Grid" ) );
1240 mMapItem->grids()->removeGrid( item->data( Qt::UserRole ).toString() );
1241 QListWidgetItem *delItem = mGridListWidget->takeItem( mGridListWidget->row( item ) );
1243 mMapItem->endCommand();
1244 mMapItem->updateBoundingRect();
1248void QgsLayoutMapWidget::mGridUpButton_clicked()
1250 QListWidgetItem *item = mGridListWidget->currentItem();
1256 const int row = mGridListWidget->row( item );
1261 mGridListWidget->takeItem( row );
1262 mGridListWidget->insertItem( row - 1, item );
1263 mGridListWidget->setCurrentItem( item );
1264 mMapItem->beginCommand( tr(
"Move Grid Up" ) );
1265 mMapItem->grids()->moveGridUp( item->data( Qt::UserRole ).toString() );
1266 mMapItem->endCommand();
1270void QgsLayoutMapWidget::mGridDownButton_clicked()
1272 QListWidgetItem *item = mGridListWidget->currentItem();
1278 const int row = mGridListWidget->row( item );
1279 if ( mGridListWidget->count() <= row )
1283 mGridListWidget->takeItem( row );
1284 mGridListWidget->insertItem( row + 1, item );
1285 mGridListWidget->setCurrentItem( item );
1286 mMapItem->beginCommand( tr(
"Move Grid Down" ) );
1287 mMapItem->grids()->moveGridDown( item->data( Qt::UserRole ).toString() );
1288 mMapItem->endCommand();
1299 QListWidgetItem *item = mGridListWidget->currentItem();
1304 return mMapItem->grids()->grid( item->data( Qt::UserRole ).toString() );
1307void QgsLayoutMapWidget::mGridListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem * )
1309 mGridPropertiesButton->setEnabled(
static_cast< bool >( current ) );
1312void QgsLayoutMapWidget::mGridListWidget_itemChanged( QListWidgetItem *item )
1325 mMapItem->beginCommand( tr(
"Rename Grid" ) );
1326 grid->
setName( item->text() );
1327 mMapItem->endCommand();
1330void QgsLayoutMapWidget::mGridPropertiesButton_clicked()
1347QListWidgetItem *QgsLayoutMapWidget::addGridListItem(
const QString &
id,
const QString &name )
1349 QListWidgetItem *item =
new QListWidgetItem( name,
nullptr );
1350 item->setData( Qt::UserRole,
id );
1351 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
1352 mGridListWidget->insertItem( 0, item );
1356void QgsLayoutMapWidget::loadGridEntries()
1359 QSet<QString> selectedIds;
1360 const QList<QListWidgetItem *> itemSelection = mGridListWidget->selectedItems();
1361 QList<QListWidgetItem *>::const_iterator sIt = itemSelection.constBegin();
1362 for ( ; sIt != itemSelection.constEnd(); ++sIt )
1364 selectedIds.insert( ( *sIt )->data( Qt::UserRole ).toString() );
1367 mGridListWidget->clear();
1373 const QList< QgsLayoutItemMapGrid * > grids = mMapItem->grids()->asList();
1374 QList< QgsLayoutItemMapGrid * >::const_iterator gridIt = grids.constBegin();
1375 for ( ; gridIt != grids.constEnd(); ++gridIt )
1377 QListWidgetItem *item = addGridListItem( ( *gridIt )->id(), ( *gridIt )->name() );
1378 if ( selectedIds.contains( ( *gridIt )->id() ) )
1380 item->setSelected(
true );
1381 mGridListWidget->setCurrentItem( item );
1385 if ( mGridListWidget->currentItem() )
1387 mGridListWidget_currentItemChanged( mGridListWidget->currentItem(),
nullptr );
1391 mGridListWidget_currentItemChanged(
nullptr,
nullptr );
1395void QgsLayoutMapWidget::mAddOverviewPushButton_clicked()
1402 const QString itemName = tr(
"Overview %1" ).arg( mMapItem->overviews()->size() + 1 );
1404 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Add Map Overview" ) );
1405 mMapItem->overviews()->addOverview( overview );
1406 mMapItem->layout()->undoStack()->endCommand();
1407 mMapItem->invalidateCache();
1409 addOverviewListItem( overview->
id(), overview->
name() );
1411 mOverviewListWidget->setCurrentRow( 0 );
1414void QgsLayoutMapWidget::mRemoveOverviewPushButton_clicked()
1416 QListWidgetItem *item = mOverviewListWidget->currentItem();
1421 mMapItem->beginCommand( tr(
"Remove Map Overview" ) );
1422 mMapItem->overviews()->removeOverview( item->data( Qt::UserRole ).toString() );
1423 mMapItem->endCommand();
1424 QListWidgetItem *delItem = mOverviewListWidget->takeItem( mOverviewListWidget->row( item ) );
1426 mMapItem->invalidateCache();
1429void QgsLayoutMapWidget::mOverviewUpButton_clicked()
1431 QListWidgetItem *item = mOverviewListWidget->currentItem();
1437 const int row = mOverviewListWidget->row( item );
1442 mOverviewListWidget->takeItem( row );
1443 mOverviewListWidget->insertItem( row - 1, item );
1444 mOverviewListWidget->setCurrentItem( item );
1445 mMapItem->beginCommand( tr(
"Move Overview Up" ) );
1446 mMapItem->overviews()->moveOverviewUp( item->data( Qt::UserRole ).toString() );
1447 mMapItem->endCommand();
1448 mMapItem->invalidateCache();
1451void QgsLayoutMapWidget::mOverviewDownButton_clicked()
1453 QListWidgetItem *item = mOverviewListWidget->currentItem();
1459 const int row = mOverviewListWidget->row( item );
1460 if ( mOverviewListWidget->count() <= row )
1464 mOverviewListWidget->takeItem( row );
1465 mOverviewListWidget->insertItem( row + 1, item );
1466 mOverviewListWidget->setCurrentItem( item );
1467 mMapItem->beginCommand( tr(
"Move Overview Down" ) );
1468 mMapItem->overviews()->moveOverviewDown( item->data( Qt::UserRole ).toString() );
1469 mMapItem->endCommand();
1470 mMapItem->invalidateCache();
1480 QListWidgetItem *item = mOverviewListWidget->currentItem();
1486 return mMapItem->overviews()->overview( item->data( Qt::UserRole ).toString() );
1489void QgsLayoutMapWidget::mOverviewListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem *previous )
1491 Q_UNUSED( previous )
1494 mOverviewCheckBox->setEnabled(
false );
1498 mOverviewCheckBox->setEnabled(
true );
1499 setOverviewItems( mMapItem->overviews()->overview( current->data( Qt::UserRole ).toString() ) );
1502void QgsLayoutMapWidget::mOverviewListWidget_itemChanged( QListWidgetItem *item )
1515 mMapItem->beginCommand( QStringLiteral(
"Rename Overview" ) );
1516 overview->
setName( item->text() );
1517 mMapItem->endCommand();
1518 if ( item->isSelected() )
1521 mOverviewCheckBox->setTitle( tr(
"Draw \"%1\" overview" ).arg( overview->
name() ) );
1525void QgsLayoutMapWidget::setOverviewItemsEnabled(
bool enabled )
1527 mOverviewFrameMapLabel->setEnabled( enabled );
1528 mOverviewFrameMapComboBox->setEnabled( enabled );
1529 mOverviewFrameStyleLabel->setEnabled( enabled );
1530 mOverviewFrameStyleButton->setEnabled( enabled );
1531 mOverviewBlendModeLabel->setEnabled( enabled );
1532 mOverviewBlendModeComboBox->setEnabled( enabled );
1533 mOverviewInvertCheckbox->setEnabled( enabled );
1534 mOverviewCenterCheckbox->setEnabled( enabled );
1535 mOverviewPositionComboBox->setEnabled( enabled );
1541void QgsLayoutMapWidget::blockOverviewItemsSignals(
const bool block )
1543 mOverviewFrameMapComboBox->blockSignals( block );
1544 mOverviewFrameStyleButton->blockSignals( block );
1545 mOverviewBlendModeComboBox->blockSignals( block );
1546 mOverviewInvertCheckbox->blockSignals( block );
1547 mOverviewCenterCheckbox->blockSignals( block );
1548 mOverviewPositionComboBox->blockSignals( block );
1549 mOverviewStackingLayerComboBox->blockSignals( block );
1559 blockOverviewItemsSignals(
true );
1561 mOverviewCheckBox->setTitle( tr(
"Draw \"%1\" overview" ).arg( overview->
name() ) );
1562 mOverviewCheckBox->setChecked( overview->
enabled() );
1565 mOverviewFrameMapComboBox->setItem( overview->
linkedMap() );
1568 mOverviewBlendModeComboBox->setBlendMode( overview->
blendMode() );
1570 mOverviewInvertCheckbox->setChecked( overview->
inverted() );
1572 mOverviewCenterCheckbox->setChecked( overview->
centered() );
1574 mOverviewPositionComboBox->setCurrentIndex( mOverviewPositionComboBox->findData( overview->
stackingPosition() ) );
1575 mOverviewStackingLayerComboBox->setLayer( overview->
stackingLayer() );
1581 blockOverviewItemsSignals(
false );
1584void QgsLayoutMapWidget::storeCurrentLayerSet()
1591 mMapItem->setLayers( layers );
1593 if ( mMapItem->keepLayerStyles() )
1596 mMapItem->storeCurrentLayerStyles();
1600QList<QgsMapLayer *> QgsLayoutMapWidget::orderedPresetVisibleLayers(
const QString &name )
const
1605 QList<QgsMapLayer *> lst;
1609 if ( visibleIds.contains( layer->
id() ) )
1617QListWidgetItem *QgsLayoutMapWidget::addOverviewListItem(
const QString &
id,
const QString &name )
1619 QListWidgetItem *item =
new QListWidgetItem( name,
nullptr );
1620 item->setData( Qt::UserRole,
id );
1621 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
1622 mOverviewListWidget->insertItem( 0, item );
1626void QgsLayoutMapWidget::loadOverviewEntries()
1629 QSet<QString> selectedIds;
1630 const QList<QListWidgetItem *> itemSelection = mOverviewListWidget->selectedItems();
1631 QList<QListWidgetItem *>::const_iterator sIt = itemSelection.constBegin();
1632 for ( ; sIt != itemSelection.constEnd(); ++sIt )
1634 selectedIds.insert( ( *sIt )->data( Qt::UserRole ).toString() );
1637 mOverviewListWidget->clear();
1643 mOverviewFrameMapComboBox->setExceptedItemList( QList< QgsLayoutItem * >() << mMapItem );
1646 const QList< QgsLayoutItemMapOverview * > overviews = mMapItem->overviews()->asList();
1647 QList< QgsLayoutItemMapOverview * >::const_iterator overviewIt = overviews.constBegin();
1648 for ( ; overviewIt != overviews.constEnd(); ++overviewIt )
1650 QListWidgetItem *item = addOverviewListItem( ( *overviewIt )->id(), ( *overviewIt )->name() );
1651 if ( selectedIds.contains( ( *overviewIt )->id() ) )
1653 item->setSelected(
true );
1654 mOverviewListWidget->setCurrentItem( item );
1658 if ( mOverviewListWidget->currentItem() )
1660 mOverviewListWidget_currentItemChanged( mOverviewListWidget->currentItem(),
nullptr );
1664 mOverviewListWidget_currentItemChanged(
nullptr,
nullptr );
1668void QgsLayoutMapWidget::mOverviewCheckBox_toggled(
bool state )
1676 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Overview Display Toggled" ) );
1678 mMapItem->invalidateCache();
1679 mMapItem->layout()->undoStack()->endCommand();
1682void QgsLayoutMapWidget::overviewMapChanged(
QgsLayoutItem *item )
1694 mMapItem->beginCommand( tr(
"Change Overview Map" ) );
1696 mMapItem->invalidateCache();
1697 mMapItem->endCommand();
1700void QgsLayoutMapWidget::mOverviewBlendModeComboBox_currentIndexChanged(
int index )
1709 mMapItem->beginCommand( tr(
"Change Overview Blend Mode" ) );
1710 overview->
setBlendMode( mOverviewBlendModeComboBox->blendMode() );
1711 mMapItem->invalidateCache();
1712 mMapItem->endCommand();
1715void QgsLayoutMapWidget::mOverviewInvertCheckbox_toggled(
bool state )
1723 mMapItem->beginCommand( tr(
"Toggle Overview Inverted" ) );
1725 mMapItem->invalidateCache();
1726 mMapItem->endCommand();
1729void QgsLayoutMapWidget::mOverviewCenterCheckbox_toggled(
bool state )
1737 mMapItem->beginCommand( tr(
"Toggle Overview Centered" ) );
1739 mMapItem->invalidateCache();
1740 mMapItem->endCommand();
1743void QgsLayoutMapWidget::overviewStackingChanged(
int )
1751 mMapItem->beginCommand( tr(
"Change Overview Position" ) );
1753 mMapItem->invalidateCache();
1754 mMapItem->endCommand();
1761 mOverviewStackingLayerComboBox->setEnabled(
false );
1766 mOverviewStackingLayerComboBox->setEnabled(
true );
1771void QgsLayoutMapWidget::overviewStackingLayerChanged(
QgsMapLayer *layer )
1779 mMapItem->beginCommand( tr(
"Change Overview Position" ) );
1781 mMapItem->invalidateCache();
1782 mMapItem->endCommand();
1796 mLabelBoundarySpinBox->setClearValue( 0 );
1797 mLabelBoundarySpinBox->setShowClearButton(
true );
1799 mLabelBoundaryUnitsCombo->linkToWidget( mLabelBoundarySpinBox );
1800 mLabelBoundaryUnitsCombo->setConverter( &mMapItem->layout()->renderContext().measurementConverter() );
1803 connect( mLabelBoundarySpinBox,
static_cast < void ( QDoubleSpinBox::* )(
double )
> ( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapLabelingWidget::labelMarginChanged );
1804 connect( mShowPartialLabelsCheckBox, &QCheckBox::toggled,
this, &QgsLayoutMapLabelingWidget::showPartialsToggled );
1805 connect( mShowUnplacedCheckBox, &QCheckBox::toggled,
this, &QgsLayoutMapLabelingWidget::showUnplacedToggled );
1822 mMapItem = qobject_cast< QgsLayoutItemMap * >( item );
1829 updateGuiElements();
1834void QgsLayoutMapLabelingWidget::updateGuiElements()
1836 whileBlocking( mLabelBoundarySpinBox )->setValue( mMapItem->labelMargin().length() );
1837 whileBlocking( mLabelBoundaryUnitsCombo )->setUnit( mMapItem->labelMargin().units() );
1841 if ( mBlockingItemsListView->model() )
1843 QAbstractItemModel *oldModel = mBlockingItemsListView->model();
1844 mBlockingItemsListView->setModel(
nullptr );
1845 oldModel->deleteLater();
1849 mBlockingItemsListView->setModel( model );
1854void QgsLayoutMapLabelingWidget::labelMarginChanged(
double val )
1861 mMapItem->layout()->undoStack()->endCommand();
1862 mMapItem->invalidateCache();
1865void QgsLayoutMapLabelingWidget::labelMarginUnitsChanged()
1871 mMapItem->setLabelMargin(
QgsLayoutMeasurement( mLabelBoundarySpinBox->value(), mLabelBoundaryUnitsCombo->unit() ) );
1872 mMapItem->layout()->undoStack()->endCommand();
1873 mMapItem->invalidateCache();
1876void QgsLayoutMapLabelingWidget::showPartialsToggled(
bool checked )
1881 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Label Visibility" ) );
1887 mMapItem->setMapFlags( flags );
1888 mMapItem->layout()->undoStack()->endCommand();
1889 mMapItem->invalidateCache();
1892void QgsLayoutMapLabelingWidget::showUnplacedToggled(
bool checked )
1897 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Label Visibility" ) );
1903 mMapItem->setMapFlags( flags );
1904 mMapItem->layout()->undoStack()->endCommand();
1905 mMapItem->invalidateCache();
1909 : QSortFilterProxyModel( parent )
1910 , mLayoutModel( layoutModel )
1913 setSourceModel( layoutModel );
1926 if ( i.column() != 0 )
1939 case Qt::CheckStateRole:
1940 switch ( i.column() )
1943 return mMapItem ? ( mMapItem->isLabelBlockingItem( item ) ? Qt::Checked : Qt::Unchecked ) : Qt::Unchecked;
1949 return mLayoutModel->
data( sourceIndex, role );
1957 if ( !index.isValid() )
1961 if ( !item || !mMapItem )
1966 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Label Blocking Items" ) );
1968 if ( value.toBool() )
1970 mMapItem->addLabelBlockingItem( item );
1974 mMapItem->removeLabelBlockingItem( item );
1976 emit dataChanged( index, index, QVector<int>() << role );
1978 mMapItem->layout()->undoStack()->endCommand();
1979 mMapItem->invalidateCache();
1986 Qt::ItemFlags
flags = QSortFilterProxyModel::flags( index );
1988 if ( ! index.isValid() )
1993 switch ( index.column() )
1996 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
1998 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
2005 if ( !item || item == mMapItem )
2028 mLayersTreeView->setModel( mLayerModel );
2034 for (
int i = 0; i < mAtlasClippingTypeComboBox->count(); ++i )
2036 mItemClippingTypeComboBox->addItem( mAtlasClippingTypeComboBox->itemText( i ), mAtlasClippingTypeComboBox->itemData( i ) );
2039 mClipItemComboBox->setCurrentLayout( map->
layout() );
2042 connect( mRadioClipSelectedLayers, &QRadioButton::toggled,
this, &QgsLayoutMapClippingWidget::toggleLayersSelectionGui );
2043 mLayersTreeView->setEnabled(
false );
2044 mSelectAllButton->setEnabled(
false );
2045 mDeselectAllButton->setEnabled(
false );
2046 mInvertSelectionButton->setEnabled(
false );
2047 mRadioClipAllLayers->setChecked(
true );
2049 connect( mClipToAtlasCheckBox, &QGroupBox::toggled,
this, [ = ](
bool active )
2051 if ( !mBlockUpdates )
2053 mMapItem->beginCommand( tr(
"Toggle Atlas Clipping" ) );
2054 mMapItem->atlasClippingSettings()->setEnabled( active );
2055 mMapItem->endCommand();
2058 connect( mForceLabelsInsideCheckBox, &QCheckBox::toggled,
this, [ = ](
bool active )
2060 if ( !mBlockUpdates )
2062 mMapItem->beginCommand( tr(
"Change Atlas Clipping Label Behavior" ) );
2063 mMapItem->atlasClippingSettings()->setForceLabelsInsideFeature( active );
2064 mMapItem->endCommand();
2067 connect( mAtlasClippingTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [ = ]
2069 if ( !mBlockUpdates )
2071 mMapItem->beginCommand( tr(
"Change Atlas Clipping Behavior" ) );
2073 mMapItem->endCommand();
2077 connect( mRadioClipSelectedLayers, &QCheckBox::toggled,
this, [ = ](
bool active )
2079 if ( active && !mBlockUpdates )
2081 mBlockUpdates =
true;
2082 mMapItem->beginCommand( tr(
"Change Atlas Clipping Layers" ) );
2083 mMapItem->atlasClippingSettings()->setRestrictToLayers(
true );
2084 mMapItem->endCommand();
2085 mBlockUpdates =
false;
2089 connect( mSelectAllButton, &QPushButton::clicked,
this, &QgsLayoutMapClippingWidget::selectAll );
2090 connect( mDeselectAllButton, &QPushButton::clicked,
this, &QgsLayoutMapClippingWidget::deselectAll );
2091 connect( mInvertSelectionButton, &QPushButton::clicked,
this, &QgsLayoutMapClippingWidget::invertSelection );
2093 connect( mRadioClipAllLayers, &QCheckBox::toggled,
this, [ = ](
bool active )
2095 if ( active && !mBlockUpdates )
2097 mBlockUpdates =
true;
2098 mMapItem->beginCommand( tr(
"Change Atlas Clipping Layers" ) );
2099 mMapItem->atlasClippingSettings()->setRestrictToLayers(
false );
2100 mMapItem->endCommand();
2101 mBlockUpdates =
false;
2104 connect( mLayerModel, &QgsMapLayerModel::dataChanged,
this, [ = ](
const QModelIndex &,
const QModelIndex &,
const QVector<int> &roles = QVector<int>() )
2106 if ( !roles.contains( Qt::CheckStateRole ) )
2109 if ( !mBlockUpdates )
2111 mBlockUpdates =
true;
2112 mMapItem->beginCommand( tr(
"Change Atlas Clipping Layers" ) );
2113 mMapItem->atlasClippingSettings()->setLayersToClip( mLayerModel->
layersChecked() );
2114 mMapItem->endCommand();
2115 mBlockUpdates =
false;
2121 connect( mClipToItemCheckBox, &QGroupBox::toggled,
this, [ = ](
bool active )
2123 if ( !mBlockUpdates )
2125 mMapItem->beginCommand( tr(
"Toggle Map Clipping" ) );
2126 mMapItem->itemClippingSettings()->setEnabled( active );
2127 mMapItem->endCommand();
2130 connect( mItemClippingTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [ = ]
2132 if ( !mBlockUpdates )
2134 mMapItem->beginCommand( tr(
"Change Map Clipping Behavior" ) );
2136 mMapItem->endCommand();
2139 connect( mForceLabelsInsideItemCheckBox, &QCheckBox::toggled,
this, [ = ](
bool active )
2141 if ( !mBlockUpdates )
2143 mMapItem->beginCommand( tr(
"Change Map Clipping Label Behavior" ) );
2144 mMapItem->itemClippingSettings()->setForceLabelsInsideClipPath( active );
2145 mMapItem->endCommand();
2150 if ( !mBlockUpdates )
2152 mMapItem->beginCommand( tr(
"Change Map Clipping Item" ) );
2153 mMapItem->itemClippingSettings()->setSourceItem( item );
2154 mMapItem->endCommand();
2161 this, &QgsLayoutMapClippingWidget::atlasLayerChanged );
2165 atlasToggled( atlas->enabled() );
2171 mClipToAtlasCheckBox->setTitle( tr(
"Clip to %1 feature" ).arg(
string ) );
2172 mClipToAtlasLabel->setText( tr(
"<b>When enabled, map layers will be automatically clipped to the boundary of the current %1 feature.</b>" ).arg(
string ) );
2173 mForceLabelsInsideCheckBox->setText( tr(
"Force labels inside %1 feature" ).arg(
string ) );
2186 mMapItem = qobject_cast< QgsLayoutItemMap * >( item );
2193 updateGuiElements();
2198void QgsLayoutMapClippingWidget::updateGuiElements()
2200 if ( mBlockUpdates )
2203 mBlockUpdates =
true;
2204 mClipToAtlasCheckBox->setChecked( mMapItem->atlasClippingSettings()->enabled() );
2205 mAtlasClippingTypeComboBox->setCurrentIndex( mAtlasClippingTypeComboBox->findData(
static_cast< int >( mMapItem->atlasClippingSettings()->featureClippingType() ) ) );
2206 mForceLabelsInsideCheckBox->setChecked( mMapItem->atlasClippingSettings()->forceLabelsInsideFeature() );
2208 mRadioClipAllLayers->setChecked( !mMapItem->atlasClippingSettings()->restrictToLayers() );
2209 mRadioClipSelectedLayers->setChecked( mMapItem->atlasClippingSettings()->restrictToLayers() );
2210 mLayerModel->
setLayersChecked( mMapItem->atlasClippingSettings()->layersToClip() );
2212 mClipToItemCheckBox->setChecked( mMapItem->itemClippingSettings()->enabled() );
2213 mItemClippingTypeComboBox->setCurrentIndex( mItemClippingTypeComboBox->findData(
static_cast< int >( mMapItem->itemClippingSettings()->featureClippingType() ) ) );
2214 mForceLabelsInsideItemCheckBox->setChecked( mMapItem->itemClippingSettings()->forceLabelsInsideClipPath() );
2215 mClipItemComboBox->setItem( mMapItem->itemClippingSettings()->sourceItem() );
2217 mBlockUpdates =
false;
2220void QgsLayoutMapClippingWidget::atlasLayerChanged(
QgsVectorLayer *layer )
2225 mClipToAtlasCheckBox->setChecked(
false );
2226 mClipToAtlasCheckBox->setEnabled(
false );
2231 mClipToAtlasCheckBox->setEnabled(
true );
2235void QgsLayoutMapClippingWidget::atlasToggled(
bool atlasEnabled )
2237 if ( atlasEnabled &&
2238 mMapItem && mMapItem->layout() && mMapItem->layout()->reportContext().layer()
2241 mClipToAtlasCheckBox->setEnabled(
true );
2245 mClipToAtlasCheckBox->setEnabled(
false );
2246 mClipToAtlasCheckBox->setChecked(
false );
2250void QgsLayoutMapClippingWidget::invertSelection()
2252 for (
int i = 0; i < mLayerModel->
rowCount( QModelIndex() ); i++ )
2254 QModelIndex index = mLayerModel->
index( i, 0 );
2255 Qt::CheckState currentState = Qt::CheckState( mLayerModel->
data( index, Qt::CheckStateRole ).toInt() );
2256 Qt::CheckState newState = ( currentState == Qt::Checked ) ? Qt::Unchecked : Qt::Checked;
2257 mLayerModel->
setData( index, newState, Qt::CheckStateRole );
2261void QgsLayoutMapClippingWidget::selectAll()
2263 for (
int i = 0; i < mLayerModel->
rowCount( QModelIndex() ); i++ )
2265 QModelIndex index = mLayerModel->
index( i, 0 );
2266 mLayerModel->
setData( index, Qt::Checked, Qt::CheckStateRole );
2270void QgsLayoutMapClippingWidget::deselectAll()
2272 for (
int i = 0; i < mLayerModel->
rowCount( QModelIndex() ); i++ )
2274 QModelIndex index = mLayerModel->
index( i, 0 );
2275 mLayerModel->
setData( index, Qt::Unchecked, Qt::CheckStateRole );
2279void QgsLayoutMapClippingWidget::toggleLayersSelectionGui(
bool toggled )
2281 mLayersTreeView->setEnabled( toggled );
2282 mSelectAllButton->setEnabled( toggled );
2283 mDeselectAllButton->setEnabled( toggled );
2284 mInvertSelectionButton->setEnabled( toggled );
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QgsBookmarkManager * bookmarkManager()
Returns the application's bookmark manager, used for storing installation-wide bookmarks.
@ Extent
Bookmark extent as a QgsReferencedRectangle.
A QSortFilterProxyModel subclass for sorting the entries in a QgsBookmarkManagerModel.
This class represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Custom exception class for Coordinate Reference System related exceptions.
QgsRange which stores a range of double values.
The QgsSpinBox is a spin box with a clear button that will set the value to the defined clear value.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
QgsFillSymbol * clone() const override
Returns a deep copy of this symbol.
QList< QgsMapLayer * > layerOrder() const
The order in which layers will be rendered on the canvas.
Class used to render QgsLayout as an atlas, by iterating over the features from an associated vector ...
void toggled(bool)
Emitted when atlas is enabled or disabled.
A common interface for layout designer dialogs and widgets.
virtual void activateTool(StandardTool tool)=0
Activates a standard layout designer tool.
@ ToolMoveItemContent
Move item content tool.
void itemChanged(QgsLayoutItem *item)
Emitted whenever the currently selected item changes.
An individual grid which is drawn above the map content in a QgsLayoutItemMap.
QString id() const
Returns the unique id for the map item.
StackingPosition
Item stacking position, specifies where the in the map's stack the item should be rendered.
@ StackBelowMapLabels
Render above all map layers, but below map labels.
@ StackAboveMapLabels
Render above all map layers and labels.
@ StackBelowMapLayer
Render below a specific map layer (see stackingLayer())
@ StackAboveMapLayer
Render above a specific map layer (see stackingLayer())
@ StackBelowMap
Render below all map layers.
void setStackingLayer(QgsMapLayer *layer)
Sets the item's stacking layer, which specifies where the in the map's stack the item should be rende...
virtual void setEnabled(bool enabled)
Controls whether the item will be drawn.
void setStackingPosition(StackingPosition position)
Sets the item's stacking position, which specifies where the in the map's stack the item should be re...
StackingPosition stackingPosition() const
Returns the item's stacking position, which specifies where the in the map's stack the item should be...
QString name() const
Returns the friendly display name for the item.
void setName(const QString &name)
Sets the friendly display name for the item.
bool enabled() const
Returns whether the item will be drawn.
QgsMapLayer * stackingLayer() const
Returns the item's stacking layer, which specifies where the in the map's stack the item should be re...
An individual overview which is drawn above the map content in a QgsLayoutItemMap,...
QgsFillSymbol * frameSymbol()
Returns the fill symbol used for drawing the overview extent.
QPainter::CompositionMode blendMode() const
Retrieves the blending mode used for drawing the overview.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the overview.
bool centered() const
Returns whether the extent of the map is forced to center on the overview.
void setLinkedMap(QgsLayoutItemMap *map)
Sets the map to show the overview extent of.
void setFrameSymbol(QgsFillSymbol *symbol)
Sets the fill symbol used for drawing the overview extent.
bool inverted() const
Returns whether the overview frame is inverted, ie, whether the shaded area is drawn outside the exte...
void setInverted(bool inverted)
Sets whether the overview frame is inverted, ie, whether the shaded area is drawn outside the extent ...
void setCentered(bool centered)
Sets whether the extent of the map is forced to center on the overview.
QgsLayoutItemMap * linkedMap()
Returns the source map to show the overview extent of.
Layout graphical items for displaying a map.
void extentChanged()
Emitted when the map's extent changes.
@ Predefined
A scale is chosen from the predefined scales.
@ Auto
The extent is adjusted so that each feature is fully visible.
@ Fixed
The current scale of the map is used for each feature of the atlas.
void mapRotationChanged(double newRotation)
Emitted when the map's rotation changes.
QFlags< MapItemFlag > MapItemFlags
@ ShowPartialLabels
Whether to draw labels which are partially outside of the map view.
@ ShowUnplacedLabels
Whether to render unplaced labels in the map view.
Base class for graphical items within a QgsLayout.
@ UndoOverviewStyle
Map overview style.
@ UndoMapRotation
Map rotation changed.
@ UndoAtlasMargin
Map atlas margin changed.
@ UndoMapLabelMargin
Margin for labels from edge of map.
int type() const override
Returns a unique graphics item type identifier.
@ FlagProvidesClipPath
Item can act as a clipping path provider (see clipPath())
Model for label blocking items.
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
QgsLayoutMapItemBlocksLabelsModel(QgsLayoutItemMap *map, QgsLayoutModel *layoutModel, QObject *parent=nullptr)
constructor
Qt::ItemFlags flags(const QModelIndex &index) const override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QVariant data(const QModelIndex &index, int role) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
This class provides a method of storing measurements for use in QGIS layouts using a variety of diffe...
A model for items attached to a layout.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
QgsLayoutItem * itemFromIndex(const QModelIndex &index) const
Returns the QgsLayoutItem corresponding to a QModelIndex index, if possible.
const QgsLayout * layout() const
Returns the layout the object is attached to.
void changed()
Emitted when the object's properties change.
@ MapYMin
Map extent y minimum.
@ MapZRangeUpper
Map frame Z-range lower value (since QGIS 3.38)
@ StartDateTime
Temporal range's start DateTime.
@ MapLayers
Map layer set.
@ MapZRangeLower
Map frame Z-range lower value (since QGIS 3.38)
@ MapRotation
Map rotation.
@ MapXMax
Map extent x maximum.
@ MapStylePreset
Layer and style map theme.
@ MapYMax
Map extent y maximum.
@ MapAtlasMargin
Map atlas margin.
@ EndDateTime
Temporal range's end DateTime.
@ MapXMin
Map extent x minimum.
@ MapLabelMargin
Map label margin.
@ OriginalValue
Return the original, user set value.
void layerChanged(QgsVectorLayer *layer)
Emitted when the context's layer is changed.
void unitChanged(Qgis::LayoutUnit unit)
Emitted when the unit is changed.
QgsLayoutReportContext & reportContext()
Returns a reference to the layout's report context, which stores information relating to the current ...
Map canvas is a class for displaying all GIS data types on a canvas.
void zoomScale(double scale, bool ignoreScaleLock=false)
Zooms the canvas to a specific scale.
bool setReferencedExtent(const QgsReferencedRectangle &extent)
Sets the canvas to the specified extent.
double scale() const
Returns the last reported scale of the canvas.
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
void refresh()
Repaints the canvas map.
FeatureClippingType
Feature clipping behavior, which controls how features from vector layers will be clipped.
@ NoClipping
Only render features which intersect the clipping region, but do not clip these features to the regio...
@ ClipPainterOnly
Applying clipping on the painter only (i.e. feature boundaries will be unchanged, but may be invisibl...
@ ClipToIntersection
Clip the geometry of these features to the region prior to rendering (i.e. feature boundaries will fo...
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
The QgsMapLayerModel class is a model to display layers in widgets.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QList< QgsMapLayer * > layersChecked(Qt::CheckState checkState=Qt::Checked)
layersChecked returns the list of layers which are checked (or unchecked)
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void setItemsCheckable(bool checkable)
setItemsCheckable defines if layers should be selectable in the widget
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override
void setLayersChecked(const QList< QgsMapLayer * > &layers)
Sets which layers are checked in the model.
Base class for all map layer types.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
void mapThemesChanged()
Emitted when map themes within the collection are changed.
QStringList mapThemeVisibleLayerIds(const QString &name) const
Returns the list of layer IDs that are visible for the specified map theme.
Interface for master layout type objects, such as print layouts and reports.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsMapThemeCollection * mapThemeCollection
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
QgsCoordinateReferenceSystem crs
A rectangle specified with double values.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
double yMaximum() const
Returns the y maximum value (top side of rectangle).
bool isEmpty() const
Returns true if the rectangle has no area.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsRectangle with associated coordinate reference system.
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryStringList * settingsMapScales
This class is a composition of two QSettings instances:
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QgsTemporalRange< QDateTime > QgsDateTimeRange
QgsRange which stores a range of date times.
const QgsCoordinateReferenceSystem & crs