20#include "moc_qgslayoutmapwidget.cpp"
41#include <QStringListModel>
46 , mMapCanvas( mapCanvas )
51 connect( mScaleLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mScaleLineEdit_editingFinished );
52 connect( mActionSetToCanvasExtent, &QAction::triggered,
this, &QgsLayoutMapWidget::setToMapCanvasExtent );
53 connect( mActionViewExtentInCanvas, &QAction::triggered,
this, &QgsLayoutMapWidget::viewExtentInCanvas );
54 connect( mActionSetToCanvasScale, &QAction::triggered,
this, &QgsLayoutMapWidget::setToMapCanvasScale );
55 connect( mActionViewScaleInCanvas, &QAction::triggered,
this, &QgsLayoutMapWidget::viewScaleInCanvas );
56 connect( mActionUpdatePreview, &QAction::triggered,
this, &QgsLayoutMapWidget::updatePreview );
57 connect( mFollowVisibilityPresetCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged );
58 connect( mKeepLayerListCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged );
59 connect( mKeepLayerStylesCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mKeepLayerStylesCheckBox_stateChanged );
60 connect( mDrawCanvasItemsCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutMapWidget::mDrawCanvasItemsCheckBox_stateChanged );
61 connect( mOverviewBlendModeComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutMapWidget::mOverviewBlendModeComboBox_currentIndexChanged );
62 connect( mOverviewInvertCheckbox, &QCheckBox::toggled,
this, &QgsLayoutMapWidget::mOverviewInvertCheckbox_toggled );
63 connect( mOverviewCenterCheckbox, &QCheckBox::toggled,
this, &QgsLayoutMapWidget::mOverviewCenterCheckbox_toggled );
64 connect( mOverviewPositionComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutMapWidget::overviewStackingChanged );
66 connect( mXMinLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mXMinLineEdit_editingFinished );
67 connect( mXMaxLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mXMaxLineEdit_editingFinished );
68 connect( mYMinLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mYMinLineEdit_editingFinished );
69 connect( mYMaxLineEdit, &QLineEdit::editingFinished,
this, &QgsLayoutMapWidget::mYMaxLineEdit_editingFinished );
70 connect( mAtlasMarginRadio, &QRadioButton::toggled,
this, &QgsLayoutMapWidget::mAtlasMarginRadio_toggled );
71 connect( mAtlasCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mAtlasCheckBox_toggled );
72 connect( mAtlasMarginSpinBox,
static_cast<void ( QSpinBox::* )(
int )
>( &QSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::mAtlasMarginSpinBox_valueChanged );
73 connect( mAtlasFixedScaleRadio, &QRadioButton::toggled,
this, &QgsLayoutMapWidget::mAtlasFixedScaleRadio_toggled );
74 connect( mAtlasPredefinedScaleRadio, &QRadioButton::toggled,
this, &QgsLayoutMapWidget::mAtlasPredefinedScaleRadio_toggled );
75 connect( mAddGridPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mAddGridPushButton_clicked );
76 connect( mRemoveGridPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mRemoveGridPushButton_clicked );
77 connect( mCopyGridPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mCopyGridPushButton_clicked );
78 connect( mGridUpButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mGridUpButton_clicked );
79 connect( mGridDownButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mGridDownButton_clicked );
80 connect( mGridListWidget, &QListWidget::currentItemChanged,
this, &QgsLayoutMapWidget::mGridListWidget_currentItemChanged );
81 connect( mGridListWidget, &QListWidget::itemChanged,
this, &QgsLayoutMapWidget::mGridListWidget_itemChanged );
82 connect( mGridPropertiesButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mGridPropertiesButton_clicked );
83 connect( mAddOverviewPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mAddOverviewPushButton_clicked );
84 connect( mRemoveOverviewPushButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mRemoveOverviewPushButton_clicked );
85 connect( mOverviewUpButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mOverviewUpButton_clicked );
86 connect( mOverviewDownButton, &QPushButton::clicked,
this, &QgsLayoutMapWidget::mOverviewDownButton_clicked );
87 connect( mOverviewCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mOverviewCheckBox_toggled );
88 connect( mOverviewListWidget, &QListWidget::currentItemChanged,
this, &QgsLayoutMapWidget::mOverviewListWidget_currentItemChanged );
89 connect( mOverviewListWidget, &QListWidget::itemChanged,
this, &QgsLayoutMapWidget::mOverviewListWidget_itemChanged );
90 connect( mActionLabelSettings, &QAction::triggered,
this, &QgsLayoutMapWidget::showLabelSettings );
91 connect( mActionClipSettings, &QAction::triggered,
this, &QgsLayoutMapWidget::showClipSettings );
93 connect( mTemporalCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mTemporalCheckBox_toggled );
94 connect( mStartDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsLayoutMapWidget::updateTemporalExtent );
95 connect( mEndDateTime, &QDateTimeEdit::dateTimeChanged,
this, &QgsLayoutMapWidget::updateTemporalExtent );
99 connect( mElevationRangeCheckBox, &QgsCollapsibleGroupBoxBasic::toggled,
this, &QgsLayoutMapWidget::mElevationRangeCheckBox_toggled );
100 connect( mZLowerSpin, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::updateZRange );
101 connect( mZUpperSpin, qOverload<double>( &QgsDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapWidget::updateZRange );
103 mStartDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
104 mEndDateTime->setDateTimeRange( QDateTime( QDate( 1, 1, 1 ), QTime( 0, 0, 0 ) ), mStartDateTime->maximumDateTime() );
105 mStartDateTime->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
106 mEndDateTime->setDisplayFormat(
"yyyy-MM-dd HH:mm:ss" );
108 connect( mActionMoveContent, &QAction::triggered,
this, &QgsLayoutMapWidget::switchToMoveContentTool );
110 mMapRotationSpinBox->setClearValue( 0 );
114 mBookmarkMenu =
new QMenu(
this );
115 QToolButton *btnBookmarks =
new QToolButton(
this );
116 btnBookmarks->setAutoRaise(
true );
117 btnBookmarks->setToolTip( tr(
"Bookmarks" ) );
119 btnBookmarks->setPopupMode( QToolButton::InstantPopup );
120 btnBookmarks->setMenu( mBookmarkMenu );
122 mDockToolbar->insertWidget( mActionMoveContent, btnBookmarks );
123 connect( mBookmarkMenu, &QMenu::aboutToShow,
this, &QgsLayoutMapWidget::aboutToShowBookmarkMenu );
127 mainLayout->addWidget( mItemPropertiesWidget );
129 mScaleLineEdit->setValidator(
new QDoubleValidator( mScaleLineEdit ) );
131 mXMinLineEdit->setValidator(
new QDoubleValidator( mXMinLineEdit ) );
132 mXMaxLineEdit->setValidator(
new QDoubleValidator( mXMaxLineEdit ) );
133 mYMinLineEdit->setValidator(
new QDoubleValidator( mYMinLineEdit ) );
134 mYMaxLineEdit->setValidator(
new QDoubleValidator( mYMaxLineEdit ) );
142 blockAllSignals(
true );
145 mCrsSelector->setNotSetText( tr(
"Use Project CRS" ) );
146 mCrsSelector->setDialogTitle( tr(
"Map Item CRS" ) );
151 mFollowVisibilityPresetCombo->setModel(
new QStringListModel( mFollowVisibilityPresetCombo ) );
152 connect( mFollowVisibilityPresetCombo,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsLayoutMapWidget::followVisibilityPresetSelected );
154 onMapThemesChanged();
157 QMenu *menuKeepLayers =
new QMenu(
this );
158 mLayerListFromPresetButton->setMenu( menuKeepLayers );
160 mLayerListFromPresetButton->setToolTip( tr(
"Set layer list from a map theme" ) );
161 connect( menuKeepLayers, &QMenu::aboutToShow,
this, &QgsLayoutMapWidget::aboutToShowKeepLayersVisibilityPresetsMenu );
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 )
288 if ( atlasEnabled && mMapItem && mMapItem->layout() && mMapItem->layout()->reportContext().layer()
291 mAtlasCheckBox->setEnabled(
true );
295 mAtlasCheckBox->setEnabled(
false );
296 mAtlasCheckBox->setChecked(
false );
300void QgsLayoutMapWidget::aboutToShowKeepLayersVisibilityPresetsMenu()
305 QMenu *menu = qobject_cast<QMenu *>( sender() );
311 for (
const QString &presetName : constMapThemes )
313 menu->addAction( presetName,
this, &QgsLayoutMapWidget::keepLayersVisibilityPresetSelected );
316 if ( menu->actions().isEmpty() )
317 menu->addAction( tr(
"No presets defined" ) )->setEnabled(
false );
320void QgsLayoutMapWidget::followVisibilityPresetSelected(
int currentIndex )
325 if ( mBlockThemeComboChanges != 0 )
328 if ( currentIndex == -1 )
332 if ( currentIndex != 0 )
334 presetName = mFollowVisibilityPresetCombo->currentText();
337 if ( presetName == mMapItem->followVisibilityPresetName() )
340 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
341 mFollowVisibilityPresetCheckBox->setChecked(
true );
342 mMapItem->setFollowVisibilityPresetName( presetName );
343 mMapItem->layout()->undoStack()->endCommand();
345 mMapItem->invalidateCache();
348void QgsLayoutMapWidget::keepLayersVisibilityPresetSelected()
350 QAction *action = qobject_cast<QAction *>( sender() );
354 const QString presetName = action->text();
355 const QList<QgsMapLayer *> lst = orderedPresetVisibleLayers( presetName );
358 mKeepLayerListCheckBox->setChecked(
true );
359 mMapItem->setLayers( lst );
361 mKeepLayerStylesCheckBox->setChecked(
true );
363 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
364 mMapItem->setLayerStyleOverrides(
QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverrides( presetName ) );
365 mMapItem->layout()->undoStack()->endCommand();
367 mMapItem->invalidateCache();
371void QgsLayoutMapWidget::onMapThemesChanged()
373 if ( QStringListModel *model = qobject_cast<QStringListModel *>( mFollowVisibilityPresetCombo->model() ) )
375 mBlockThemeComboChanges++;
377 lst.append( tr(
"(none)" ) );
379 model->setStringList( lst );
382 const int presetModelIndex = mFollowVisibilityPresetCombo->findText( mMapItem->followVisibilityPresetName() );
383 mFollowVisibilityPresetCombo->blockSignals(
true );
384 mFollowVisibilityPresetCombo->setCurrentIndex( presetModelIndex != -1 ? presetModelIndex : 0 );
385 mFollowVisibilityPresetCombo->blockSignals(
false );
386 mBlockThemeComboChanges--;
397 if ( mMapItem->presetCrs() ==
crs )
403 bool updateExtent =
false;
410 newExtent = xForm.transformBoundingBox( prevExtent );
418 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map CRS" ) );
419 mMapItem->setCrs(
crs );
421 mMapItem->zoomToExtent( newExtent );
422 mMapItem->layout()->undoStack()->endCommand();
423 mMapItem->invalidateCache();
426void QgsLayoutMapWidget::overviewSymbolChanged()
434 mMapItem->endCommand();
435 mMapItem->invalidateCache();
438void QgsLayoutMapWidget::showLabelSettings()
442 if ( !mReportTypeString.isEmpty() )
443 mLabelWidget->setReportTypeString( mReportTypeString );
448void QgsLayoutMapWidget::showClipSettings()
451 if ( !mReportTypeString.isEmpty() )
452 mClipWidget->setReportTypeString( mReportTypeString );
456void QgsLayoutMapWidget::switchToMoveContentTool()
462void QgsLayoutMapWidget::aboutToShowBookmarkMenu()
464 mBookmarkMenu->clear();
468 if ( !mBookmarkModel )
471 QMap<QString, QMenu *> groupMenus;
472 for (
int i = 0; i < mBookmarkModel->rowCount(); ++i )
475 QMenu *destMenu = mBookmarkMenu;
476 if ( !group.isEmpty() )
478 destMenu = groupMenus.value( group );
481 destMenu =
new QMenu( group, mBookmarkMenu );
482 groupMenus[group] = destMenu;
487 connect( action, &QAction::triggered,
this, [=] {
496 if ( extent.
crs() != mMapItem->crs() )
500 QgsCoordinateTransform xForm( extent.crs(), mMapItem->crs(), QgsProject::instance() );
501 xForm.setBallparkTransformsAreAppropriate( true );
502 newExtent = xForm.transformBoundingBox( newExtent );
511 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Extent" ) );
512 mMapItem->zoomToExtent( newExtent );
513 mMapItem->layout()->undoStack()->endCommand();
515 destMenu->addAction( action );
518 QStringList groupKeys = groupMenus.keys();
519 groupKeys.sort( Qt::CaseInsensitive );
520 for (
int i = 0; i < groupKeys.count(); ++i )
522 if ( mBookmarkMenu->actions().value( i ) )
523 mBookmarkMenu->insertMenu( mBookmarkMenu->actions().at( i ), groupMenus.value( groupKeys.at( i ) ) );
525 mBookmarkMenu->addMenu( groupMenus.value( groupKeys.at( i ) ) );
529void QgsLayoutMapWidget::mTemporalCheckBox_toggled(
bool checked )
536 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Toggle Temporal Range" ) );
537 mMapItem->setIsTemporal( checked );
538 mMapItem->layout()->undoStack()->endCommand();
542 whileBlocking( mStartDateTime )->setDateTime( mMapItem->temporalRange().begin() );
543 whileBlocking( mEndDateTime )->setDateTime( mMapItem->temporalRange().end() );
549void QgsLayoutMapWidget::updateTemporalExtent()
556 const QDateTime begin = mStartDateTime->dateTime();
557 const QDateTime end = mEndDateTime->dateTime();
560 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Set Temporal Range" ) );
561 mMapItem->setTemporalRange( range );
562 mMapItem->layout()->undoStack()->endCommand();
567void QgsLayoutMapWidget::mElevationRangeCheckBox_toggled(
bool checked )
574 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Toggle Z Range" ) );
575 mMapItem->setZRangeEnabled( checked );
576 mMapItem->layout()->undoStack()->endCommand();
581void QgsLayoutMapWidget::updateZRange()
588 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Set Z Range" ) );
589 double zLower = mZLowerSpin->value();
590 if ( zLower == mZLowerSpin->clearValue() )
591 zLower = std::numeric_limits<double>::lowest();
592 double zUpper = mZUpperSpin->value();
593 if ( zUpper == mZUpperSpin->clearValue() )
594 zUpper = std::numeric_limits<double>::max();
597 mMapItem->layout()->undoStack()->endCommand();
602void QgsLayoutMapWidget::mAtlasCheckBox_toggled(
bool checked )
609 mAtlasFixedScaleRadio->setEnabled( checked );
610 mAtlasMarginRadio->setEnabled( checked );
612 if ( mAtlasMarginRadio->isEnabled() && mAtlasMarginRadio->isChecked() )
614 mAtlasMarginSpinBox->setEnabled(
true );
618 mAtlasMarginSpinBox->setEnabled(
false );
621 mAtlasPredefinedScaleRadio->setEnabled( checked );
626 if ( mMapItem->layout() )
628 toggleAtlasScalingOptionsByLayerType();
633 if ( !hasPredefinedScales() )
635 mAtlasPredefinedScaleRadio->setEnabled(
false );
638 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Set Atlas Driven" ) );
639 mMapItem->setAtlasDriven( checked );
640 mMapItem->layout()->undoStack()->endCommand();
644void QgsLayoutMapWidget::updateMapForAtlas()
647 if ( mMapItem->atlasDriven() )
654 mMapItem->invalidateCache();
658void QgsLayoutMapWidget::mAtlasMarginRadio_toggled(
bool checked )
660 mAtlasMarginSpinBox->setEnabled( checked );
662 if ( checked && mMapItem )
664 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Mode" ) );
666 mMapItem->layout()->undoStack()->endCommand();
671void QgsLayoutMapWidget::mAtlasMarginSpinBox_valueChanged(
int value )
679 mMapItem->setAtlasMargin( value / 100. );
680 mMapItem->layout()->undoStack()->endCommand();
684void QgsLayoutMapWidget::mAtlasFixedScaleRadio_toggled(
bool checked )
693 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Mode" ) );
695 mMapItem->layout()->undoStack()->endCommand();
700void QgsLayoutMapWidget::mAtlasPredefinedScaleRadio_toggled(
bool checked )
707 if ( hasPredefinedScales() )
711 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Scales" ) );
713 mMapItem->layout()->undoStack()->endCommand();
721 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Atlas Mode" ) );
723 mMapItem->layout()->undoStack()->endCommand();
727void QgsLayoutMapWidget::mScaleLineEdit_editingFinished()
734 bool conversionSuccess =
false;
735 const double scaleDenominator = QLocale().toDouble( mScaleLineEdit->text(), &conversionSuccess );
736 if ( !conversionSuccess )
744 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Scale" ) );
745 mMapItem->setScale( scaleDenominator );
746 mMapItem->layout()->undoStack()->endCommand();
749void QgsLayoutMapWidget::rotationChanged(
double value )
757 mMapItem->setMapRotation( value );
758 mMapItem->layout()->undoStack()->endCommand();
759 mMapItem->invalidateCache();
762void QgsLayoutMapWidget::setToMapCanvasExtent()
778 xForm.setBallparkTransformsAreAppropriate(
true );
779 newExtent = xForm.transformBoundingBox( newExtent );
788 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Extent" ) );
789 mMapItem->zoomToExtent( newExtent );
790 mMapItem->layout()->undoStack()->endCommand();
793void QgsLayoutMapWidget::setToMapCanvasScale()
800 const double newScale = mMapCanvas->
scale();
802 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Scale" ) );
803 mMapItem->setScale( newScale );
804 mMapItem->layout()->undoStack()->endCommand();
807void QgsLayoutMapWidget::viewExtentInCanvas()
814 const QgsRectangle currentMapExtent = mMapItem->extent();
816 if ( !currentMapExtent.
isEmpty() )
831void QgsLayoutMapWidget::viewScaleInCanvas()
838 const double currentScale = mMapItem->scale();
839 mMapCanvas->
zoomScale( currentScale,
true );
842void QgsLayoutMapWidget::mXMinLineEdit_editingFinished()
844 updateComposerExtentFromGui();
847void QgsLayoutMapWidget::mXMaxLineEdit_editingFinished()
849 updateComposerExtentFromGui();
852void QgsLayoutMapWidget::mYMinLineEdit_editingFinished()
854 updateComposerExtentFromGui();
857void QgsLayoutMapWidget::mYMaxLineEdit_editingFinished()
859 updateComposerExtentFromGui();
862void QgsLayoutMapWidget::updateGuiElements()
869 blockAllSignals(
true );
870 mLabel->setText( mMapItem->displayName() );
872 whileBlocking( mCrsSelector )->setCrs( mMapItem->presetCrs() );
875 const double scale = mMapItem->scale();
878 if ( scale >= 10000 )
881 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 0 ) );
883 else if ( scale >= 10 )
885 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 3 ) );
887 else if ( scale >= 1 )
890 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 4 ) );
895 mScaleLineEdit->setText( QLocale().toString( mMapItem->scale(),
'f', 10 ) );
899 const QgsRectangle composerMapExtent = mMapItem->extent();
900 mXMinLineEdit->setText( QLocale().toString( composerMapExtent.
xMinimum(),
'f', 3 ) );
901 mXMaxLineEdit->setText( QLocale().toString( composerMapExtent.
xMaximum(),
'f', 3 ) );
902 mYMinLineEdit->setText( QLocale().toString( composerMapExtent.
yMinimum(),
'f', 3 ) );
903 mYMaxLineEdit->setText( QLocale().toString( composerMapExtent.
yMaximum(),
'f', 3 ) );
908 mFollowVisibilityPresetCheckBox->setCheckState(
909 mMapItem->followVisibilityPreset() ? Qt::Checked : Qt::Unchecked
911 const int presetModelIndex = mFollowVisibilityPresetCombo->findText( mMapItem->followVisibilityPresetName() );
912 mFollowVisibilityPresetCombo->setCurrentIndex( presetModelIndex != -1 ? presetModelIndex : 0 );
915 if ( mMapItem->keepLayerSet() )
917 mKeepLayerListCheckBox->setCheckState( Qt::Checked );
921 mKeepLayerListCheckBox->setCheckState( Qt::Unchecked );
924 mKeepLayerStylesCheckBox->setEnabled( mMapItem->keepLayerSet() );
925 mKeepLayerStylesCheckBox->setCheckState( mMapItem->keepLayerStyles() ? Qt::Checked : Qt::Unchecked );
928 if ( mMapItem->drawAnnotations() )
930 mDrawCanvasItemsCheckBox->setCheckState( Qt::Checked );
934 mDrawCanvasItemsCheckBox->setCheckState( Qt::Unchecked );
938 mAtlasCheckBox->setChecked( mMapItem->atlasDriven() );
941 mAtlasFixedScaleRadio->setEnabled( mMapItem->atlasDriven() );
944 mAtlasMarginRadio->setEnabled( mMapItem->atlasDriven() );
946 mAtlasPredefinedScaleRadio->setEnabled( mMapItem->atlasDriven() );
949 if ( mMapItem->atlasDriven() )
951 toggleAtlasScalingOptionsByLayerType();
954 if ( !hasPredefinedScales() )
956 mAtlasPredefinedScaleRadio->setEnabled(
false );
959 mTemporalCheckBox->setChecked( mMapItem->isTemporal() );
960 mTemporalCheckBox->setCollapsed( !mMapItem->isTemporal() );
961 mStartDateTime->setEnabled( mMapItem->isTemporal() );
962 mEndDateTime->setEnabled( mMapItem->isTemporal() );
963 if ( mMapItem->isTemporal() )
965 mStartDateTime->setDateTime( mMapItem->temporalRange().begin() );
966 mEndDateTime->setDateTime( mMapItem->temporalRange().end() );
969 whileBlocking( mElevationRangeCheckBox )->setChecked( mMapItem->zRangeEnabled() );
970 mElevationRangeCheckBox->setCollapsed( !mMapItem->zRangeEnabled() );
971 if ( mMapItem->zRange().lower() != std::numeric_limits<double>::lowest() )
972 whileBlocking( mZLowerSpin )->setValue( mMapItem->zRange().lower() );
975 if ( mMapItem->zRange().upper() != std::numeric_limits<double>::max() )
976 whileBlocking( mZUpperSpin )->setValue( mMapItem->zRange().upper() );
982 loadOverviewEntries();
984 blockAllSignals(
false );
987void QgsLayoutMapWidget::toggleAtlasScalingOptionsByLayerType()
1005 mAtlasFixedScaleRadio->setChecked(
true );
1006 mAtlasMarginRadio->setEnabled(
false );
1011 mAtlasMarginRadio->setEnabled(
true );
1015void QgsLayoutMapWidget::updateComposerExtentFromGui()
1022 double xmin, ymin, xmax, ymax;
1023 bool conversionSuccess;
1025 xmin = QLocale().toDouble( mXMinLineEdit->text(), &conversionSuccess );
1026 if ( !conversionSuccess )
1028 xmax = QLocale().toDouble( mXMaxLineEdit->text(), &conversionSuccess );
1029 if ( !conversionSuccess )
1031 ymin = QLocale().toDouble( mYMinLineEdit->text(), &conversionSuccess );
1032 if ( !conversionSuccess )
1034 ymax = QLocale().toDouble( mYMaxLineEdit->text(), &conversionSuccess );
1035 if ( !conversionSuccess )
1038 const QgsRectangle newExtent( xmin, ymin, xmax, ymax );
1040 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Extent" ) );
1041 mMapItem->setExtent( newExtent );
1042 mMapItem->layout()->undoStack()->endCommand();
1045void QgsLayoutMapWidget::blockAllSignals(
bool b )
1047 mScaleLineEdit->blockSignals( b );
1048 mXMinLineEdit->blockSignals( b );
1049 mXMaxLineEdit->blockSignals( b );
1050 mYMinLineEdit->blockSignals( b );
1051 mYMaxLineEdit->blockSignals( b );
1052 mDrawCanvasItemsCheckBox->blockSignals( b );
1053 mOverviewFrameMapComboBox->blockSignals( b );
1054 mOverviewFrameStyleButton->blockSignals( b );
1055 mOverviewBlendModeComboBox->blockSignals( b );
1056 mOverviewInvertCheckbox->blockSignals( b );
1057 mOverviewCenterCheckbox->blockSignals( b );
1058 mAtlasCheckBox->blockSignals( b );
1059 mAtlasMarginSpinBox->blockSignals( b );
1060 mAtlasFixedScaleRadio->blockSignals( b );
1061 mAtlasMarginRadio->blockSignals( b );
1062 mFollowVisibilityPresetCheckBox->blockSignals( b );
1063 mFollowVisibilityPresetCombo->blockSignals( b );
1064 mKeepLayerListCheckBox->blockSignals( b );
1065 mKeepLayerStylesCheckBox->blockSignals( b );
1066 mActionSetToCanvasExtent->blockSignals( b );
1067 mActionUpdatePreview->blockSignals( b );
1068 mTemporalCheckBox->blockSignals( b );
1069 mStartDateTime->blockSignals( b );
1070 mEndDateTime->blockSignals( b );
1072 blockOverviewItemsSignals( b );
1075void QgsLayoutMapWidget::updatePreview()
1081 mMapItem->refresh();
1084void QgsLayoutMapWidget::mFollowVisibilityPresetCheckBox_stateChanged(
int state )
1091 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
1092 if ( state == Qt::Checked )
1094 mMapItem->setFollowVisibilityPreset(
true );
1097 mKeepLayerListCheckBox->setCheckState( Qt::Unchecked );
1098 mKeepLayerStylesCheckBox->setCheckState( Qt::Unchecked );
1100 mMapItem->invalidateCache();
1104 mMapItem->setFollowVisibilityPreset(
false );
1106 mMapItem->layout()->undoStack()->endCommand();
1109void QgsLayoutMapWidget::mKeepLayerListCheckBox_stateChanged(
int state )
1117 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Map Preset Changed" ) );
1118 storeCurrentLayerSet();
1119 mMapItem->setKeepLayerSet( state == Qt::Checked );
1120 if ( state == Qt::Unchecked )
1122 mMapItem->setLayers( QList<QgsMapLayer *>() );
1124 mMapItem->layout()->undoStack()->endCommand();
1127 if ( state == Qt::Checked )
1130 mFollowVisibilityPresetCheckBox->setCheckState( Qt::Unchecked );
1134 mKeepLayerStylesCheckBox->setChecked( Qt::Unchecked );
1135 mMapItem->invalidateCache();
1138 mKeepLayerStylesCheckBox->setEnabled( state == Qt::Checked );
1141void QgsLayoutMapWidget::mKeepLayerStylesCheckBox_stateChanged(
int state )
1148 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Map Preset" ) );
1149 if ( state == Qt::Checked )
1151 mMapItem->storeCurrentLayerStyles();
1152 mMapItem->setKeepLayerStyles(
true );
1156 mMapItem->setLayerStyleOverrides( QMap<QString, QString>() );
1157 mMapItem->setKeepLayerStyles(
false );
1159 mMapItem->layout()->undoStack()->endCommand();
1162void QgsLayoutMapWidget::mDrawCanvasItemsCheckBox_stateChanged(
int state )
1169 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Toggle Map Item" ) );
1170 mMapItem->setDrawAnnotations( state == Qt::Checked );
1171 mMapItem->invalidateCache();
1172 mMapItem->layout()->undoStack()->endCommand();
1175void QgsLayoutMapWidget::atlasLayerChanged(
QgsVectorLayer *layer )
1180 mAtlasCheckBox->setChecked(
false );
1181 mAtlasCheckBox->setEnabled(
false );
1186 mAtlasCheckBox->setEnabled(
true );
1190 if ( mAtlasCheckBox->isChecked() )
1191 toggleAtlasScalingOptionsByLayerType();
1194bool QgsLayoutMapWidget::hasPredefinedScales()
const
1199 if ( !hasProjectScales || scales.isEmpty() )
1204 return !scales.isEmpty() && !scales[0].isEmpty();
1209void QgsLayoutMapWidget::mAddGridPushButton_clicked()
1216 const QString itemName = tr(
"Grid %1" ).arg( mMapItem->grids()->size() + 1 );
1218 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Add Map Grid" ) );
1219 mMapItem->grids()->addGrid( grid );
1220 mMapItem->layout()->undoStack()->endCommand();
1221 mMapItem->updateBoundingRect();
1224 addGridListItem( grid->
id(), grid->
name() );
1225 mGridListWidget->setCurrentRow( 0 );
1226 mGridListWidget_currentItemChanged( mGridListWidget->currentItem(),
nullptr );
1229void QgsLayoutMapWidget::mRemoveGridPushButton_clicked()
1231 QListWidgetItem *item = mGridListWidget->currentItem();
1237 mMapItem->beginCommand( tr(
"Remove Grid" ) );
1238 mMapItem->grids()->removeGrid( item->data( Qt::UserRole ).toString() );
1239 QListWidgetItem *delItem = mGridListWidget->takeItem( mGridListWidget->row( item ) );
1241 mMapItem->endCommand();
1242 mMapItem->updateBoundingRect();
1246void QgsLayoutMapWidget::mCopyGridPushButton_clicked()
1248 QListWidgetItem *item = mGridListWidget->currentItem();
1254 QgsLayoutItemMapGrid *sourceGrid = mMapItem->grids()->grid( item->data( Qt::UserRole ).toString() );
1260 QString itemName = tr(
"%1 - Copy" ).arg( sourceGrid->
name() );
1261 QList<QgsLayoutItemMapGrid *> grids = mMapItem->grids()->asList();
1264 const auto it = std::find_if( grids.begin(), grids.end(), [&itemName](
const QgsLayoutItemMapGrid *grd ) { return grd->name() == itemName; } );
1265 if ( it != grids.end() )
1268 itemName = tr(
"%1 - Copy %2" ).arg( sourceGrid->
name() ).arg( i );
1276 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Duplicate Map Grid" ) );
1277 mMapItem->grids()->addGrid( grid );
1278 mMapItem->layout()->undoStack()->endCommand();
1279 mMapItem->updateBoundingRect();
1282 addGridListItem( grid->
id(), grid->
name() );
1283 mGridListWidget->setCurrentRow( 0 );
1284 mGridListWidget_currentItemChanged( mGridListWidget->currentItem(),
nullptr );
1287void QgsLayoutMapWidget::mGridUpButton_clicked()
1289 QListWidgetItem *item = mGridListWidget->currentItem();
1295 const int row = mGridListWidget->row( item );
1300 mGridListWidget->takeItem( row );
1301 mGridListWidget->insertItem( row - 1, item );
1302 mGridListWidget->setCurrentItem( item );
1303 mMapItem->beginCommand( tr(
"Move Grid Up" ) );
1304 mMapItem->grids()->moveGridUp( item->data( Qt::UserRole ).toString() );
1305 mMapItem->endCommand();
1309void QgsLayoutMapWidget::mGridDownButton_clicked()
1311 QListWidgetItem *item = mGridListWidget->currentItem();
1317 const int row = mGridListWidget->row( item );
1318 if ( mGridListWidget->count() <= row )
1322 mGridListWidget->takeItem( row );
1323 mGridListWidget->insertItem( row + 1, item );
1324 mGridListWidget->setCurrentItem( item );
1325 mMapItem->beginCommand( tr(
"Move Grid Down" ) );
1326 mMapItem->grids()->moveGridDown( item->data( Qt::UserRole ).toString() );
1327 mMapItem->endCommand();
1338 QListWidgetItem *item = mGridListWidget->currentItem();
1343 return mMapItem->grids()->grid( item->data( Qt::UserRole ).toString() );
1346void QgsLayoutMapWidget::mGridListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem * )
1348 mGridPropertiesButton->setEnabled(
static_cast<bool>( current ) );
1351void QgsLayoutMapWidget::mGridListWidget_itemChanged( QListWidgetItem *item )
1364 mMapItem->beginCommand( tr(
"Rename Grid" ) );
1365 grid->
setName( item->text() );
1366 mMapItem->endCommand();
1369void QgsLayoutMapWidget::mGridPropertiesButton_clicked()
1386QListWidgetItem *QgsLayoutMapWidget::addGridListItem(
const QString &
id,
const QString &name )
1388 QListWidgetItem *item =
new QListWidgetItem( name,
nullptr );
1389 item->setData( Qt::UserRole,
id );
1390 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
1391 mGridListWidget->insertItem( 0, item );
1395void QgsLayoutMapWidget::loadGridEntries()
1398 QSet<QString> selectedIds;
1399 const QList<QListWidgetItem *> itemSelection = mGridListWidget->selectedItems();
1400 QList<QListWidgetItem *>::const_iterator sIt = itemSelection.constBegin();
1401 for ( ; sIt != itemSelection.constEnd(); ++sIt )
1403 selectedIds.insert( ( *sIt )->data( Qt::UserRole ).toString() );
1406 mGridListWidget->clear();
1412 const QList<QgsLayoutItemMapGrid *> grids = mMapItem->grids()->asList();
1413 QList<QgsLayoutItemMapGrid *>::const_iterator gridIt = grids.constBegin();
1414 for ( ; gridIt != grids.constEnd(); ++gridIt )
1416 QListWidgetItem *item = addGridListItem( ( *gridIt )->id(), ( *gridIt )->name() );
1417 if ( selectedIds.contains( ( *gridIt )->id() ) )
1419 item->setSelected(
true );
1420 mGridListWidget->setCurrentItem( item );
1424 if ( mGridListWidget->currentItem() )
1426 mGridListWidget_currentItemChanged( mGridListWidget->currentItem(),
nullptr );
1430 mGridListWidget_currentItemChanged(
nullptr,
nullptr );
1434void QgsLayoutMapWidget::mAddOverviewPushButton_clicked()
1441 const QString itemName = tr(
"Overview %1" ).arg( mMapItem->overviews()->size() + 1 );
1443 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Add Map Overview" ) );
1444 mMapItem->overviews()->addOverview( overview );
1445 mMapItem->layout()->undoStack()->endCommand();
1446 mMapItem->invalidateCache();
1448 addOverviewListItem( overview->
id(), overview->
name() );
1450 mOverviewListWidget->setCurrentRow( 0 );
1453void QgsLayoutMapWidget::mRemoveOverviewPushButton_clicked()
1455 QListWidgetItem *item = mOverviewListWidget->currentItem();
1460 mMapItem->beginCommand( tr(
"Remove Map Overview" ) );
1461 mMapItem->overviews()->removeOverview( item->data( Qt::UserRole ).toString() );
1462 mMapItem->endCommand();
1463 QListWidgetItem *delItem = mOverviewListWidget->takeItem( mOverviewListWidget->row( item ) );
1465 mMapItem->invalidateCache();
1468void QgsLayoutMapWidget::mOverviewUpButton_clicked()
1470 QListWidgetItem *item = mOverviewListWidget->currentItem();
1476 const int row = mOverviewListWidget->row( item );
1481 mOverviewListWidget->takeItem( row );
1482 mOverviewListWidget->insertItem( row - 1, item );
1483 mOverviewListWidget->setCurrentItem( item );
1484 mMapItem->beginCommand( tr(
"Move Overview Up" ) );
1485 mMapItem->overviews()->moveOverviewUp( item->data( Qt::UserRole ).toString() );
1486 mMapItem->endCommand();
1487 mMapItem->invalidateCache();
1490void QgsLayoutMapWidget::mOverviewDownButton_clicked()
1492 QListWidgetItem *item = mOverviewListWidget->currentItem();
1498 const int row = mOverviewListWidget->row( item );
1499 if ( mOverviewListWidget->count() <= row )
1503 mOverviewListWidget->takeItem( row );
1504 mOverviewListWidget->insertItem( row + 1, item );
1505 mOverviewListWidget->setCurrentItem( item );
1506 mMapItem->beginCommand( tr(
"Move Overview Down" ) );
1507 mMapItem->overviews()->moveOverviewDown( item->data( Qt::UserRole ).toString() );
1508 mMapItem->endCommand();
1509 mMapItem->invalidateCache();
1519 QListWidgetItem *item = mOverviewListWidget->currentItem();
1525 return mMapItem->overviews()->overview( item->data( Qt::UserRole ).toString() );
1528void QgsLayoutMapWidget::mOverviewListWidget_currentItemChanged( QListWidgetItem *current, QListWidgetItem *previous )
1530 Q_UNUSED( previous )
1533 mOverviewCheckBox->setEnabled(
false );
1537 mOverviewCheckBox->setEnabled(
true );
1538 setOverviewItems( mMapItem->overviews()->overview( current->data( Qt::UserRole ).toString() ) );
1541void QgsLayoutMapWidget::mOverviewListWidget_itemChanged( QListWidgetItem *item )
1554 mMapItem->beginCommand( QStringLiteral(
"Rename Overview" ) );
1555 overview->
setName( item->text() );
1556 mMapItem->endCommand();
1557 if ( item->isSelected() )
1560 mOverviewCheckBox->setTitle( tr(
"Draw \"%1\" overview" ).arg( overview->
name() ) );
1564void QgsLayoutMapWidget::setOverviewItemsEnabled(
bool enabled )
1566 mOverviewFrameMapLabel->setEnabled( enabled );
1567 mOverviewFrameMapComboBox->setEnabled( enabled );
1568 mOverviewFrameStyleLabel->setEnabled( enabled );
1569 mOverviewFrameStyleButton->setEnabled( enabled );
1570 mOverviewBlendModeLabel->setEnabled( enabled );
1571 mOverviewBlendModeComboBox->setEnabled( enabled );
1572 mOverviewInvertCheckbox->setEnabled( enabled );
1573 mOverviewCenterCheckbox->setEnabled( enabled );
1574 mOverviewPositionComboBox->setEnabled( enabled );
1580void QgsLayoutMapWidget::blockOverviewItemsSignals(
const bool block )
1582 mOverviewFrameMapComboBox->blockSignals( block );
1583 mOverviewFrameStyleButton->blockSignals( block );
1584 mOverviewBlendModeComboBox->blockSignals( block );
1585 mOverviewInvertCheckbox->blockSignals( block );
1586 mOverviewCenterCheckbox->blockSignals( block );
1587 mOverviewPositionComboBox->blockSignals( block );
1588 mOverviewStackingLayerComboBox->blockSignals( block );
1598 blockOverviewItemsSignals(
true );
1600 mOverviewCheckBox->setTitle( tr(
"Draw \"%1\" overview" ).arg( overview->
name() ) );
1601 mOverviewCheckBox->setChecked( overview->
enabled() );
1604 mOverviewFrameMapComboBox->setItem( overview->
linkedMap() );
1607 mOverviewBlendModeComboBox->setBlendMode( overview->
blendMode() );
1609 mOverviewInvertCheckbox->setChecked( overview->
inverted() );
1611 mOverviewCenterCheckbox->setChecked( overview->
centered() );
1613 mOverviewPositionComboBox->setCurrentIndex( mOverviewPositionComboBox->findData( overview->
stackingPosition() ) );
1614 mOverviewStackingLayerComboBox->setLayer( overview->
stackingLayer() );
1619 blockOverviewItemsSignals(
false );
1622void QgsLayoutMapWidget::storeCurrentLayerSet()
1629 mMapItem->setLayers( layers );
1631 if ( mMapItem->keepLayerStyles() )
1634 mMapItem->storeCurrentLayerStyles();
1638QList<QgsMapLayer *> QgsLayoutMapWidget::orderedPresetVisibleLayers(
const QString &name )
const
1643 QList<QgsMapLayer *> lst;
1647 if ( visibleIds.contains( layer->
id() ) )
1655QListWidgetItem *QgsLayoutMapWidget::addOverviewListItem(
const QString &
id,
const QString &name )
1657 QListWidgetItem *item =
new QListWidgetItem( name,
nullptr );
1658 item->setData( Qt::UserRole,
id );
1659 item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
1660 mOverviewListWidget->insertItem( 0, item );
1664void QgsLayoutMapWidget::loadOverviewEntries()
1667 QSet<QString> selectedIds;
1668 const QList<QListWidgetItem *> itemSelection = mOverviewListWidget->selectedItems();
1669 QList<QListWidgetItem *>::const_iterator sIt = itemSelection.constBegin();
1670 for ( ; sIt != itemSelection.constEnd(); ++sIt )
1672 selectedIds.insert( ( *sIt )->data( Qt::UserRole ).toString() );
1675 mOverviewListWidget->clear();
1681 mOverviewFrameMapComboBox->setExceptedItemList( QList<QgsLayoutItem *>() << mMapItem );
1684 const QList<QgsLayoutItemMapOverview *> overviews = mMapItem->overviews()->asList();
1685 QList<QgsLayoutItemMapOverview *>::const_iterator overviewIt = overviews.constBegin();
1686 for ( ; overviewIt != overviews.constEnd(); ++overviewIt )
1688 QListWidgetItem *item = addOverviewListItem( ( *overviewIt )->id(), ( *overviewIt )->name() );
1689 if ( selectedIds.contains( ( *overviewIt )->id() ) )
1691 item->setSelected(
true );
1692 mOverviewListWidget->setCurrentItem( item );
1696 if ( mOverviewListWidget->currentItem() )
1698 mOverviewListWidget_currentItemChanged( mOverviewListWidget->currentItem(),
nullptr );
1702 mOverviewListWidget_currentItemChanged(
nullptr,
nullptr );
1706void QgsLayoutMapWidget::mOverviewCheckBox_toggled(
bool state )
1714 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Overview Display Toggled" ) );
1716 mMapItem->invalidateCache();
1717 mMapItem->layout()->undoStack()->endCommand();
1720void QgsLayoutMapWidget::overviewMapChanged(
QgsLayoutItem *item )
1732 mMapItem->beginCommand( tr(
"Change Overview Map" ) );
1734 mMapItem->invalidateCache();
1735 mMapItem->endCommand();
1738void QgsLayoutMapWidget::mOverviewBlendModeComboBox_currentIndexChanged(
int index )
1747 mMapItem->beginCommand( tr(
"Change Overview Blend Mode" ) );
1748 overview->
setBlendMode( mOverviewBlendModeComboBox->blendMode() );
1749 mMapItem->invalidateCache();
1750 mMapItem->endCommand();
1753void QgsLayoutMapWidget::mOverviewInvertCheckbox_toggled(
bool state )
1761 mMapItem->beginCommand( tr(
"Toggle Overview Inverted" ) );
1763 mMapItem->invalidateCache();
1764 mMapItem->endCommand();
1767void QgsLayoutMapWidget::mOverviewCenterCheckbox_toggled(
bool state )
1775 mMapItem->beginCommand( tr(
"Toggle Overview Centered" ) );
1777 mMapItem->invalidateCache();
1778 mMapItem->endCommand();
1781void QgsLayoutMapWidget::overviewStackingChanged(
int )
1789 mMapItem->beginCommand( tr(
"Change Overview Position" ) );
1791 mMapItem->invalidateCache();
1792 mMapItem->endCommand();
1799 mOverviewStackingLayerComboBox->setEnabled(
false );
1804 mOverviewStackingLayerComboBox->setEnabled(
true );
1809void QgsLayoutMapWidget::overviewStackingLayerChanged(
QgsMapLayer *layer )
1817 mMapItem->beginCommand( tr(
"Change Overview Position" ) );
1819 mMapItem->invalidateCache();
1820 mMapItem->endCommand();
1834 mLabelBoundarySpinBox->setClearValue( 0 );
1835 mLabelBoundarySpinBox->setShowClearButton(
true );
1837 mLabelBoundaryUnitsCombo->linkToWidget( mLabelBoundarySpinBox );
1838 mLabelBoundaryUnitsCombo->setConverter( &mMapItem->layout()->renderContext().measurementConverter() );
1841 connect( mLabelBoundarySpinBox,
static_cast<void ( QDoubleSpinBox::* )(
double )
>( &QDoubleSpinBox::valueChanged ),
this, &QgsLayoutMapLabelingWidget::labelMarginChanged );
1842 connect( mShowPartialLabelsCheckBox, &QCheckBox::toggled,
this, &QgsLayoutMapLabelingWidget::showPartialsToggled );
1843 connect( mShowUnplacedCheckBox, &QCheckBox::toggled,
this, &QgsLayoutMapLabelingWidget::showUnplacedToggled );
1860 mMapItem = qobject_cast<QgsLayoutItemMap *>( item );
1867 updateGuiElements();
1872void QgsLayoutMapLabelingWidget::updateGuiElements()
1874 whileBlocking( mLabelBoundarySpinBox )->setValue( mMapItem->labelMargin().length() );
1875 whileBlocking( mLabelBoundaryUnitsCombo )->setUnit( mMapItem->labelMargin().units() );
1879 if ( mBlockingItemsListView->model() )
1881 QAbstractItemModel *oldModel = mBlockingItemsListView->model();
1882 mBlockingItemsListView->setModel(
nullptr );
1883 oldModel->deleteLater();
1887 mBlockingItemsListView->setModel( model );
1892void QgsLayoutMapLabelingWidget::labelMarginChanged(
double val )
1899 mMapItem->layout()->undoStack()->endCommand();
1900 mMapItem->invalidateCache();
1903void QgsLayoutMapLabelingWidget::labelMarginUnitsChanged()
1909 mMapItem->setLabelMargin(
QgsLayoutMeasurement( mLabelBoundarySpinBox->value(), mLabelBoundaryUnitsCombo->unit() ) );
1910 mMapItem->layout()->undoStack()->endCommand();
1911 mMapItem->invalidateCache();
1914void QgsLayoutMapLabelingWidget::showPartialsToggled(
bool checked )
1919 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Label Visibility" ) );
1925 mMapItem->setMapFlags( flags );
1926 mMapItem->layout()->undoStack()->endCommand();
1927 mMapItem->invalidateCache();
1930void QgsLayoutMapLabelingWidget::showUnplacedToggled(
bool checked )
1935 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Label Visibility" ) );
1941 mMapItem->setMapFlags( flags );
1942 mMapItem->layout()->undoStack()->endCommand();
1943 mMapItem->invalidateCache();
1947 : QSortFilterProxyModel( parent )
1948 , mLayoutModel( layoutModel )
1951 setSourceModel( layoutModel );
1964 if ( i.column() != 0 )
1977 case Qt::CheckStateRole:
1978 switch ( i.column() )
1981 return mMapItem ? ( mMapItem->isLabelBlockingItem( item ) ? Qt::Checked : Qt::Unchecked ) : Qt::Unchecked;
1987 return mLayoutModel->
data( sourceIndex, role );
1995 if ( !index.isValid() )
1999 if ( !item || !mMapItem )
2004 mMapItem->layout()->undoStack()->beginCommand( mMapItem, tr(
"Change Label Blocking Items" ) );
2006 if ( value.toBool() )
2008 mMapItem->addLabelBlockingItem( item );
2012 mMapItem->removeLabelBlockingItem( item );
2014 emit dataChanged( index, index, QVector<int>() << role );
2016 mMapItem->layout()->undoStack()->endCommand();
2017 mMapItem->invalidateCache();
2024 Qt::ItemFlags
flags = QSortFilterProxyModel::flags( index );
2026 if ( !index.isValid() )
2031 switch ( index.column() )
2034 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
2036 return flags | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
2043 if ( !item || item == mMapItem )
2065 mLayersTreeView->setModel( mLayerModel );
2071 for (
int i = 0; i < mAtlasClippingTypeComboBox->count(); ++i )
2073 mItemClippingTypeComboBox->addItem( mAtlasClippingTypeComboBox->itemText( i ), mAtlasClippingTypeComboBox->itemData( i ) );
2076 mClipItemComboBox->setCurrentLayout( map->
layout() );
2079 connect( mRadioClipSelectedLayers, &QRadioButton::toggled,
this, &QgsLayoutMapClippingWidget::toggleLayersSelectionGui );
2080 mLayersTreeView->setEnabled(
false );
2081 mSelectAllButton->setEnabled(
false );
2082 mDeselectAllButton->setEnabled(
false );
2083 mInvertSelectionButton->setEnabled(
false );
2084 mRadioClipAllLayers->setChecked(
true );
2086 connect( mClipToAtlasCheckBox, &QGroupBox::toggled,
this, [=](
bool active ) {
2087 if ( !mBlockUpdates )
2089 mMapItem->beginCommand( tr(
"Toggle Atlas Clipping" ) );
2090 mMapItem->atlasClippingSettings()->setEnabled( active );
2091 mMapItem->endCommand();
2094 connect( mForceLabelsInsideCheckBox, &QCheckBox::toggled,
this, [=](
bool active ) {
2095 if ( !mBlockUpdates )
2097 mMapItem->beginCommand( tr(
"Change Atlas Clipping Label Behavior" ) );
2098 mMapItem->atlasClippingSettings()->setForceLabelsInsideFeature( active );
2099 mMapItem->endCommand();
2102 connect( mAtlasClippingTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=] {
2103 if ( !mBlockUpdates )
2105 mMapItem->beginCommand( tr(
"Change Atlas Clipping Behavior" ) );
2107 mMapItem->endCommand();
2111 connect( mRadioClipSelectedLayers, &QCheckBox::toggled,
this, [=](
bool active ) {
2112 if ( active && !mBlockUpdates )
2114 mBlockUpdates =
true;
2115 mMapItem->beginCommand( tr(
"Change Atlas Clipping Layers" ) );
2116 mMapItem->atlasClippingSettings()->setRestrictToLayers(
true );
2117 mMapItem->endCommand();
2118 mBlockUpdates =
false;
2122 connect( mSelectAllButton, &QPushButton::clicked,
this, &QgsLayoutMapClippingWidget::selectAll );
2123 connect( mDeselectAllButton, &QPushButton::clicked,
this, &QgsLayoutMapClippingWidget::deselectAll );
2124 connect( mInvertSelectionButton, &QPushButton::clicked,
this, &QgsLayoutMapClippingWidget::invertSelection );
2126 connect( mRadioClipAllLayers, &QCheckBox::toggled,
this, [=](
bool active ) {
2127 if ( active && !mBlockUpdates )
2129 mBlockUpdates =
true;
2130 mMapItem->beginCommand( tr(
"Change Atlas Clipping Layers" ) );
2131 mMapItem->atlasClippingSettings()->setRestrictToLayers(
false );
2132 mMapItem->endCommand();
2133 mBlockUpdates =
false;
2136 connect( mLayerModel, &QgsMapLayerModel::dataChanged,
this, [=](
const QModelIndex &,
const QModelIndex &,
const QVector<int> &roles = QVector<int>() ) {
2137 if ( !roles.contains( Qt::CheckStateRole ) )
2140 if ( !mBlockUpdates )
2142 mBlockUpdates =
true;
2143 mMapItem->beginCommand( tr(
"Change Atlas Clipping Layers" ) );
2144 mMapItem->atlasClippingSettings()->setLayersToClip( mLayerModel->
layersChecked() );
2145 mMapItem->endCommand();
2146 mBlockUpdates =
false;
2152 connect( mClipToItemCheckBox, &QGroupBox::toggled,
this, [=](
bool active ) {
2153 if ( !mBlockUpdates )
2155 mMapItem->beginCommand( tr(
"Toggle Map Clipping" ) );
2156 mMapItem->itemClippingSettings()->setEnabled( active );
2157 mMapItem->endCommand();
2160 connect( mItemClippingTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=] {
2161 if ( !mBlockUpdates )
2163 mMapItem->beginCommand( tr(
"Change Map Clipping Behavior" ) );
2165 mMapItem->endCommand();
2168 connect( mForceLabelsInsideItemCheckBox, &QCheckBox::toggled,
this, [=](
bool active ) {
2169 if ( !mBlockUpdates )
2171 mMapItem->beginCommand( tr(
"Change Map Clipping Label Behavior" ) );
2172 mMapItem->itemClippingSettings()->setForceLabelsInsideClipPath( active );
2173 mMapItem->endCommand();
2177 if ( !mBlockUpdates )
2179 mMapItem->beginCommand( tr(
"Change Map Clipping Item" ) );
2180 mMapItem->itemClippingSettings()->setSourceItem( item );
2181 mMapItem->endCommand();
2191 atlasToggled( atlas->enabled() );
2197 mClipToAtlasCheckBox->setTitle( tr(
"Clip to %1 feature" ).arg(
string ) );
2198 mClipToAtlasLabel->setText( tr(
"<b>When enabled, map layers will be automatically clipped to the boundary of the current %1 feature.</b>" ).arg(
string ) );
2199 mForceLabelsInsideCheckBox->setText( tr(
"Force labels inside %1 feature" ).arg(
string ) );
2212 mMapItem = qobject_cast<QgsLayoutItemMap *>( item );
2219 updateGuiElements();
2224void QgsLayoutMapClippingWidget::updateGuiElements()
2226 if ( mBlockUpdates )
2229 mBlockUpdates =
true;
2230 mClipToAtlasCheckBox->setChecked( mMapItem->atlasClippingSettings()->enabled() );
2231 mAtlasClippingTypeComboBox->setCurrentIndex( mAtlasClippingTypeComboBox->findData(
static_cast<int>( mMapItem->atlasClippingSettings()->featureClippingType() ) ) );
2232 mForceLabelsInsideCheckBox->setChecked( mMapItem->atlasClippingSettings()->forceLabelsInsideFeature() );
2234 mRadioClipAllLayers->setChecked( !mMapItem->atlasClippingSettings()->restrictToLayers() );
2235 mRadioClipSelectedLayers->setChecked( mMapItem->atlasClippingSettings()->restrictToLayers() );
2236 mLayerModel->
setLayersChecked( mMapItem->atlasClippingSettings()->layersToClip() );
2238 mClipToItemCheckBox->setChecked( mMapItem->itemClippingSettings()->enabled() );
2239 mItemClippingTypeComboBox->setCurrentIndex( mItemClippingTypeComboBox->findData(
static_cast<int>( mMapItem->itemClippingSettings()->featureClippingType() ) ) );
2240 mForceLabelsInsideItemCheckBox->setChecked( mMapItem->itemClippingSettings()->forceLabelsInsideClipPath() );
2241 mClipItemComboBox->setItem( mMapItem->itemClippingSettings()->sourceItem() );
2243 mBlockUpdates =
false;
2246void QgsLayoutMapClippingWidget::atlasLayerChanged(
QgsVectorLayer *layer )
2251 mClipToAtlasCheckBox->setChecked(
false );
2252 mClipToAtlasCheckBox->setEnabled(
false );
2257 mClipToAtlasCheckBox->setEnabled(
true );
2261void QgsLayoutMapClippingWidget::atlasToggled(
bool atlasEnabled )
2263 if ( atlasEnabled && mMapItem && mMapItem->layout() && mMapItem->layout()->reportContext().layer()
2266 mClipToAtlasCheckBox->setEnabled(
true );
2270 mClipToAtlasCheckBox->setEnabled(
false );
2271 mClipToAtlasCheckBox->setChecked(
false );
2275void QgsLayoutMapClippingWidget::invertSelection()
2277 for (
int i = 0; i < mLayerModel->
rowCount( QModelIndex() ); i++ )
2279 QModelIndex index = mLayerModel->
index( i, 0 );
2280 Qt::CheckState currentState = Qt::CheckState( mLayerModel->
data( index, Qt::CheckStateRole ).toInt() );
2281 Qt::CheckState newState = ( currentState == Qt::Checked ) ? Qt::Unchecked : Qt::Checked;
2282 mLayerModel->
setData( index, newState, Qt::CheckStateRole );
2286void QgsLayoutMapClippingWidget::selectAll()
2288 for (
int i = 0; i < mLayerModel->
rowCount( QModelIndex() ); i++ )
2290 QModelIndex index = mLayerModel->
index( i, 0 );
2291 mLayerModel->
setData( index, Qt::Checked, Qt::CheckStateRole );
2295void QgsLayoutMapClippingWidget::deselectAll()
2297 for (
int i = 0; i < mLayerModel->
rowCount( QModelIndex() ); i++ )
2299 QModelIndex index = mLayerModel->
index( i, 0 );
2300 mLayerModel->
setData( index, Qt::Unchecked, Qt::CheckStateRole );
2304void QgsLayoutMapClippingWidget::toggleLayersSelectionGui(
bool toggled )
2306 mLayersTreeView->setEnabled( toggled );
2307 mSelectAllButton->setEnabled( toggled );
2308 mDeselectAllButton->setEnabled( toggled );
2309 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.
@ MinimumValue
Reset value to minimum()
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 enabled)
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.
void copyProperties(const QgsLayoutItemMapGrid *other)
Copies properties from specified map grid.
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.
@ StartDateTime
Temporal range's start DateTime.
@ MapLayers
Map layer set.
@ MapZRangeLower
Map frame Z-range lower value.
@ 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)
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)
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.
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.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
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.
A rectangle specified with double values.
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