Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
@@ -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:
Toggle all file notes