18#include <QImageWriter>
21#include "moc_qgslayoutatlaswidget.cpp"
33 , mAtlas( layout->atlas() )
36 connect( mUseAtlasCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mUseAtlasCheckBox_stateChanged );
37 connect( mAtlasFilenamePatternEdit, &QLineEdit::editingFinished,
this, &QgsLayoutAtlasWidget::mAtlasFilenamePatternEdit_editingFinished );
38 connect( mAtlasFilenameExpressionButton, &QToolButton::clicked,
this, &QgsLayoutAtlasWidget::mAtlasFilenameExpressionButton_clicked );
39 connect( mAtlasLimitCoverageLayerRenderCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasLimitCoverageLayerRenderCheckBox_stateChanged );
40 connect( mAtlasHideCoverageCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasHideCoverageCheckBox_stateChanged );
41 connect( mAtlasSingleFileCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasSingleFileCheckBox_stateChanged );
42 connect( mAtlasSortFeatureCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasSortFeatureCheckBox_stateChanged );
43 connect( mAtlasSortFeatureDirectionButton, &QToolButton::clicked,
this, &QgsLayoutAtlasWidget::mAtlasSortFeatureDirectionButton_clicked );
44 connect( mAtlasFeatureFilterEdit, &QLineEdit::editingFinished,
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterEdit_editingFinished );
45 connect( mAtlasFeatureFilterButton, &QToolButton::clicked,
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterButton_clicked );
46 connect( mAtlasFeatureFilterCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterCheckBox_stateChanged );
57 mAtlasSortFeatureDirectionButton->setEnabled(
false );
58 mAtlasSortExpressionWidget->setEnabled(
false );
63 mPageNameWidget->registerExpressionContextGenerator( mLayout );
65 const QList<QByteArray> formats = QImageWriter::supportedImageFormats();
66 for (
int i = 0; i < formats.size(); ++i )
68 mAtlasFileFormat->addItem( QString( formats.at( i ) ) );
70 connect( mAtlasFileFormat, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [
this](
int ) { changeFileFormat(); } );
80void QgsLayoutAtlasWidget::mUseAtlasCheckBox_stateChanged(
int state )
82 if ( state == Qt::Checked )
85 mConfigurationGroup->setEnabled(
true );
86 mOutputGroup->setEnabled(
true );
91 mConfigurationGroup->setEnabled(
false );
92 mOutputGroup->setEnabled(
false );
96void QgsLayoutAtlasWidget::changeCoverageLayer(
QgsMapLayer *layer )
104 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Layer" ) );
105 mLayout->reportContext().setLayer( vl );
113 updateAtlasFeatures();
119 if ( exp.prepare( &context ) && !exp.hasParserError() )
128 mLayout->undoStack()->endCommand();
131void QgsLayoutAtlasWidget::mAtlasFilenamePatternEdit_editingFinished()
137 mBlockUpdates =
true;
138 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filename" ) );
142 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filename expression to '%1'.\nParser error:\n%2" ).arg( mAtlasFilenamePatternEdit->text(), error ) );
144 mLayout->undoStack()->endCommand();
145 mBlockUpdates =
false;
148void QgsLayoutAtlasWidget::mAtlasFilenameExpressionButton_clicked()
157 exprDlg.setWindowTitle( tr(
"Expression Based Filename" ) );
159 if ( exprDlg.exec() == QDialog::Accepted )
161 const QString expression = exprDlg.expressionText();
162 if ( !expression.isEmpty() )
165 mAtlasFilenamePatternEdit->setText( expression );
167 mBlockUpdates =
true;
168 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filename" ) );
172 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filename expression to '%1'.\nParser error:\n%2" ).arg( expression, error ) );
174 mBlockUpdates =
false;
175 mLayout->undoStack()->endCommand();
180void QgsLayoutAtlasWidget::mAtlasLimitCoverageLayerRenderCheckBox_stateChanged(
int state )
185 mBlockUpdates =
true;
186 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Toggle Limit Atlas Layer Rendering to Current Feature" ) );
188 mLayout->undoStack()->endCommand();
189 mBlockUpdates =
false;
192void QgsLayoutAtlasWidget::mAtlasHideCoverageCheckBox_stateChanged(
int state )
197 mBlockUpdates =
true;
198 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Toggle Atlas Layer Visibility" ) );
200 mLayout->undoStack()->endCommand();
201 mBlockUpdates =
false;
203 mAtlasLimitCoverageLayerRenderCheckBox->setEnabled( state != Qt::Checked );
206void QgsLayoutAtlasWidget::mAtlasSingleFileCheckBox_stateChanged(
int state )
211 if ( state == Qt::Checked )
213 mAtlasFilenamePatternEdit->setEnabled(
false );
214 mAtlasFilenameExpressionButton->setEnabled(
false );
218 mAtlasFilenamePatternEdit->setEnabled(
true );
219 mAtlasFilenameExpressionButton->setEnabled(
true );
222 mLayout->setCustomProperty( QStringLiteral(
"singleFile" ), state == Qt::Checked );
225void QgsLayoutAtlasWidget::mAtlasSortFeatureCheckBox_stateChanged(
int state )
230 if ( state == Qt::Checked )
232 mAtlasSortFeatureDirectionButton->setEnabled(
true );
233 mAtlasSortExpressionWidget->setEnabled(
true );
237 mAtlasSortFeatureDirectionButton->setEnabled(
false );
238 mAtlasSortExpressionWidget->setEnabled(
false );
240 mBlockUpdates =
true;
241 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Toggle Atlas Sorting" ) );
243 mLayout->undoStack()->endCommand();
244 mBlockUpdates =
false;
245 updateAtlasFeatures();
248void QgsLayoutAtlasWidget::changesSortFeatureExpression(
const QString &expression,
bool )
253 mBlockUpdates =
true;
254 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Sort" ) );
255 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mAtlasCoverageLayerComboBox->currentLayer() );
257 mLayout->undoStack()->endCommand();
258 mBlockUpdates =
false;
259 updateAtlasFeatures();
262void QgsLayoutAtlasWidget::updateAtlasFeatures()
267 mMessageBar->
pushInfo( tr(
"Atlas" ), tr(
"No matching atlas features found!" ) );
274void QgsLayoutAtlasWidget::mAtlasFeatureFilterCheckBox_stateChanged(
int state )
279 if ( state == Qt::Checked )
281 mAtlasFeatureFilterEdit->setEnabled(
true );
282 mAtlasFeatureFilterButton->setEnabled(
true );
286 mAtlasFeatureFilterEdit->setEnabled(
false );
287 mAtlasFeatureFilterButton->setEnabled(
false );
289 mBlockUpdates =
true;
290 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filter" ) );
292 mLayout->undoStack()->endCommand();
293 mBlockUpdates =
false;
294 updateAtlasFeatures();
297void QgsLayoutAtlasWidget::pageNameExpressionChanged(
const QString &,
bool valid )
302 const QString expression = mPageNameWidget->asExpression();
303 if ( !valid && !expression.isEmpty() )
308 mBlockUpdates =
true;
309 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Name" ) );
311 mLayout->undoStack()->endCommand();
312 mBlockUpdates =
false;
315void QgsLayoutAtlasWidget::mAtlasFeatureFilterEdit_editingFinished()
321 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filter" ) );
323 mBlockUpdates =
true;
327 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filter expression to '%1'.\nParser error:\n%2" ).arg( mAtlasFeatureFilterEdit->text(), error ) );
329 mBlockUpdates =
false;
330 mLayout->undoStack()->endCommand();
331 updateAtlasFeatures();
334void QgsLayoutAtlasWidget::mAtlasFeatureFilterButton_clicked()
339 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mAtlasCoverageLayerComboBox->currentLayer() );
348 exprDlg.setWindowTitle( tr(
"Expression Based Filter" ) );
350 if ( exprDlg.exec() == QDialog::Accepted )
352 const QString expression = exprDlg.expressionText();
353 if ( !expression.isEmpty() )
355 mAtlasFeatureFilterEdit->setText( expression );
357 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filter" ) );
358 mBlockUpdates =
true;
362 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filter expression to '%1'.\nParser error:\n%2" ).arg( mAtlasFeatureFilterEdit->text(), error ) );
364 mBlockUpdates =
false;
365 mLayout->undoStack()->endCommand();
366 updateAtlasFeatures();
371void QgsLayoutAtlasWidget::mAtlasSortFeatureDirectionButton_clicked()
376 Qt::ArrowType at = mAtlasSortFeatureDirectionButton->arrowType();
377 at = ( at == Qt::UpArrow ) ? Qt::DownArrow : Qt::UpArrow;
378 mAtlasSortFeatureDirectionButton->setArrowType( at );
380 mBlockUpdates =
true;
381 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Sort" ) );
383 mLayout->undoStack()->endCommand();
384 mBlockUpdates =
false;
385 updateAtlasFeatures();
388void QgsLayoutAtlasWidget::changeFileFormat()
393 mLayout->setCustomProperty( QStringLiteral(
"atlasRasterFormat" ), mAtlasFileFormat->currentText() );
396void QgsLayoutAtlasWidget::updateGuiElements()
401 blockAllSignals(
true );
402 mUseAtlasCheckBox->setCheckState( mAtlas->
enabled() ? Qt::Checked : Qt::Unchecked );
403 mConfigurationGroup->setEnabled( mAtlas->
enabled() );
404 mOutputGroup->setEnabled( mAtlas->
enabled() );
406 mAtlasCoverageLayerComboBox->setLayer( mAtlas->
coverageLayer() );
410 mAtlasSortExpressionWidget->setLayer( mAtlas->
coverageLayer() );
415 mAtlasHideCoverageCheckBox->setCheckState( mAtlas->
hideCoverage() ? Qt::Checked : Qt::Unchecked );
417 const bool singleFile = mLayout->customProperty( QStringLiteral(
"singleFile" ) ).toBool();
418 mAtlasSingleFileCheckBox->setCheckState( singleFile ? Qt::Checked : Qt::Unchecked );
419 mAtlasFilenamePatternEdit->setEnabled( !singleFile );
420 mAtlasFilenameExpressionButton->setEnabled( !singleFile );
422 mAtlasSortFeatureCheckBox->setCheckState( mAtlas->
sortFeatures() ? Qt::Checked : Qt::Unchecked );
423 mAtlasSortFeatureDirectionButton->setEnabled( mAtlas->
sortFeatures() );
424 mAtlasSortExpressionWidget->setEnabled( mAtlas->
sortFeatures() );
426 mAtlasSortFeatureDirectionButton->setArrowType( mAtlas->
sortAscending() ? Qt::UpArrow : Qt::DownArrow );
429 mAtlasFeatureFilterCheckBox->setCheckState( mAtlas->
filterFeatures() ? Qt::Checked : Qt::Unchecked );
431 mAtlasFeatureFilterButton->setEnabled( mAtlas->
filterFeatures() );
433 mAtlasFileFormat->setCurrentIndex( mAtlasFileFormat->findText( mLayout->customProperty( QStringLiteral(
"atlasRasterFormat" ), QStringLiteral(
"png" ) ).toString() ) );
435 blockAllSignals(
false );
438void QgsLayoutAtlasWidget::blockAllSignals(
bool b )
440 mUseAtlasCheckBox->blockSignals( b );
441 mConfigurationGroup->blockSignals( b );
442 mOutputGroup->blockSignals( b );
443 mAtlasCoverageLayerComboBox->blockSignals( b );
444 mPageNameWidget->blockSignals( b );
445 mAtlasSortExpressionWidget->blockSignals( b );
446 mAtlasFilenamePatternEdit->blockSignals( b );
447 mAtlasLimitCoverageLayerRenderCheckBox->blockSignals( b );
448 mAtlasHideCoverageCheckBox->blockSignals( b );
449 mAtlasSingleFileCheckBox->blockSignals( b );
450 mAtlasSortFeatureCheckBox->blockSignals( b );
451 mAtlasSortFeatureDirectionButton->blockSignals( b );
452 mAtlasFeatureFilterEdit->blockSignals( b );
453 mAtlasFeatureFilterCheckBox->blockSignals( b );
A generic dialog for building expression strings.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Handles parsing and evaluation of expressions (formerly called "search strings").
static QString quoteFieldExpression(const QString &expression, const QgsVectorLayer *layer)
Validate if the expression is a field in the layer and ensure it is quoted.
QString sortExpression() const
Returns the expression (or field name) to use for sorting features.
bool filterFeatures() const
Returns true if features should be filtered in the coverage layer.
QString filenameExpression() const
Returns the filename expression used for generating output filenames for each atlas page.
bool sortAscending() const
Returns true if features should be sorted in an ascending order.
void setCoverageLayer(QgsVectorLayer *layer)
Sets the coverage layer to use for the atlas features.
bool setFilterExpression(const QString &expression, QString &errorString)
Sets the expression used for filtering features in the coverage layer.
void setSortAscending(bool ascending)
Sets whether features should be sorted in an ascending order.
bool hideCoverage() const
Returns true if the atlas is set to hide the coverage layer.
void setEnabled(bool enabled)
Sets whether the atlas is enabled.
void setPageNameExpression(const QString &expression)
Sets the expression (or field name) used for calculating the page name.
QString filterExpression() const
Returns the expression used for filtering features in the coverage layer.
bool enabled() const
Returns whether the atlas generation is enabled.
bool limitCoverageLayerRenderToCurrentFeature() const
Returns true if the atlas is set to limit rendering on the coverage layer to the current feature.
bool setFilenameExpression(const QString &expression, QString &errorString)
Sets the filename expression used for generating output filenames for each atlas page.
void setLimitCoverageLayerRenderToCurrentFeature(bool limit)
Sets whether the rendering of the coverage layer should be limited to the current feature.
void setSortFeatures(bool enabled)
Sets whether features should be sorted in the atlas.
QString pageNameExpression() const
Returns the expression (or field name) used for calculating the page name.
void setSortExpression(const QString &expression)
Sets the expression (or field name) to use for sorting features.
void setFilterFeatures(bool filtered)
Sets whether features should be filtered in the coverage layer.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
void changed()
Emitted when one of the atlas parameters changes.
int updateFeatures()
Requeries the current atlas coverage layer and applies filtering and sorting.
bool sortFeatures() const
Returns true if features should be sorted in the atlas.
void setHideCoverage(bool hide)
Sets whether the coverage layer should be hidden in map items in the layouts.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
Base class for all map layer types.
A bar for displaying non-blocking messages to the user.
void pushInfo(const QString &title, const QString &message)
Pushes a information message with default timeout to the message bar.
void pushWarning(const QString &title, const QString &message)
Pushes a warning message that must be manually dismissed by the user.
Print layout, a QgsLayout subclass for static or atlas-based layouts.
Represents a vector layer which manages a vector based dataset.
QString displayExpression