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