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( mAtlasHideCoverageCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasHideCoverageCheckBox_stateChanged );
40 connect( mAtlasSingleFileCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasSingleFileCheckBox_stateChanged );
41 connect( mAtlasSortFeatureCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasSortFeatureCheckBox_stateChanged );
42 connect( mAtlasSortFeatureDirectionButton, &QToolButton::clicked,
this, &QgsLayoutAtlasWidget::mAtlasSortFeatureDirectionButton_clicked );
43 connect( mAtlasFeatureFilterEdit, &QLineEdit::editingFinished,
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterEdit_editingFinished );
44 connect( mAtlasFeatureFilterButton, &QToolButton::clicked,
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterButton_clicked );
45 connect( mAtlasFeatureFilterCheckBox, &QCheckBox::stateChanged,
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterCheckBox_stateChanged );
56 mAtlasSortFeatureDirectionButton->setEnabled(
false );
57 mAtlasSortExpressionWidget->setEnabled(
false );
62 mPageNameWidget->registerExpressionContextGenerator( mLayout );
64 const QList<QByteArray> formats = QImageWriter::supportedImageFormats();
65 for (
int i = 0; i < formats.size(); ++i )
67 mAtlasFileFormat->addItem( QString( formats.at( i ) ) );
69 connect( mAtlasFileFormat, qOverload<int>( &QComboBox::currentIndexChanged ),
this, [=](
int ) { changeFileFormat(); } );
79void QgsLayoutAtlasWidget::mUseAtlasCheckBox_stateChanged(
int state )
81 if ( state == Qt::Checked )
84 mConfigurationGroup->setEnabled(
true );
85 mOutputGroup->setEnabled(
true );
90 mConfigurationGroup->setEnabled(
false );
91 mOutputGroup->setEnabled(
false );
95void QgsLayoutAtlasWidget::changeCoverageLayer(
QgsMapLayer *layer )
103 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Layer" ) );
104 mLayout->reportContext().setLayer( vl );
112 updateAtlasFeatures();
118 if ( exp.prepare( &context ) && !exp.hasParserError() )
127 mLayout->undoStack()->endCommand();
130void QgsLayoutAtlasWidget::mAtlasFilenamePatternEdit_editingFinished()
136 mBlockUpdates =
true;
137 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filename" ) );
141 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filename expression to '%1'.\nParser error:\n%2" ).arg( mAtlasFilenamePatternEdit->text(), error ) );
143 mLayout->undoStack()->endCommand();
144 mBlockUpdates =
false;
147void QgsLayoutAtlasWidget::mAtlasFilenameExpressionButton_clicked()
156 exprDlg.setWindowTitle( tr(
"Expression Based Filename" ) );
158 if ( exprDlg.exec() == QDialog::Accepted )
160 const QString expression = exprDlg.expressionText();
161 if ( !expression.isEmpty() )
164 mAtlasFilenamePatternEdit->setText( expression );
166 mBlockUpdates =
true;
167 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filename" ) );
171 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filename expression to '%1'.\nParser error:\n%2" ).arg( expression, error ) );
173 mBlockUpdates =
false;
174 mLayout->undoStack()->endCommand();
179void QgsLayoutAtlasWidget::mAtlasHideCoverageCheckBox_stateChanged(
int state )
184 mBlockUpdates =
true;
185 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Toggle Atlas Layer" ) );
187 mLayout->undoStack()->endCommand();
188 mBlockUpdates =
false;
191void QgsLayoutAtlasWidget::mAtlasSingleFileCheckBox_stateChanged(
int state )
196 if ( state == Qt::Checked )
198 mAtlasFilenamePatternEdit->setEnabled(
false );
199 mAtlasFilenameExpressionButton->setEnabled(
false );
203 mAtlasFilenamePatternEdit->setEnabled(
true );
204 mAtlasFilenameExpressionButton->setEnabled(
true );
207 mLayout->setCustomProperty( QStringLiteral(
"singleFile" ), state == Qt::Checked );
210void QgsLayoutAtlasWidget::mAtlasSortFeatureCheckBox_stateChanged(
int state )
215 if ( state == Qt::Checked )
217 mAtlasSortFeatureDirectionButton->setEnabled(
true );
218 mAtlasSortExpressionWidget->setEnabled(
true );
222 mAtlasSortFeatureDirectionButton->setEnabled(
false );
223 mAtlasSortExpressionWidget->setEnabled(
false );
225 mBlockUpdates =
true;
226 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Toggle Atlas Sorting" ) );
228 mLayout->undoStack()->endCommand();
229 mBlockUpdates =
false;
230 updateAtlasFeatures();
233void QgsLayoutAtlasWidget::changesSortFeatureExpression(
const QString &expression,
bool )
238 mBlockUpdates =
true;
239 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Sort" ) );
240 QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mAtlasCoverageLayerComboBox->currentLayer() );
242 mLayout->undoStack()->endCommand();
243 mBlockUpdates =
false;
244 updateAtlasFeatures();
247void QgsLayoutAtlasWidget::updateAtlasFeatures()
252 mMessageBar->
pushInfo( tr(
"Atlas" ), tr(
"No matching atlas features found!" ) );
259void QgsLayoutAtlasWidget::mAtlasFeatureFilterCheckBox_stateChanged(
int state )
264 if ( state == Qt::Checked )
266 mAtlasFeatureFilterEdit->setEnabled(
true );
267 mAtlasFeatureFilterButton->setEnabled(
true );
271 mAtlasFeatureFilterEdit->setEnabled(
false );
272 mAtlasFeatureFilterButton->setEnabled(
false );
274 mBlockUpdates =
true;
275 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filter" ) );
277 mLayout->undoStack()->endCommand();
278 mBlockUpdates =
false;
279 updateAtlasFeatures();
282void QgsLayoutAtlasWidget::pageNameExpressionChanged(
const QString &,
bool valid )
287 const QString expression = mPageNameWidget->asExpression();
288 if ( !valid && !expression.isEmpty() )
293 mBlockUpdates =
true;
294 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Name" ) );
296 mLayout->undoStack()->endCommand();
297 mBlockUpdates =
false;
300void QgsLayoutAtlasWidget::mAtlasFeatureFilterEdit_editingFinished()
306 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filter" ) );
308 mBlockUpdates =
true;
312 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filter expression to '%1'.\nParser error:\n%2" ).arg( mAtlasFeatureFilterEdit->text(), error ) );
314 mBlockUpdates =
false;
315 mLayout->undoStack()->endCommand();
316 updateAtlasFeatures();
319void QgsLayoutAtlasWidget::mAtlasFeatureFilterButton_clicked()
324 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mAtlasCoverageLayerComboBox->currentLayer() );
333 exprDlg.setWindowTitle( tr(
"Expression Based Filter" ) );
335 if ( exprDlg.exec() == QDialog::Accepted )
337 const QString expression = exprDlg.expressionText();
338 if ( !expression.isEmpty() )
340 mAtlasFeatureFilterEdit->setText( expression );
342 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Filter" ) );
343 mBlockUpdates =
true;
347 mMessageBar->
pushWarning( tr(
"Atlas" ), tr(
"Could not set filter expression to '%1'.\nParser error:\n%2" ).arg( mAtlasFeatureFilterEdit->text(), error ) );
349 mBlockUpdates =
false;
350 mLayout->undoStack()->endCommand();
351 updateAtlasFeatures();
356void QgsLayoutAtlasWidget::mAtlasSortFeatureDirectionButton_clicked()
361 Qt::ArrowType at = mAtlasSortFeatureDirectionButton->arrowType();
362 at = ( at == Qt::UpArrow ) ? Qt::DownArrow : Qt::UpArrow;
363 mAtlasSortFeatureDirectionButton->setArrowType( at );
365 mBlockUpdates =
true;
366 mLayout->undoStack()->beginCommand( mAtlas, tr(
"Change Atlas Sort" ) );
368 mLayout->undoStack()->endCommand();
369 mBlockUpdates =
false;
370 updateAtlasFeatures();
373void QgsLayoutAtlasWidget::changeFileFormat()
378 mLayout->setCustomProperty( QStringLiteral(
"atlasRasterFormat" ), mAtlasFileFormat->currentText() );
381void QgsLayoutAtlasWidget::updateGuiElements()
386 blockAllSignals(
true );
387 mUseAtlasCheckBox->setCheckState( mAtlas->
enabled() ? Qt::Checked : Qt::Unchecked );
388 mConfigurationGroup->setEnabled( mAtlas->
enabled() );
389 mOutputGroup->setEnabled( mAtlas->
enabled() );
391 mAtlasCoverageLayerComboBox->setLayer( mAtlas->
coverageLayer() );
395 mAtlasSortExpressionWidget->setLayer( mAtlas->
coverageLayer() );
399 mAtlasHideCoverageCheckBox->setCheckState( mAtlas->
hideCoverage() ? Qt::Checked : Qt::Unchecked );
401 const bool singleFile = mLayout->customProperty( QStringLiteral(
"singleFile" ) ).toBool();
402 mAtlasSingleFileCheckBox->setCheckState( singleFile ? Qt::Checked : Qt::Unchecked );
403 mAtlasFilenamePatternEdit->setEnabled( !singleFile );
404 mAtlasFilenameExpressionButton->setEnabled( !singleFile );
406 mAtlasSortFeatureCheckBox->setCheckState( mAtlas->
sortFeatures() ? Qt::Checked : Qt::Unchecked );
407 mAtlasSortFeatureDirectionButton->setEnabled( mAtlas->
sortFeatures() );
408 mAtlasSortExpressionWidget->setEnabled( mAtlas->
sortFeatures() );
410 mAtlasSortFeatureDirectionButton->setArrowType( mAtlas->
sortAscending() ? Qt::UpArrow : Qt::DownArrow );
413 mAtlasFeatureFilterCheckBox->setCheckState( mAtlas->
filterFeatures() ? Qt::Checked : Qt::Unchecked );
415 mAtlasFeatureFilterButton->setEnabled( mAtlas->
filterFeatures() );
417 mAtlasFileFormat->setCurrentIndex( mAtlasFileFormat->findText( mLayout->customProperty( QStringLiteral(
"atlasRasterFormat" ), QStringLiteral(
"png" ) ).toString() ) );
419 blockAllSignals(
false );
422void QgsLayoutAtlasWidget::blockAllSignals(
bool b )
424 mUseAtlasCheckBox->blockSignals( b );
425 mConfigurationGroup->blockSignals( b );
426 mOutputGroup->blockSignals( b );
427 mAtlasCoverageLayerComboBox->blockSignals( b );
428 mPageNameWidget->blockSignals( b );
429 mAtlasSortExpressionWidget->blockSignals( b );
430 mAtlasFilenamePatternEdit->blockSignals( b );
431 mAtlasHideCoverageCheckBox->blockSignals( b );
432 mAtlasSingleFileCheckBox->blockSignals( b );
433 mAtlasSortFeatureCheckBox->blockSignals( b );
434 mAtlasSortFeatureDirectionButton->blockSignals( b );
435 mAtlasFeatureFilterEdit->blockSignals( b );
436 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...
Class for 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 setFilenameExpression(const QString &expression, QString &errorString)
Sets the filename expression used for generating output filenames for each atlas page.
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 data sets.
QString displayExpression