Skip to content
Permalink
Browse files

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

…table
  • Loading branch information
nirvn committed Jul 14, 2020
1 parent e8704f0 commit c964dea4fa4ac37ffaa31ab2a66b7788f6956563
Showing with 42 additions and 3 deletions.
  1. +12 −3 src/core/layout/qgslayouttable.cpp
  2. +30 −0 tests/src/core/testqgslayouttable.cpp
@@ -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 ) )
@@ -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() );

0 comments on commit c964dea

Please sign in to comment.
You can’t perform that action at this time.