18#include <QImageWriter> 
   32  , mAtlas( layout->atlas() )
 
   35  connect( mUseAtlasCheckBox, &QCheckBox::stateChanged, 
this, &QgsLayoutAtlasWidget::mUseAtlasCheckBox_stateChanged );
 
   36  connect( mAtlasFilenamePatternEdit, &QLineEdit::editingFinished, 
this, &QgsLayoutAtlasWidget::mAtlasFilenamePatternEdit_editingFinished );
 
   37  connect( mAtlasFilenameExpressionButton, &QToolButton::clicked, 
this, &QgsLayoutAtlasWidget::mAtlasFilenameExpressionButton_clicked );
 
   38  connect( mAtlasHideCoverageCheckBox, &QCheckBox::stateChanged, 
this, &QgsLayoutAtlasWidget::mAtlasHideCoverageCheckBox_stateChanged );
 
   39  connect( mAtlasSingleFileCheckBox, &QCheckBox::stateChanged, 
this, &QgsLayoutAtlasWidget::mAtlasSingleFileCheckBox_stateChanged );
 
   40  connect( mAtlasSortFeatureCheckBox, &QCheckBox::stateChanged, 
this, &QgsLayoutAtlasWidget::mAtlasSortFeatureCheckBox_stateChanged );
 
   41  connect( mAtlasSortFeatureDirectionButton, &QToolButton::clicked, 
this, &QgsLayoutAtlasWidget::mAtlasSortFeatureDirectionButton_clicked );
 
   42  connect( mAtlasFeatureFilterEdit, &QLineEdit::editingFinished, 
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterEdit_editingFinished );
 
   43  connect( mAtlasFeatureFilterButton, &QToolButton::clicked, 
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterButton_clicked );
 
   44  connect( mAtlasFeatureFilterCheckBox, &QCheckBox::stateChanged, 
this, &QgsLayoutAtlasWidget::mAtlasFeatureFilterCheckBox_stateChanged );
 
   55  mAtlasSortFeatureDirectionButton->setEnabled( 
false );
 
   56  mAtlasSortExpressionWidget->setEnabled( 
false );
 
   61  mPageNameWidget->registerExpressionContextGenerator( mLayout );
 
   63  const QList<QByteArray> formats = QImageWriter::supportedImageFormats();
 
   64  for ( 
int i = 0; i < formats.size(); ++i )
 
   66    mAtlasFileFormat->addItem( QString( formats.at( i ) ) );
 
   68  connect( mAtlasFileFormat, qOverload<int>( &QComboBox::currentIndexChanged ), 
this, [ = ]( 
int ) { changeFileFormat(); } );
 
 
   78void QgsLayoutAtlasWidget::mUseAtlasCheckBox_stateChanged( 
int state )
 
   80  if ( state == Qt::Checked )
 
   83    mConfigurationGroup->setEnabled( 
true );
 
   84    mOutputGroup->setEnabled( 
true );
 
   89    mConfigurationGroup->setEnabled( 
false );
 
   90    mOutputGroup->setEnabled( 
false );
 
   94void QgsLayoutAtlasWidget::changeCoverageLayer( 
QgsMapLayer *layer )
 
  102  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Layer" ) );
 
  103  mLayout->reportContext().setLayer( vl );
 
  111    updateAtlasFeatures();
 
  117  if ( exp.prepare( &context ) && !exp.hasParserError() )
 
  126  mLayout->undoStack()->endCommand();
 
  129void QgsLayoutAtlasWidget::mAtlasFilenamePatternEdit_editingFinished()
 
  135  mBlockUpdates = 
true;
 
  136  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Filename" ) );
 
  141                              tr( 
"Could not set filename expression to '%1'.\nParser error:\n%2" )
 
  142                              .arg( mAtlasFilenamePatternEdit->text(),
 
  145  mLayout->undoStack()->endCommand();
 
  146  mBlockUpdates = 
false;
 
  149void QgsLayoutAtlasWidget::mAtlasFilenameExpressionButton_clicked()
 
  158  exprDlg.setWindowTitle( tr( 
"Expression Based Filename" ) );
 
  160  if ( exprDlg.exec() == QDialog::Accepted )
 
  162    const QString expression = exprDlg.expressionText();
 
  163    if ( !expression.isEmpty() )
 
  166      mAtlasFilenamePatternEdit->setText( expression );
 
  168      mBlockUpdates = 
true;
 
  169      mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Filename" ) );
 
  173        mMessageBar->
pushWarning( tr( 
"Atlas" ), tr( 
"Could not set filename expression to '%1'.\nParser error:\n%2" )
 
  177      mBlockUpdates = 
false;
 
  178      mLayout->undoStack()->endCommand();
 
  183void QgsLayoutAtlasWidget::mAtlasHideCoverageCheckBox_stateChanged( 
int state )
 
  188  mBlockUpdates = 
true;
 
  189  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Toggle Atlas Layer" ) );
 
  191  mLayout->undoStack()->endCommand();
 
  192  mBlockUpdates = 
false;
 
  195void QgsLayoutAtlasWidget::mAtlasSingleFileCheckBox_stateChanged( 
int state )
 
  200  if ( state == Qt::Checked )
 
  202    mAtlasFilenamePatternEdit->setEnabled( 
false );
 
  203    mAtlasFilenameExpressionButton->setEnabled( 
false );
 
  207    mAtlasFilenamePatternEdit->setEnabled( 
true );
 
  208    mAtlasFilenameExpressionButton->setEnabled( 
true );
 
  211  mLayout->setCustomProperty( QStringLiteral( 
"singleFile" ), state == Qt::Checked );
 
  214void QgsLayoutAtlasWidget::mAtlasSortFeatureCheckBox_stateChanged( 
int state )
 
  219  if ( state == Qt::Checked )
 
  221    mAtlasSortFeatureDirectionButton->setEnabled( 
true );
 
  222    mAtlasSortExpressionWidget->setEnabled( 
true );
 
  226    mAtlasSortFeatureDirectionButton->setEnabled( 
false );
 
  227    mAtlasSortExpressionWidget->setEnabled( 
false );
 
  229  mBlockUpdates = 
true;
 
  230  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Toggle Atlas Sorting" ) );
 
  232  mLayout->undoStack()->endCommand();
 
  233  mBlockUpdates = 
false;
 
  234  updateAtlasFeatures();
 
  237void QgsLayoutAtlasWidget::changesSortFeatureExpression( 
const QString &expression, 
bool )
 
  242  mBlockUpdates = 
true;
 
  243  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Sort" ) );
 
  244  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mAtlasCoverageLayerComboBox->currentLayer() );
 
  246  mLayout->undoStack()->endCommand();
 
  247  mBlockUpdates = 
false;
 
  248  updateAtlasFeatures();
 
  251void QgsLayoutAtlasWidget::updateAtlasFeatures()
 
  256    mMessageBar->
pushInfo( tr( 
"Atlas" ),
 
  257                           tr( 
"No matching atlas features found!" ) );
 
  264void QgsLayoutAtlasWidget::mAtlasFeatureFilterCheckBox_stateChanged( 
int state )
 
  269  if ( state == Qt::Checked )
 
  271    mAtlasFeatureFilterEdit->setEnabled( 
true );
 
  272    mAtlasFeatureFilterButton->setEnabled( 
true );
 
  276    mAtlasFeatureFilterEdit->setEnabled( 
false );
 
  277    mAtlasFeatureFilterButton->setEnabled( 
false );
 
  279  mBlockUpdates = 
true;
 
  280  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Filter" ) );
 
  282  mLayout->undoStack()->endCommand();
 
  283  mBlockUpdates = 
false;
 
  284  updateAtlasFeatures();
 
  287void QgsLayoutAtlasWidget::pageNameExpressionChanged( 
const QString &, 
bool valid )
 
  292  const QString expression = mPageNameWidget->asExpression();
 
  293  if ( !valid && !expression.isEmpty() )
 
  298  mBlockUpdates = 
true;
 
  299  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Name" ) );
 
  301  mLayout->undoStack()->endCommand();
 
  302  mBlockUpdates = 
false;
 
  305void QgsLayoutAtlasWidget::mAtlasFeatureFilterEdit_editingFinished()
 
  311  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Filter" ) );
 
  313  mBlockUpdates = 
true;
 
  317    mMessageBar->
pushWarning( tr( 
"Atlas" ), tr( 
"Could not set filter expression to '%1'.\nParser error:\n%2" )
 
  318                              .arg( mAtlasFeatureFilterEdit->text(),
 
  321  mBlockUpdates = 
false;
 
  322  mLayout->undoStack()->endCommand();
 
  323  updateAtlasFeatures();
 
  326void QgsLayoutAtlasWidget::mAtlasFeatureFilterButton_clicked()
 
  331  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( mAtlasCoverageLayerComboBox->currentLayer() );
 
  340  exprDlg.setWindowTitle( tr( 
"Expression Based Filter" ) );
 
  342  if ( exprDlg.exec() == QDialog::Accepted )
 
  344    const QString expression = exprDlg.expressionText();
 
  345    if ( !expression.isEmpty() )
 
  347      mAtlasFeatureFilterEdit->setText( expression );
 
  349      mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Filter" ) );
 
  350      mBlockUpdates = 
true;
 
  355                                  tr( 
"Could not set filter expression to '%1'.\nParser error:\n%2" )
 
  356                                  .arg( mAtlasFeatureFilterEdit->text(),
 
  360      mBlockUpdates = 
false;
 
  361      mLayout->undoStack()->endCommand();
 
  362      updateAtlasFeatures();
 
  367void QgsLayoutAtlasWidget::mAtlasSortFeatureDirectionButton_clicked()
 
  372  Qt::ArrowType at = mAtlasSortFeatureDirectionButton->arrowType();
 
  373  at = ( at == Qt::UpArrow ) ? Qt::DownArrow : Qt::UpArrow;
 
  374  mAtlasSortFeatureDirectionButton->setArrowType( at );
 
  376  mBlockUpdates = 
true;
 
  377  mLayout->undoStack()->beginCommand( mAtlas, tr( 
"Change Atlas Sort" ) );
 
  379  mLayout->undoStack()->endCommand();
 
  380  mBlockUpdates = 
false;
 
  381  updateAtlasFeatures();
 
  384void QgsLayoutAtlasWidget::changeFileFormat()
 
  389  mLayout->setCustomProperty( QStringLiteral( 
"atlasRasterFormat" ), mAtlasFileFormat->currentText() );
 
  392void QgsLayoutAtlasWidget::updateGuiElements()
 
  397  blockAllSignals( 
true );
 
  398  mUseAtlasCheckBox->setCheckState( mAtlas->
enabled() ? Qt::Checked : Qt::Unchecked );
 
  399  mConfigurationGroup->setEnabled( mAtlas->
enabled() );
 
  400  mOutputGroup->setEnabled( mAtlas->
enabled() );
 
  402  mAtlasCoverageLayerComboBox->setLayer( mAtlas->
coverageLayer() );
 
  406  mAtlasSortExpressionWidget->setLayer( mAtlas->
coverageLayer() );
 
  410  mAtlasHideCoverageCheckBox->setCheckState( mAtlas->
hideCoverage() ? Qt::Checked : Qt::Unchecked );
 
  412  const bool singleFile = mLayout->customProperty( QStringLiteral( 
"singleFile" ) ).toBool();
 
  413  mAtlasSingleFileCheckBox->setCheckState( singleFile ? Qt::Checked : Qt::Unchecked );
 
  414  mAtlasFilenamePatternEdit->setEnabled( !singleFile );
 
  415  mAtlasFilenameExpressionButton->setEnabled( !singleFile );
 
  417  mAtlasSortFeatureCheckBox->setCheckState( mAtlas->
sortFeatures() ? Qt::Checked : Qt::Unchecked );
 
  418  mAtlasSortFeatureDirectionButton->setEnabled( mAtlas->
sortFeatures() );
 
  419  mAtlasSortExpressionWidget->setEnabled( mAtlas->
sortFeatures() );
 
  421  mAtlasSortFeatureDirectionButton->setArrowType( mAtlas->
sortAscending() ? Qt::UpArrow : Qt::DownArrow );
 
  424  mAtlasFeatureFilterCheckBox->setCheckState( mAtlas->
filterFeatures() ? Qt::Checked : Qt::Unchecked );
 
  426  mAtlasFeatureFilterButton->setEnabled( mAtlas->
filterFeatures() );
 
  428  mAtlasFileFormat->setCurrentIndex( mAtlasFileFormat->findText( mLayout->customProperty( QStringLiteral( 
"atlasRasterFormat" ), QStringLiteral( 
"png" ) ).toString() ) );
 
  430  blockAllSignals( 
false );
 
  433void QgsLayoutAtlasWidget::blockAllSignals( 
bool b )
 
  435  mUseAtlasCheckBox->blockSignals( b );
 
  436  mConfigurationGroup->blockSignals( b );
 
  437  mOutputGroup->blockSignals( b );
 
  438  mAtlasCoverageLayerComboBox->blockSignals( b );
 
  439  mPageNameWidget->blockSignals( b );
 
  440  mAtlasSortExpressionWidget->blockSignals( b );
 
  441  mAtlasFilenamePatternEdit->blockSignals( b );
 
  442  mAtlasHideCoverageCheckBox->blockSignals( b );
 
  443  mAtlasSingleFileCheckBox->blockSignals( b );
 
  444  mAtlasSortFeatureCheckBox->blockSignals( b );
 
  445  mAtlasSortFeatureDirectionButton->blockSignals( b );
 
  446  mAtlasFeatureFilterEdit->blockSignals( b );
 
  447  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