Navigation Menu

Skip to content

Commit

Permalink
[layouts] Expose the correct expression context for attribute and
Browse files Browse the repository at this point in the history
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 f337271
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 2 deletions.
12 changes: 12 additions & 0 deletions src/core/layout/qgslayouttable.cpp
Expand Up @@ -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();
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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
Expand Down
24 changes: 24 additions & 0 deletions src/gui/layout/qgslayoutattributetablewidget.cpp
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down
3 changes: 2 additions & 1 deletion src/gui/layout/qgslayoutattributetablewidget.h
Expand Up @@ -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:
Expand All @@ -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:

Expand Down
24 changes: 24 additions & 0 deletions src/gui/layout/qgslayoutmanualtablewidget.cpp
Expand Up @@ -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 );
Expand Down Expand Up @@ -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 );
Expand Down
3 changes: 2 additions & 1 deletion src/gui/layout/qgslayoutmanualtablewidget.h
Expand Up @@ -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:

Expand Down

0 comments on commit f337271

Please sign in to comment.