[layouts] Allow cell-based data-defined text format in the attribute table

This commit is contained in:
nirvn 2020-07-14 15:28:28 +07:00 committed by Mathieu Pellerin
parent e8704f0517
commit c964dea4fa
2 changed files with 42 additions and 3 deletions

View File

@ -15,6 +15,7 @@
* *
***************************************************************************/
#include "qgsexpressioncontextutils.h"
#include "qgslayouttable.h"
#include "qgslayout.h"
#include "qgslayoututils.h"
@ -506,7 +507,6 @@ void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF &
//calculate row height
double rowHeight = mMaxRowHeightMap[row + 1] + 2 * mCellMargin;
for ( const QgsLayoutTableColumn &column : qgis::as_const( mColumns ) )
{
const QRectF fullCell( currentX, currentY, mMaxColumnWidthMap[col] + 2 * mCellMargin, rowHeight );
@ -524,6 +524,8 @@ void QgsLayoutTable::render( QgsLayoutItemRenderContext &context, const QRectF &
QStringList str = cellContents.toString().split( '\n' );
QgsTextFormat cellFormat = textFormatForCell( row, col );
QgsExpressionContextScopePopper popper( context.renderContext().expressionContext(), scopeForCell( row, col ) );
cellFormat.updateDataDefinedProperties( context.renderContext() );
// disable text clipping to target text rectangle, because we manually clip to the full cell bounds below
// and it's ok if text overlaps into the margin (e.g. extenders or italicized text)
@ -1118,7 +1120,12 @@ bool QgsLayoutTable::calculateMaxColumnWidths()
{
//column width set to automatic, so check content size
const QStringList multiLineSplit = ( *colIt ).toString().split( '\n' );
currentCellTextWidth = QgsTextRenderer::textWidth( context, textFormatForCell( row - 1, col ), multiLineSplit ) / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
QgsTextFormat cellFormat = textFormatForCell( row - 1, col );
QgsExpressionContextScopePopper popper( context.expressionContext(), scopeForCell( row - 1, col ) );
cellFormat.updateDataDefinedProperties( context );
currentCellTextWidth = QgsTextRenderer::textWidth( context, cellFormat, multiLineSplit ) / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
widths[ row * cols + col ] = currentCellTextWidth;
}
else
@ -1192,7 +1199,9 @@ bool QgsLayoutTable::calculateMaxRowHeights()
int i = 0;
for ( ; colIt != rowIt->constEnd(); ++colIt )
{
const QgsTextFormat cellFormat = textFormatForCell( row - 1, i );
QgsTextFormat cellFormat = textFormatForCell( row - 1, i );
QgsExpressionContextScopePopper popper( context.expressionContext(), scopeForCell( row - 1, i ) );
cellFormat.updateDataDefinedProperties( context );
const double contentDescentMm = QgsTextRenderer::fontMetrics( context, cellFormat, QgsTextRenderer::FONT_WORKAROUND_SCALE ).descent() / QgsTextRenderer::FONT_WORKAROUND_SCALE / context.convertToPainterUnits( 1, QgsUnitTypes::RenderMillimeters );
if ( textRequiresWrapping( context, ( *colIt ).toString(), mColumns.at( i ).width(), cellFormat ) )

View File

@ -35,6 +35,7 @@
#include "qgsprintlayout.h"
#include "qgslayoutatlas.h"
#include "qgslayoututils.h"
#include "qgspallabeling.h"
#include <QObject>
#include "qgstest.h"
@ -83,6 +84,7 @@ class TestQgsLayoutTable : public QObject
void testBaseSort();
void testExpressionSort();
void testScopeForCell();
void testDataDefinedTextFormatForCell();
private:
QgsVectorLayer *mVectorLayer = nullptr;
@ -1052,6 +1054,34 @@ void TestQgsLayoutTable::verticalGrid()
delete multiLineLayer;
}
void TestQgsLayoutTable::testDataDefinedTextFormatForCell()
{
QgsLayout l( QgsProject::instance() );
l.initializeDefaults();
QgsLayoutItemAttributeTable *table = new QgsLayoutItemAttributeTable( &l );
table->setVectorLayer( mVectorLayer );
l.addMultiFrame( table );
QgsLayoutFrame *frame = new QgsLayoutFrame( &l, table );
frame->attemptSetSceneRect( QRectF( 5, 5, 100, 30 ) );
frame->setFrameEnabled( true );
l.addLayoutItem( frame );
table->addFrame( frame );
QgsTextFormat textFormat = QgsTextFormat::fromQFont( QgsFontUtils::getStandardTestFont( QStringLiteral( "Bold" ) ) );
table->setHeaderTextFormat( textFormat );
table->setContentTextFormat( textFormat );
table->refresh();
QCOMPARE( table->totalHeight(), 150.0 );
textFormat.dataDefinedProperties().setProperty( QgsPalLayerSettings::Size, QgsProperty::fromExpression( QStringLiteral( "if(@column_number = 1,30,5)" ) ) );
table->setContentTextFormat( textFormat );
table->refresh();
QCOMPARE( table->totalHeight(), 270.0 );
}
void TestQgsLayoutTable::align()
{
QgsLayout l( QgsProject::instance() );