Skip to content

Commit

Permalink
Merge pull request #3602 from nirvn/composer_table_custom_grid
Browse files Browse the repository at this point in the history
[FEATURE] control over drawing of composer table grid horizontal & vertical lines
  • Loading branch information
nyalldawson committed Oct 14, 2016
2 parents 721d3c5 + ec2d7fe commit 47c1f6e
Show file tree
Hide file tree
Showing 9 changed files with 292 additions and 27 deletions.
40 changes: 40 additions & 0 deletions python/core/composer/qgscomposertablev2.sip
Expand Up @@ -310,6 +310,46 @@ class QgsComposerTableV2: QgsComposerMultiFrame
*/ */
QColor gridColor() const; QColor gridColor() const;


/** Sets whether the grid's horizontal lines should be drawn in the table
* @param horizontalGird set to true to draw grid's horizontal lines
* @see setShowGrid
* @see setGridStrokeWidth
* @see setGridColor
* @see setVerticalGrid
* @note added in QGIS 3.0
*/
void setHorizontalGrid( const bool horizontalGrid );

/** Returns whether the grid's horizontal lines are drawn in the table
* @returns true if grid's horizontal lines are drawn
* @see setShowGrid
* @see setGridStrokeWidth
* @see setGridColor
* @see setVerticalGrid
* @note added in QGIS 3.0
*/
bool horizontalGrid() const;

/** Sets whether the grid's vertical lines should be drawn in the table
* @param verticalGird set to true to draw grid's vertical lines
* @see setShowGrid
* @see setGridStrokeWidth
* @see setGridColor
* @see setHorizontalGrid
* @note added in QGIS 3.0
*/
void setVerticalGrid( const bool verticalGrid );

/** Returns whether the grid's vertical lines are drawn in the table
* @returns true if grid's vertical lines are drawn
* @see setShowGrid
* @see setGridStrokeWidth
* @see setGridColor
* @see setHorizontalGrid
* @note added in QGIS 3.0
*/
bool verticalGrid() const;

/** Sets color used for background of table. /** Sets color used for background of table.
* @param color table background color * @param color table background color
* @see backgroundColor * @see backgroundColor
Expand Down
42 changes: 42 additions & 0 deletions src/app/composer/qgscomposerattributetablewidget.cpp
Expand Up @@ -357,6 +357,44 @@ void QgsComposerAttributeTableWidget::on_mGridColorButton_colorChanged( const QC
} }
} }


void QgsComposerAttributeTableWidget::on_mDrawHorizontalGrid_toggled( bool state )
{
if ( !mComposerTable )
{
return;
}

QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table horizontal grid toggled" ) );
}
mComposerTable->setHorizontalGrid( state );
if ( composition )
{
composition->endMultiFrameCommand();
}
}

void QgsComposerAttributeTableWidget::on_mDrawVerticalGrid_toggled( bool state )
{
if ( !mComposerTable )
{
return;
}

QgsComposition* composition = mComposerTable->composition();
if ( composition )
{
composition->beginMultiFrameCommand( mComposerTable, tr( "Table vertical grid toggled" ) );
}
mComposerTable->setVerticalGrid( state );
if ( composition )
{
composition->endMultiFrameCommand();
}
}

void QgsComposerAttributeTableWidget::on_mShowGridGroupCheckBox_toggled( bool state ) void QgsComposerAttributeTableWidget::on_mShowGridGroupCheckBox_toggled( bool state )
{ {
if ( !mComposerTable ) if ( !mComposerTable )
Expand Down Expand Up @@ -428,6 +466,8 @@ void QgsComposerAttributeTableWidget::updateGuiElements()
mMarginSpinBox->setValue( mComposerTable->cellMargin() ); mMarginSpinBox->setValue( mComposerTable->cellMargin() );
mGridStrokeWidthSpinBox->setValue( mComposerTable->gridStrokeWidth() ); mGridStrokeWidthSpinBox->setValue( mComposerTable->gridStrokeWidth() );
mGridColorButton->setColor( mComposerTable->gridColor() ); mGridColorButton->setColor( mComposerTable->gridColor() );
mDrawHorizontalGrid->setChecked( mComposerTable->horizontalGrid() );
mDrawVerticalGrid->setChecked( mComposerTable->verticalGrid() );
if ( mComposerTable->showGrid() ) if ( mComposerTable->showGrid() )
{ {
mShowGridGroupCheckBox->setChecked( true ); mShowGridGroupCheckBox->setChecked( true );
Expand Down Expand Up @@ -568,6 +608,8 @@ void QgsComposerAttributeTableWidget::blockAllSignals( bool b )
mGridColorButton->blockSignals( b ); mGridColorButton->blockSignals( b );
mGridStrokeWidthSpinBox->blockSignals( b ); mGridStrokeWidthSpinBox->blockSignals( b );
mBackgroundColorButton->blockSignals( b ); mBackgroundColorButton->blockSignals( b );
mDrawHorizontalGrid->blockSignals( b );
mDrawVerticalGrid->blockSignals( b );
mShowGridGroupCheckBox->blockSignals( b ); mShowGridGroupCheckBox->blockSignals( b );
mShowOnlyVisibleFeaturesCheckBox->blockSignals( b ); mShowOnlyVisibleFeaturesCheckBox->blockSignals( b );
mUniqueOnlyCheckBox->blockSignals( b ); mUniqueOnlyCheckBox->blockSignals( b );
Expand Down
2 changes: 2 additions & 0 deletions src/app/composer/qgscomposerattributetablewidget.h
Expand Up @@ -55,6 +55,8 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
void on_mHeaderFontColorButton_colorChanged( const QColor& newColor ); void on_mHeaderFontColorButton_colorChanged( const QColor& newColor );
void on_mContentFontPushButton_clicked(); void on_mContentFontPushButton_clicked();
void on_mContentFontColorButton_colorChanged( const QColor& newColor ); void on_mContentFontColorButton_colorChanged( const QColor& newColor );
void on_mDrawHorizontalGrid_toggled( bool state );
void on_mDrawVerticalGrid_toggled( bool state );
void on_mShowGridGroupCheckBox_toggled( bool state ); void on_mShowGridGroupCheckBox_toggled( bool state );
void on_mShowOnlyVisibleFeaturesCheckBox_stateChanged( int state ); void on_mShowOnlyVisibleFeaturesCheckBox_stateChanged( int state );
void on_mFeatureFilterCheckBox_stateChanged( int state ); void on_mFeatureFilterCheckBox_stateChanged( int state );
Expand Down
95 changes: 68 additions & 27 deletions src/core/composer/qgscomposertablev2.cpp
Expand Up @@ -58,6 +58,8 @@ QgsComposerTableV2::QgsComposerTableV2( QgsComposition *composition, bool create
, mShowGrid( true ) , mShowGrid( true )
, mGridStrokeWidth( 0.5 ) , mGridStrokeWidth( 0.5 )
, mGridColor( Qt::black ) , mGridColor( Qt::black )
, mHorizontalGrid( true )
, mVerticalGrid( true )
, mBackgroundColor( Qt::white ) , mBackgroundColor( Qt::white )
, mWrapBehaviour( TruncateText ) , mWrapBehaviour( TruncateText )
{ {
Expand Down Expand Up @@ -120,6 +122,8 @@ bool QgsComposerTableV2::writeXml( QDomElement& elem, QDomDocument & doc, bool i
elem.setAttribute( "contentFontColor", QgsSymbolLayerUtils::encodeColor( mContentFontColor ) ); elem.setAttribute( "contentFontColor", QgsSymbolLayerUtils::encodeColor( mContentFontColor ) );
elem.setAttribute( "gridStrokeWidth", QString::number( mGridStrokeWidth ) ); elem.setAttribute( "gridStrokeWidth", QString::number( mGridStrokeWidth ) );
elem.setAttribute( "gridColor", QgsSymbolLayerUtils::encodeColor( mGridColor ) ); elem.setAttribute( "gridColor", QgsSymbolLayerUtils::encodeColor( mGridColor ) );
elem.setAttribute( "horizontalGrid", mHorizontalGrid );
elem.setAttribute( "verticalGrid", mVerticalGrid );
elem.setAttribute( "showGrid", mShowGrid ); elem.setAttribute( "showGrid", mShowGrid );
elem.setAttribute( "backgroundColor", QgsSymbolLayerUtils::encodeColor( mBackgroundColor ) ); elem.setAttribute( "backgroundColor", QgsSymbolLayerUtils::encodeColor( mBackgroundColor ) );
elem.setAttribute( "wrapBehaviour", QString::number( static_cast< int >( mWrapBehaviour ) ) ); elem.setAttribute( "wrapBehaviour", QString::number( static_cast< int >( mWrapBehaviour ) ) );
Expand Down Expand Up @@ -187,6 +191,8 @@ bool QgsComposerTableV2::readXml( const QDomElement &itemElem, const QDomDocumen
mContentFontColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( "contentFontColor", "0,0,0,255" ) ); mContentFontColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( "contentFontColor", "0,0,0,255" ) );
mCellMargin = itemElem.attribute( "cellMargin", "1.0" ).toDouble(); mCellMargin = itemElem.attribute( "cellMargin", "1.0" ).toDouble();
mGridStrokeWidth = itemElem.attribute( "gridStrokeWidth", "0.5" ).toDouble(); mGridStrokeWidth = itemElem.attribute( "gridStrokeWidth", "0.5" ).toDouble();
mHorizontalGrid = itemElem.attribute( "horizontalGrid", "1" ).toInt();
mVerticalGrid = itemElem.attribute( "verticalGrid", "1" ).toInt();
mShowGrid = itemElem.attribute( "showGrid", "1" ).toInt(); mShowGrid = itemElem.attribute( "showGrid", "1" ).toInt();
mGridColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( "gridColor", "0,0,0,255" ) ); mGridColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( "gridColor", "0,0,0,255" ) );
mBackgroundColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( "backgroundColor", "255,255,255,0" ) ); mBackgroundColor = QgsSymbolLayerUtils::decodeColor( itemElem.attribute( "backgroundColor", "255,255,255,0" ) );
Expand Down Expand Up @@ -243,18 +249,18 @@ int QgsComposerTableV2::rowsVisible( double frameHeight, int firstRow, bool incl
if ( includeHeader ) if ( includeHeader )
{ {
//frame has a header //frame has a header
headerHeight = 2 * ( mShowGrid ? mGridStrokeWidth : 0 ) + 2 * mCellMargin + QgsComposerUtils::fontAscentMM( mHeaderFont ); headerHeight = 2 * ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 ) + 2 * mCellMargin + QgsComposerUtils::fontAscentMM( mHeaderFont );
} }
else else
{ {
//frame has no header text, just the stroke //frame has no header text, just the stroke
headerHeight = ( mShowGrid ? mGridStrokeWidth : 0 ); headerHeight = ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 );
} }


//remaining height available for content rows //remaining height available for content rows
double contentHeight = frameHeight - headerHeight; double contentHeight = frameHeight - headerHeight;


double gridHeight = ( mShowGrid ? mGridStrokeWidth : 0 ); double gridHeight = ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 );


int currentRow = firstRow; int currentRow = firstRow;
while ( contentHeight > 0 && currentRow <= mTableContents.count() ) while ( contentHeight > 0 && currentRow <= mTableContents.count() )
Expand All @@ -266,7 +272,7 @@ int QgsComposerTableV2::rowsVisible( double frameHeight, int firstRow, bool incl


if ( includeEmptyRows && contentHeight > 0 ) if ( includeEmptyRows && contentHeight > 0 )
{ {
double rowHeight = ( mShowGrid ? mGridStrokeWidth : 0 ) + 2 * mCellMargin + QgsComposerUtils::fontAscentMM( mContentFont ); double rowHeight = ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 ) + 2 * mCellMargin + QgsComposerUtils::fontAscentMM( mContentFont );
currentRow += qMax( floor( contentHeight / rowHeight ), 0.0 ); currentRow += qMax( floor( contentHeight / rowHeight ), 0.0 );
} }


Expand Down Expand Up @@ -341,7 +347,8 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
//calculate which rows to show in this frame //calculate which rows to show in this frame
QPair< int, int > rowsToShow = rowRange( frameIndex ); QPair< int, int > rowsToShow = rowRange( frameIndex );


double gridSize = mShowGrid ? mGridStrokeWidth : 0; double gridSizeX = mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0;
double gridSizeY = mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0;
double cellHeaderHeight = QgsComposerUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin; double cellHeaderHeight = QgsComposerUtils::fontAscentMM( mHeaderFont ) + 2 * mCellMargin;
double cellBodyHeight = QgsComposerUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin; double cellBodyHeight = QgsComposerUtils::fontAscentMM( mContentFont ) + 2 * mCellMargin;
QRectF cell; QRectF cell;
Expand Down Expand Up @@ -375,8 +382,8 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
//draw the text //draw the text
p->setPen( Qt::SolidLine ); p->setPen( Qt::SolidLine );


double currentX = gridSize; double currentX = gridSizeX;
double currentY = gridSize; double currentY = gridSizeY;
if ( drawHeader ) if ( drawHeader )
{ {
//draw the headers //draw the headers
Expand Down Expand Up @@ -425,12 +432,12 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd


currentX += mMaxColumnWidthMap[ col ]; currentX += mMaxColumnWidthMap[ col ];
currentX += mCellMargin; currentX += mCellMargin;
currentX += gridSize; currentX += gridSizeX;
col++; col++;
} }


currentY += cellHeaderHeight; currentY += cellHeaderHeight;
currentY += gridSize; currentY += gridSizeY;
} }


//now draw the body cells //now draw the body cells
Expand All @@ -441,7 +448,7 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
for ( int row = rowsToShow.first; row < rowsToShow.second; ++row ) for ( int row = rowsToShow.first; row < rowsToShow.second; ++row )
{ {
rowsDrawn++; rowsDrawn++;
currentX = gridSize; currentX = gridSizeX;
int col = 0; int col = 0;


//calculate row height //calculate row height
Expand Down Expand Up @@ -481,11 +488,11 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd


currentX += mMaxColumnWidthMap[ col ]; currentX += mMaxColumnWidthMap[ col ];
currentX += mCellMargin; currentX += mCellMargin;
currentX += gridSize; currentX += gridSizeX;
col++; col++;
} }
currentY += rowHeight; currentY += rowHeight;
currentY += gridSize; currentY += gridSizeY;
} }
} }


Expand All @@ -497,13 +504,13 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
//draw background of empty rows //draw background of empty rows
for ( int row = rowsDrawn; row < numberRowsToDraw; ++row ) for ( int row = rowsDrawn; row < numberRowsToDraw; ++row )
{ {
currentX = gridSize; currentX = gridSizeX;
int col = 0; int col = 0;


if ( mergeCells ) if ( mergeCells )
{ {
p->setBrush( backgroundColor( row + 10000, 0 ) ); p->setBrush( backgroundColor( row + 10000, 0 ) );
p->drawRect( QRectF( gridSize, currentY, mTableSize.width() - 2 * gridSize, cellBodyHeight ) ); p->drawRect( QRectF( gridSizeX, currentY, mTableSize.width() - 2 * gridSizeX, cellBodyHeight ) );
} }
else else
{ {
Expand All @@ -517,11 +524,11 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd


// currentY = gridSize; // currentY = gridSize;
currentX += mMaxColumnWidthMap[ col ] + 2 * mCellMargin; currentX += mMaxColumnWidthMap[ col ] + 2 * mCellMargin;
currentX += gridSize; currentX += gridSizeX;
col++; col++;
} }
} }
currentY += cellBodyHeight + gridSize; currentY += cellBodyHeight + gridSizeY;
} }
p->restore(); p->restore();
} }
Expand All @@ -534,15 +541,21 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
gridPen.setColor( mGridColor ); gridPen.setColor( mGridColor );
gridPen.setJoinStyle( Qt::MiterJoin ); gridPen.setJoinStyle( Qt::MiterJoin );
p->setPen( gridPen ); p->setPen( gridPen );
drawHorizontalGridLines( p, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader ); if ( mHorizontalGrid )
drawVerticalGridLines( p, mMaxColumnWidthMap, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader, mergeCells ); {
drawHorizontalGridLines( p, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader );
}
if ( mVerticalGrid )
{
drawVerticalGridLines( p, mMaxColumnWidthMap, rowsToShow.first, rowsToShow.second + numberEmptyRows, drawHeader, mergeCells );
}
} }


//special case - no records and table is set to ShowMessage mode //special case - no records and table is set to ShowMessage mode
if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage ) if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage )
{ {
double messageX = gridSize + mCellMargin; double messageX = gridSizeX + mCellMargin;
double messageY = gridSize + ( drawHeader ? cellHeaderHeight + gridSize : 0 ); double messageY = gridSizeY + ( drawHeader ? cellHeaderHeight + gridSizeY : 0 );
cell = QRectF( messageX, messageY, mTableSize.width() - messageX, cellBodyHeight ); cell = QRectF( messageX, messageY, mTableSize.width() - messageX, cellBodyHeight );
QgsComposerUtils::drawText( p, cell, mEmptyTableMessage, mContentFont, mContentFontColor, Qt::AlignHCenter, Qt::AlignVCenter, static_cast< Qt::TextFlag >( 0 ) ); QgsComposerUtils::drawText( p, cell, mEmptyTableMessage, mContentFont, mContentFontColor, Qt::AlignHCenter, Qt::AlignVCenter, static_cast< Qt::TextFlag >( 0 ) );
} }
Expand Down Expand Up @@ -729,6 +742,34 @@ void QgsComposerTableV2::setGridColor( const QColor &color )
emit changed(); emit changed();
} }


void QgsComposerTableV2::setHorizontalGrid( const bool horizontalGrid )
{
if ( horizontalGrid == mHorizontalGrid )
{
return;
}

mHorizontalGrid = horizontalGrid;
//since grid spacing has changed, we need to recalculate the table size
recalculateTableSize();

emit changed();
}

void QgsComposerTableV2::setVerticalGrid( const bool verticalGrid )
{
if ( verticalGrid == mVerticalGrid )
{
return;
}

mVerticalGrid = verticalGrid;
//since grid spacing has changed, we need to recalculate the table size
recalculateTableSize();

emit changed();
}

void QgsComposerTableV2::setBackgroundColor( const QColor &color ) void QgsComposerTableV2::setBackgroundColor( const QColor &color )
{ {
if ( color == mBackgroundColor ) if ( color == mBackgroundColor )
Expand Down Expand Up @@ -1002,7 +1043,7 @@ double QgsComposerTableV2::totalWidth()
totalWidth += maxColWidthIt.value(); totalWidth += maxColWidthIt.value();
} }
totalWidth += ( 2 * mMaxColumnWidthMap.size() * mCellMargin ); totalWidth += ( 2 * mMaxColumnWidthMap.size() * mCellMargin );
totalWidth += ( mMaxColumnWidthMap.size() + 1 ) * ( mShowGrid ? mGridStrokeWidth : 0 ); totalWidth += ( mMaxColumnWidthMap.size() + 1 ) * ( mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0 );


return totalWidth; return totalWidth;
} }
Expand Down Expand Up @@ -1216,22 +1257,22 @@ void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<in
double tableHeight = 0; double tableHeight = 0;
if ( hasHeader ) if ( hasHeader )
{ {
tableHeight += ( mShowGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2 + QgsComposerUtils::fontAscentMM( mHeaderFont ); tableHeight += ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2 + QgsComposerUtils::fontAscentMM( mHeaderFont );
} }
tableHeight += ( mShowGrid ? mGridStrokeWidth : 0 ); tableHeight += ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 );
double headerHeight = tableHeight; double headerHeight = tableHeight;


double cellBodyHeight = QgsComposerUtils::fontAscentMM( mContentFont ); double cellBodyHeight = QgsComposerUtils::fontAscentMM( mContentFont );
for ( int row = firstRow; row < lastRow; ++row ) for ( int row = firstRow; row < lastRow; ++row )
{ {
double rowHeight = row < mTableContents.count() ? mMaxRowHeightMap[row + 1] : cellBodyHeight; double rowHeight = row < mTableContents.count() ? mMaxRowHeightMap[row + 1] : cellBodyHeight;
tableHeight += rowHeight + ( mShowGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2; tableHeight += rowHeight + ( mShowGrid && mHorizontalGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2;
} }


double halfGridStrokeWidth = ( mShowGrid ? mGridStrokeWidth : 0 ) / 2.0; double halfGridStrokeWidth = ( mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0 ) / 2.0;
double currentX = halfGridStrokeWidth; double currentX = halfGridStrokeWidth;
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, tableHeight - halfGridStrokeWidth ) ); painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, tableHeight - halfGridStrokeWidth ) );
currentX += ( mShowGrid ? mGridStrokeWidth : 0 ); currentX += ( mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0 );
QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin(); QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
int col = 1; int col = 1;
for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt ) for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
Expand All @@ -1246,7 +1287,7 @@ void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<in
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, headerHeight - halfGridStrokeWidth ) ); painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, headerHeight - halfGridStrokeWidth ) );
} }


currentX += ( mShowGrid ? mGridStrokeWidth : 0 ); currentX += ( mShowGrid && mVerticalGrid ? mGridStrokeWidth : 0 );
col++; col++;
} }
} }
Expand Down

0 comments on commit 47c1f6e

Please sign in to comment.