Skip to content
Permalink
Browse files

[layouts] Expose the correct expression context for attribute and

manual table text format widgets

These text formats have access to the full layout item expression
context, and also extra variables for @row_number and @column_number,
but these weren't being shown in the UI. Expose them for use in
expressions and highlight the useful @row/column_number variables.
  • Loading branch information
nyalldawson committed Feb 16, 2021
1 parent 1d53f75 commit f3372716060f2c1eecff46c99c999b66505504fc
@@ -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
@@ -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 );
@@ -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:

@@ -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 );
@@ -36,14 +36,15 @@ 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:
//! constructor
QgsLayoutManualTableWidget( QgsLayoutFrame *frame );

void setMasterLayout( QgsMasterLayoutInterface *masterLayout ) override;
QgsExpressionContext createExpressionContext() const override;

protected:

0 comments on commit f337271

Please sign in to comment.