diff --git a/src/core/layout/qgslayouttable.cpp b/src/core/layout/qgslayouttable.cpp index 17eb249e44ad..d4cedc3d1308 100644 --- a/src/core/layout/qgslayouttable.cpp +++ b/src/core/layout/qgslayouttable.cpp @@ -433,6 +433,10 @@ void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF & int col = 0; for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) ) { + std::unique_ptr< QgsExpressionContextScope > headerCellScope = qgis::make_unique< QgsExpressionContextScope >(); + headerCellScope->setVariable( QStringLiteral( "column_number" ), col + 1, true ); + QgsExpressionContextScopePopper popper( context.renderContext().expressionContext(), headerCellScope.release() ); + const QgsTextFormat headerFormat = textFormatForHeader( col ); //draw background p->save(); @@ -1095,6 +1099,10 @@ bool QgsLayoutTable::calculateMaxColumnWidths() } else if ( mHeaderMode != QgsLayoutTable::NoHeaders ) { + std::unique_ptr< QgsExpressionContextScope > headerCellScope = qgis::make_unique< QgsExpressionContextScope >(); + headerCellScope->setVariable( QStringLiteral( "column_number" ), i + 1, true ); + QgsExpressionContextScopePopper popper( context.expressionContext(), headerCellScope.release() ); + //column width set to automatic, so check content size const QStringList multiLineSplit = col.heading().split( '\n' ); currentCellTextWidth = QgsTextRenderer::textWidth( context, textFormatForHeader( i ), multiLineSplit ) / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters ); @@ -1168,6 +1176,10 @@ bool QgsLayoutTable::calculateMaxRowHeights() int i = 0; for ( const QgsLayoutTableColumn &col : qgis::as_const( mColumns ) ) { + std::unique_ptr< QgsExpressionContextScope > headerCellScope = qgis::make_unique< QgsExpressionContextScope >(); + headerCellScope->setVariable( QStringLiteral( "column_number" ), i + 1, true ); + QgsExpressionContextScopePopper popper( context.expressionContext(), headerCellScope.release() ); + const QgsTextFormat cellFormat = textFormatForHeader( i ); const double headerDescentMm = QgsTextRenderer::fontMetrics( context, cellFormat, QgsTextRenderer::FONT_WORKAROUND_SCALE ).descent() / QgsTextRenderer::FONT_WORKAROUND_SCALE / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters ); //height diff --git a/src/gui/layout/qgslayoutattributetablewidget.cpp b/src/gui/layout/qgslayoutattributetablewidget.cpp index c68942f1d584..790e5484ba72 100644 --- a/src/gui/layout/qgslayoutattributetablewidget.cpp +++ b/src/gui/layout/qgslayoutattributetablewidget.cpp @@ -73,6 +73,9 @@ QgsLayoutAttributeTableWidget::QgsLayoutAttributeTableWidget( QgsLayoutFrame *fr mContentFontToolButton->setMode( QgsFontButton::ModeTextRenderer ); mHeaderFontToolButton->setMode( QgsFontButton::ModeTextRenderer ); + mContentFontToolButton->registerExpressionContextGenerator( this ); + mHeaderFontToolButton->registerExpressionContextGenerator( this ); + blockAllSignals( true ); mResizeModeComboBox->addItem( tr( "Use Existing Frames" ), QgsLayoutMultiFrame::UseExistingFrames ); @@ -167,6 +170,27 @@ void QgsLayoutAttributeTableWidget::setMasterLayout( QgsMasterLayoutInterface *m mItemPropertiesWidget->setMasterLayout( masterLayout ); } +QgsExpressionContext QgsLayoutAttributeTableWidget::createExpressionContext() const +{ + QgsExpressionContext context; + + // frames include their parent multiframe's context, so prefer that if possible + if ( mFrame ) + context = mFrame->createExpressionContext(); + else if ( mTable ) + context = mTable->createExpressionContext(); + + std::unique_ptr< QgsExpressionContextScope > cellScope = qgis::make_unique< QgsExpressionContextScope >(); + cellScope->setVariable( QStringLiteral( "row_number" ), 1, true ); + cellScope->setVariable( QStringLiteral( "column_number" ), 1, true ); + context.appendScope( cellScope.release() ); + + context.setHighlightedVariables( { QStringLiteral( "row_number" ), + QStringLiteral( "column_number" )} ); + + return context; +} + bool QgsLayoutAttributeTableWidget::setNewItem( QgsLayoutItem *item ) { QgsLayoutFrame *frame = qobject_cast< QgsLayoutFrame * >( item ); diff --git a/src/gui/layout/qgslayoutattributetablewidget.h b/src/gui/layout/qgslayoutattributetablewidget.h index e29b89f42d80..8d4eb862b141 100644 --- a/src/gui/layout/qgslayoutattributetablewidget.h +++ b/src/gui/layout/qgslayoutattributetablewidget.h @@ -35,7 +35,7 @@ class QgsLayoutFrame; * \note This class is not a part of public API * \since QGIS 3.12 */ -class GUI_EXPORT QgsLayoutAttributeTableWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutAttributeTableWidgetBase +class GUI_EXPORT QgsLayoutAttributeTableWidget: public QgsLayoutItemBaseWidget, public QgsExpressionContextGenerator, private Ui::QgsLayoutAttributeTableWidgetBase { Q_OBJECT public: @@ -44,6 +44,7 @@ class GUI_EXPORT QgsLayoutAttributeTableWidget: public QgsLayoutItemBaseWidget, void setReportTypeString( const QString &string ) override; void setMasterLayout( QgsMasterLayoutInterface *masterLayout ) override; + QgsExpressionContext createExpressionContext() const override; protected: diff --git a/src/gui/layout/qgslayoutmanualtablewidget.cpp b/src/gui/layout/qgslayoutmanualtablewidget.cpp index 4c42f817aad4..c1eff732a5b0 100644 --- a/src/gui/layout/qgslayoutmanualtablewidget.cpp +++ b/src/gui/layout/qgslayoutmanualtablewidget.cpp @@ -54,6 +54,9 @@ QgsLayoutManualTableWidget::QgsLayoutManualTableWidget( QgsLayoutFrame *frame ) mContentFontToolButton->setMode( QgsFontButton::ModeTextRenderer ); mHeaderFontToolButton->setMode( QgsFontButton::ModeTextRenderer ); + mContentFontToolButton->registerExpressionContextGenerator( this ); + mHeaderFontToolButton->registerExpressionContextGenerator( this ); + blockAllSignals( true ); mResizeModeComboBox->addItem( tr( "Use Existing Frames" ), QgsLayoutMultiFrame::UseExistingFrames ); @@ -107,6 +110,27 @@ void QgsLayoutManualTableWidget::setMasterLayout( QgsMasterLayoutInterface *mast mItemPropertiesWidget->setMasterLayout( masterLayout ); } +QgsExpressionContext QgsLayoutManualTableWidget::createExpressionContext() const +{ + QgsExpressionContext context; + + // frames include their parent multiframe's context, so prefer that if possible + if ( mFrame ) + context = mFrame->createExpressionContext(); + else if ( mTable ) + context = mTable->createExpressionContext(); + + std::unique_ptr< QgsExpressionContextScope > cellScope = qgis::make_unique< QgsExpressionContextScope >(); + cellScope->setVariable( QStringLiteral( "row_number" ), 1, true ); + cellScope->setVariable( QStringLiteral( "column_number" ), 1, true ); + context.appendScope( cellScope.release() ); + + context.setHighlightedVariables( { QStringLiteral( "row_number" ), + QStringLiteral( "column_number" )} ); + + return context; +} + bool QgsLayoutManualTableWidget::setNewItem( QgsLayoutItem *item ) { QgsLayoutFrame *frame = qobject_cast< QgsLayoutFrame * >( item ); diff --git a/src/gui/layout/qgslayoutmanualtablewidget.h b/src/gui/layout/qgslayoutmanualtablewidget.h index 44943496948f..8aa914208fd4 100644 --- a/src/gui/layout/qgslayoutmanualtablewidget.h +++ b/src/gui/layout/qgslayoutmanualtablewidget.h @@ -36,7 +36,7 @@ class QgsLayoutFrame; * \note This class is not a part of public API * \since QGIS 3.12 */ -class GUI_EXPORT QgsLayoutManualTableWidget: public QgsLayoutItemBaseWidget, private Ui::QgsLayoutManualTableWidgetBase +class GUI_EXPORT QgsLayoutManualTableWidget: public QgsLayoutItemBaseWidget, public QgsExpressionContextGenerator, private Ui::QgsLayoutManualTableWidgetBase { Q_OBJECT public: @@ -44,6 +44,7 @@ class GUI_EXPORT QgsLayoutManualTableWidget: public QgsLayoutItemBaseWidget, pri QgsLayoutManualTableWidget( QgsLayoutFrame *frame ); void setMasterLayout( QgsMasterLayoutInterface *masterLayout ) override; + QgsExpressionContext createExpressionContext() const override; protected: