mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[FEATURE][composer] Add choice of display style for empty tables. Options
include hiding the entire table, showing empty cells, or displaying a set message in the table body. Sponsored by City of Uster, Switzerland.
This commit is contained in:
parent
c3ec4b9eb0
commit
14690d0716
@ -72,6 +72,14 @@ class QgsComposerAttributeTableV2 : QgsComposerTableV2
|
||||
* @see setSource
|
||||
*/
|
||||
ContentSource source() const;
|
||||
|
||||
/**Returns the source layer for the table, considering the table source mode. Eg,
|
||||
* if the table is set to atlas feature mode, then the source layer will be the
|
||||
* atlas coverage layer. If the table is set to layer attributes mode, then
|
||||
* the source layer will be the user specified vector layer.
|
||||
* @returns actual source layer
|
||||
*/
|
||||
QgsVectorLayer* sourceLayer();
|
||||
|
||||
/**Sets the vector layer from which to display feature attributes
|
||||
* @param layer Vector layer for attribute table
|
||||
|
@ -45,6 +45,16 @@ class QgsComposerTableV2: QgsComposerMultiFrame
|
||||
AllFrames, /*!< headers shown on all frames */
|
||||
NoHeaders /*!< no headers shown for table */
|
||||
};
|
||||
|
||||
/*! Controls how empty tables are displayed
|
||||
*/
|
||||
enum EmptyTableMode
|
||||
{
|
||||
HeadersOnly, /*!< show header rows only */
|
||||
HideTable, /*!< hides entire table if empty */
|
||||
DrawEmptyCells, /*!< draws empty cells */
|
||||
ShowMessage /*!< shows preset message instead of table contents*/
|
||||
};
|
||||
|
||||
QgsComposerTableV2( QgsComposition* composition /TransferThis/, bool createUndoCommands );
|
||||
QgsComposerTableV2();
|
||||
@ -62,6 +72,37 @@ class QgsComposerTableV2: QgsComposerMultiFrame
|
||||
* @see setCellMargin
|
||||
*/
|
||||
double cellMargin() const;
|
||||
|
||||
/**Sets the behaviour for empty tables with no content rows.
|
||||
* @param mode behaviour mode for empty tables
|
||||
* @see emptyTableBehaviour
|
||||
*/
|
||||
void setEmptyTableBehaviour( const EmptyTableMode mode );
|
||||
|
||||
/**Returns the behaviour mode for empty tables. This property controls
|
||||
* how the table is drawn if it contains no content rows.
|
||||
* @returns behaviour mode for empty tables
|
||||
* @see setEmptyTableBehaviour
|
||||
*/
|
||||
EmptyTableMode emptyTableBehaviour() const;
|
||||
|
||||
/**Sets the message for empty tables with no content rows. This message
|
||||
* is displayed in the table body if the empty table behaviour is
|
||||
* set to ShowMessage
|
||||
* @param message message to show for empty tables
|
||||
* @see emptyTableMessage
|
||||
* @see setEmptyTableBehaviour
|
||||
*/
|
||||
void setEmptyTableMessage( const QString message );
|
||||
|
||||
/**Returns the message for empty tables with no content rows. This message
|
||||
* is displayed in the table body if the empty table behaviour is
|
||||
* set to ShowMessage
|
||||
* @returns message to show for empty tables
|
||||
* @see setEmptyTableMessage
|
||||
* @see emptyTableBehaviour
|
||||
*/
|
||||
QString emptyTableMessage() const;
|
||||
|
||||
/**Sets the font used to draw header text in the table.
|
||||
* @param font font for header cells
|
||||
@ -305,12 +346,13 @@ class QgsComposerTableV2: QgsComposerMultiFrame
|
||||
* maximum width of text present in the column.
|
||||
* @param numberRows number of rows of content in table frame
|
||||
* @param hasHeader set to true if table frame includes header cells
|
||||
* @param mergeCells set to true to merge table content cells
|
||||
* @note not available in python bindings
|
||||
* @see drawVerticalGridLines
|
||||
* @see calculateMaxColumnWidths
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
//void drawVerticalGridLines( QPainter* painter, const QMap<int, double>& maxWidthMap, const int numberRows, const bool hasHeader ) const;
|
||||
//void drawVerticalGridLines( QPainter* painter, const QMap<int, double>& maxWidthMap, const int numberRows, const bool hasHeader, const bool mergeCells = false ) const;
|
||||
|
||||
/**Recalculates and updates the size of the table and all table frames.
|
||||
*/
|
||||
|
@ -47,6 +47,11 @@ QgsComposerAttributeTableWidget::QgsComposerAttributeTableWidget( QgsComposerAtt
|
||||
mResizeModeComboBox->addItem( tr( "Extend to next page" ), QgsComposerMultiFrame::ExtendToNextPage );
|
||||
mResizeModeComboBox->addItem( tr( "Repeat until finished" ), QgsComposerMultiFrame::RepeatUntilFinished );
|
||||
|
||||
mEmptyModeComboBox->addItem( tr( "Draw headers only" ), QgsComposerTableV2::HeadersOnly );
|
||||
mEmptyModeComboBox->addItem( tr( "Hide entire table" ), QgsComposerTableV2::HideTable );
|
||||
mEmptyModeComboBox->addItem( tr( "Draw empty cells" ), QgsComposerTableV2::DrawEmptyCells );
|
||||
mEmptyModeComboBox->addItem( tr( "Show set message" ), QgsComposerTableV2::ShowMessage );
|
||||
|
||||
bool atlasEnabled = atlasComposition() && atlasComposition()->enabled();
|
||||
mSourceComboBox->addItem( tr( "Layer features" ), QgsComposerAttributeTableV2::LayerAttributes );
|
||||
toggleAtlasSpecificControls( atlasEnabled );
|
||||
@ -494,6 +499,11 @@ void QgsComposerAttributeTableWidget::updateGuiElements()
|
||||
mHeaderHAlignmentComboBox->setCurrentIndex(( int )mComposerTable->headerHAlignment() );
|
||||
mHeaderModeComboBox->setCurrentIndex(( int )mComposerTable->headerMode() );
|
||||
|
||||
mEmptyModeComboBox->setCurrentIndex( mEmptyModeComboBox->findData( mComposerTable->emptyTableBehaviour() ) );
|
||||
mEmptyMessageLineEdit->setText( mComposerTable->emptyTableMessage() );
|
||||
mEmptyMessageLineEdit->setEnabled( mComposerTable->emptyTableBehaviour() == QgsComposerTableV2::ShowMessage );
|
||||
mEmptyMessageLabel->setEnabled( mComposerTable->emptyTableBehaviour() == QgsComposerTableV2::ShowMessage );
|
||||
|
||||
mResizeModeComboBox->setCurrentIndex( mResizeModeComboBox->findData( mComposerTable->resizeMode() ) );
|
||||
mAddFramePushButton->setEnabled( mComposerTable->resizeMode() == QgsComposerMultiFrame::UseExistingFrames );
|
||||
|
||||
@ -585,6 +595,8 @@ void QgsComposerAttributeTableWidget::blockAllSignals( bool b )
|
||||
mContentFontColorButton->blockSignals( b );
|
||||
mResizeModeComboBox->blockSignals( b );
|
||||
mRelationsComboBox->blockSignals( b );
|
||||
mEmptyModeComboBox->blockSignals( b );
|
||||
mEmptyMessageLineEdit->blockSignals( b );
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::setMaximumNumberOfFeatures( int n )
|
||||
@ -850,6 +862,44 @@ void QgsComposerAttributeTableWidget::on_mRelationsComboBox_currentIndexChanged(
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mEmptyModeComboBox_currentIndexChanged( int index )
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Change empty table behaviour" ) );
|
||||
mComposerTable->setEmptyTableBehaviour(( QgsComposerTableV2::EmptyTableMode ) mEmptyModeComboBox->itemData( index ).toInt() );
|
||||
composition->endMultiFrameCommand();
|
||||
mEmptyMessageLineEdit->setEnabled( mComposerTable->emptyTableBehaviour() == QgsComposerTableV2::ShowMessage );
|
||||
mEmptyMessageLabel->setEnabled( mComposerTable->emptyTableBehaviour() == QgsComposerTableV2::ShowMessage );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::on_mEmptyMessageLineEdit_editingFinished()
|
||||
{
|
||||
if ( !mComposerTable )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsComposition* composition = mComposerTable->composition();
|
||||
if ( composition )
|
||||
{
|
||||
composition->beginMultiFrameCommand( mComposerTable, tr( "Empty table message changed" ) );
|
||||
}
|
||||
mComposerTable->setEmptyTableMessage( mEmptyMessageLineEdit->text() );
|
||||
mComposerTable->update();
|
||||
if ( composition )
|
||||
{
|
||||
composition->endMultiFrameCommand();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsComposerAttributeTableWidget::toggleSourceControls()
|
||||
{
|
||||
switch ( mComposerTable->source() )
|
||||
|
@ -70,6 +70,8 @@ class QgsComposerAttributeTableWidget: public QgsComposerItemBaseWidget, private
|
||||
void on_mResizeModeComboBox_currentIndexChanged( int index );
|
||||
void on_mSourceComboBox_currentIndexChanged( int index );
|
||||
void on_mRelationsComboBox_currentIndexChanged( int index );
|
||||
void on_mEmptyModeComboBox_currentIndexChanged( int index );
|
||||
void on_mEmptyMessageLineEdit_editingFinished();
|
||||
|
||||
/**Inserts a new maximum number of features into the spin box (without the spinbox emitting a signal)*/
|
||||
void setMaximumNumberOfFeatures( int n );
|
||||
|
@ -24,6 +24,7 @@
|
||||
QgsComposerTableV2::QgsComposerTableV2( QgsComposition *composition, bool createUndoCommands )
|
||||
: QgsComposerMultiFrame( composition, createUndoCommands )
|
||||
, mCellMargin( 1.0 )
|
||||
, mEmptyTableMode( HeadersOnly )
|
||||
, mHeaderFontColor( Qt::black )
|
||||
, mHeaderHAlignment( FollowColumn )
|
||||
, mHeaderMode( FirstFrame )
|
||||
@ -63,6 +64,8 @@ QgsComposerTableV2::~QgsComposerTableV2()
|
||||
bool QgsComposerTableV2::writeXML( QDomElement& elem, QDomDocument & doc, bool ignoreFrames ) const
|
||||
{
|
||||
elem.setAttribute( "cellMargin", QString::number( mCellMargin ) );
|
||||
elem.setAttribute( "emptyTableMode", QString::number(( int )mEmptyTableMode ) );
|
||||
elem.setAttribute( "emptyTableMessage", mEmptyTableMessage );
|
||||
elem.setAttribute( "headerFont", mHeaderFont.toString() );
|
||||
elem.setAttribute( "headerFontColor", QgsSymbolLayerV2Utils::encodeColor( mHeaderFontColor ) );
|
||||
elem.setAttribute( "headerHAlignment", QString::number(( int )mHeaderHAlignment ) );
|
||||
@ -103,6 +106,8 @@ bool QgsComposerTableV2::readXML( const QDomElement &itemElem, const QDomDocumen
|
||||
return false;
|
||||
}
|
||||
|
||||
mEmptyTableMode = QgsComposerTableV2::EmptyTableMode( itemElem.attribute( "emptyTableMode", "0" ).toInt() );
|
||||
mEmptyTableMessage = itemElem.attribute( "emptyTableMessage", tr( "No matching records" ) );
|
||||
mHeaderFont.fromString( itemElem.attribute( "headerFont", "" ) );
|
||||
mHeaderFontColor = QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "headerFontColor", "0,0,0,255" ) );
|
||||
mHeaderHAlignment = QgsComposerTableV2::HeaderHAlignment( itemElem.attribute( "headerHAlignment", "0" ).toInt() );
|
||||
@ -229,6 +234,13 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &renderExtent, const
|
||||
return;
|
||||
}
|
||||
|
||||
bool emptyTable = mTableContents.length() == 0;
|
||||
if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::HideTable )
|
||||
{
|
||||
//empty table set to hide table mode, so don't draw anything
|
||||
return;
|
||||
}
|
||||
|
||||
//calculate which rows to show in this frame
|
||||
QPair< int, int > rowsToShow = rowRange( renderExtent, frameIndex );
|
||||
|
||||
@ -260,6 +272,8 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &renderExtent, const
|
||||
//calculate whether a header is required
|
||||
bool drawHeader = (( mHeaderMode == QgsComposerTableV2::FirstFrame && frameIndex < 1 )
|
||||
|| ( mHeaderMode == QgsComposerTableV2::AllFrames ) );
|
||||
//calculate whether drawing table contents is required
|
||||
bool drawContents = !( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage );
|
||||
|
||||
for ( ; columnIt != mColumns.constEnd(); ++columnIt )
|
||||
{
|
||||
@ -304,18 +318,21 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &renderExtent, const
|
||||
currentY += ( mShowGrid ? mGridStrokeWidth : 0 );
|
||||
}
|
||||
|
||||
//draw the attribute values
|
||||
for ( int row = rowsToShow.first; row < rowsToShow.second; ++row )
|
||||
if ( drawContents )
|
||||
{
|
||||
cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellBodyHeight );
|
||||
//draw the attribute values
|
||||
for ( int row = rowsToShow.first; row < rowsToShow.second; ++row )
|
||||
{
|
||||
cell = QRectF( currentX, currentY, mMaxColumnWidthMap[col], cellBodyHeight );
|
||||
|
||||
QVariant cellContents = mTableContents.at( row ).at( col );
|
||||
QString str = cellContents.toString();
|
||||
QVariant cellContents = mTableContents.at( row ).at( col );
|
||||
QString str = cellContents.toString();
|
||||
|
||||
QgsComposerUtils::drawText( p, cell, str, mContentFont, mContentFontColor, ( *columnIt )->hAlignment(), Qt::AlignVCenter, textFlag );
|
||||
QgsComposerUtils::drawText( p, cell, str, mContentFont, mContentFontColor, ( *columnIt )->hAlignment(), Qt::AlignVCenter, textFlag );
|
||||
|
||||
currentY += cellBodyHeight;
|
||||
currentY += ( mShowGrid ? mGridStrokeWidth : 0 );
|
||||
currentY += cellBodyHeight;
|
||||
currentY += ( mShowGrid ? mGridStrokeWidth : 0 );
|
||||
}
|
||||
}
|
||||
|
||||
currentX += mMaxColumnWidthMap[ col ];
|
||||
@ -324,17 +341,39 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &renderExtent, const
|
||||
col++;
|
||||
}
|
||||
|
||||
|
||||
//and the borders
|
||||
if ( mShowGrid )
|
||||
{
|
||||
int numberRowsToDraw = rowsToShow.second - rowsToShow.first;
|
||||
if ( mEmptyTableMode == QgsComposerTableV2::DrawEmptyCells )
|
||||
{
|
||||
numberRowsToDraw = rowsVisible( frameIndex );
|
||||
}
|
||||
bool mergeCells = false;
|
||||
if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage )
|
||||
{
|
||||
//draw a merged row for the empty table message
|
||||
numberRowsToDraw++;
|
||||
mergeCells = true;
|
||||
}
|
||||
|
||||
QPen gridPen;
|
||||
gridPen.setWidthF( mGridStrokeWidth );
|
||||
gridPen.setColor( mGridColor );
|
||||
gridPen.setJoinStyle( Qt::MiterJoin );
|
||||
p->setPen( gridPen );
|
||||
drawHorizontalGridLines( p, rowsToShow.second - rowsToShow.first, drawHeader );
|
||||
drawVerticalGridLines( p, mMaxColumnWidthMap, rowsToShow.second - rowsToShow.first, drawHeader );
|
||||
drawHorizontalGridLines( p, numberRowsToDraw, drawHeader );
|
||||
drawVerticalGridLines( p, mMaxColumnWidthMap, numberRowsToDraw, drawHeader, mergeCells );
|
||||
}
|
||||
|
||||
//special case - no records and table is set to ShowMessage mode
|
||||
if ( emptyTable && mEmptyTableMode == QgsComposerTableV2::ShowMessage )
|
||||
{
|
||||
double messageX = ( mShowGrid ? mGridStrokeWidth : 0 ) + mCellMargin;
|
||||
double messageY = ( mShowGrid ? mGridStrokeWidth : 0 ) +
|
||||
( drawHeader ? cellHeaderHeight + ( mShowGrid ? mGridStrokeWidth : 0 ) : 0 );
|
||||
cell = QRectF( messageX, messageY, mTableSize.width() - messageX, cellBodyHeight );
|
||||
QgsComposerUtils::drawText( p, cell, mEmptyTableMessage, mContentFont, mContentFontColor, Qt::AlignHCenter, Qt::AlignVCenter, ( Qt::TextFlag )0 );
|
||||
}
|
||||
|
||||
p->restore();
|
||||
@ -356,6 +395,36 @@ void QgsComposerTableV2::setCellMargin( const double margin )
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setEmptyTableBehaviour( const QgsComposerTableV2::EmptyTableMode mode )
|
||||
{
|
||||
if ( mode == mEmptyTableMode )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mEmptyTableMode = mode;
|
||||
|
||||
//since appearance has changed, we need to recalculate the table size
|
||||
recalculateTableSize();
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setEmptyTableMessage( const QString message )
|
||||
{
|
||||
if ( message == mEmptyTableMessage )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mEmptyTableMessage = message;
|
||||
|
||||
//since message has changed, we need to recalculate the table size
|
||||
recalculateTableSize();
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::setHeaderFont( const QFont &font )
|
||||
{
|
||||
if ( font == mHeaderFont )
|
||||
@ -683,7 +752,7 @@ void QgsComposerTableV2::drawHorizontalGridLines( QPainter *painter, const int r
|
||||
painter->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( mTableSize.width() - halfGridStrokeWidth, currentY ) );
|
||||
}
|
||||
|
||||
void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<int, double> &maxWidthMap, const int numberRows, const bool hasHeader ) const
|
||||
void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<int, double> &maxWidthMap, const int numberRows, const bool hasHeader, const bool mergeCells ) const
|
||||
{
|
||||
//vertical lines
|
||||
if ( numberRows < 1 && !hasHeader )
|
||||
@ -697,20 +766,30 @@ void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<in
|
||||
{
|
||||
tableHeight += ( mShowGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2 + QgsComposerUtils::fontAscentMM( mHeaderFont );
|
||||
}
|
||||
|
||||
tableHeight += numberRows * (( mShowGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2 + QgsComposerUtils::fontAscentMM( mContentFont ) );
|
||||
tableHeight += ( mShowGrid ? mGridStrokeWidth : 0 );
|
||||
double headerHeight = tableHeight;
|
||||
tableHeight += numberRows * (( mShowGrid ? mGridStrokeWidth : 0 ) + mCellMargin * 2 + QgsComposerUtils::fontAscentMM( mContentFont ) );
|
||||
|
||||
double halfGridStrokeWidth = ( mShowGrid ? mGridStrokeWidth : 0 ) / 2.0;
|
||||
double currentX = halfGridStrokeWidth;
|
||||
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, tableHeight - halfGridStrokeWidth ) );
|
||||
currentX += ( mShowGrid ? mGridStrokeWidth : 0 );
|
||||
QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
|
||||
int col = 1;
|
||||
for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
|
||||
{
|
||||
currentX += ( maxColWidthIt.value() + 2 * mCellMargin );
|
||||
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, tableHeight - halfGridStrokeWidth ) );
|
||||
if ( col == maxWidthMap.size() || !mergeCells )
|
||||
{
|
||||
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, tableHeight - halfGridStrokeWidth ) );
|
||||
}
|
||||
else if ( hasHeader )
|
||||
{
|
||||
painter->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, headerHeight - halfGridStrokeWidth ) );
|
||||
}
|
||||
|
||||
currentX += ( mShowGrid ? mGridStrokeWidth : 0 );
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,16 @@ class CORE_EXPORT QgsComposerTableV2: public QgsComposerMultiFrame
|
||||
NoHeaders /*!< no headers shown for table */
|
||||
};
|
||||
|
||||
/*! Controls how empty tables are displayed
|
||||
*/
|
||||
enum EmptyTableMode
|
||||
{
|
||||
HeadersOnly = 0, /*!< show header rows only */
|
||||
HideTable, /*!< hides entire table if empty */
|
||||
DrawEmptyCells, /*!< draws empty cells */
|
||||
ShowMessage /*!< shows preset message instead of table contents*/
|
||||
};
|
||||
|
||||
QgsComposerTableV2( QgsComposition* composition, bool createUndoCommands );
|
||||
QgsComposerTableV2();
|
||||
|
||||
@ -88,6 +98,37 @@ class CORE_EXPORT QgsComposerTableV2: public QgsComposerMultiFrame
|
||||
*/
|
||||
double cellMargin() const { return mCellMargin; }
|
||||
|
||||
/**Sets the behaviour for empty tables with no content rows.
|
||||
* @param mode behaviour mode for empty tables
|
||||
* @see emptyTableBehaviour
|
||||
*/
|
||||
void setEmptyTableBehaviour( const EmptyTableMode mode );
|
||||
|
||||
/**Returns the behaviour mode for empty tables. This property controls
|
||||
* how the table is drawn if it contains no content rows.
|
||||
* @returns behaviour mode for empty tables
|
||||
* @see setEmptyTableBehaviour
|
||||
*/
|
||||
EmptyTableMode emptyTableBehaviour() const { return mEmptyTableMode; }
|
||||
|
||||
/**Sets the message for empty tables with no content rows. This message
|
||||
* is displayed in the table body if the empty table behaviour is
|
||||
* set to ShowMessage
|
||||
* @param message message to show for empty tables
|
||||
* @see emptyTableMessage
|
||||
* @see setEmptyTableBehaviour
|
||||
*/
|
||||
void setEmptyTableMessage( const QString message );
|
||||
|
||||
/**Returns the message for empty tables with no content rows. This message
|
||||
* is displayed in the table body if the empty table behaviour is
|
||||
* set to ShowMessage
|
||||
* @returns message to show for empty tables
|
||||
* @see setEmptyTableMessage
|
||||
* @see emptyTableBehaviour
|
||||
*/
|
||||
QString emptyTableMessage() const { return mEmptyTableMessage; }
|
||||
|
||||
/**Sets the font used to draw header text in the table.
|
||||
* @param font font for header cells
|
||||
* @see headerFont
|
||||
@ -279,6 +320,12 @@ class CORE_EXPORT QgsComposerTableV2: public QgsComposerMultiFrame
|
||||
/**Margin between cell borders and cell text*/
|
||||
double mCellMargin;
|
||||
|
||||
/**Behaviour for empty tables*/
|
||||
EmptyTableMode mEmptyTableMode;
|
||||
|
||||
/**String to show in empty tables*/
|
||||
QString mEmptyTableMessage;
|
||||
|
||||
/**Header font*/
|
||||
QFont mHeaderFont;
|
||||
|
||||
@ -370,12 +417,13 @@ class CORE_EXPORT QgsComposerTableV2: public QgsComposerMultiFrame
|
||||
* maximum width of text present in the column.
|
||||
* @param numberRows number of rows of content in table frame
|
||||
* @param hasHeader set to true if table frame includes header cells
|
||||
* @param mergeCells set to true to merge table content cells
|
||||
* @note not available in python bindings
|
||||
* @see drawVerticalGridLines
|
||||
* @see calculateMaxColumnWidths
|
||||
* @note not available in python bindings
|
||||
*/
|
||||
void drawVerticalGridLines( QPainter* painter, const QMap<int, double>& maxWidthMap, const int numberRows, const bool hasHeader ) const;
|
||||
void drawVerticalGridLines( QPainter* painter, const QMap<int, double>& maxWidthMap, const int numberRows, const bool hasHeader, const bool mergeCells = false ) const;
|
||||
|
||||
/**Recalculates and updates the size of the table and all table frames.
|
||||
*/
|
||||
|
@ -45,9 +45,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<y>-195</y>
|
||||
<width>392</width>
|
||||
<height>918</height>
|
||||
<height>1020</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="mainLayout">
|
||||
@ -99,6 +99,16 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mRelationLabel">
|
||||
<property name="text">
|
||||
<string>Relation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="mRelationsComboBox"/>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QPushButton" name="mRefreshPushButton">
|
||||
<property name="text">
|
||||
@ -113,36 +123,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="mMarginLabel">
|
||||
<property name="text">
|
||||
<string>Margin</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mMarginSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="mRelationsComboBox"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="mRelationLabel">
|
||||
<property name="text">
|
||||
<string>Relation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -235,6 +215,87 @@
|
||||
<zorder>mMaxNumFeaturesLabel</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox_6">
|
||||
<property name="title">
|
||||
<string>Appearance</string>
|
||||
</property>
|
||||
<property name="syncGroup" stdset="0">
|
||||
<string notr="true">composeritem</string>
|
||||
</property>
|
||||
<property name="collapsed" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="mMarginLabel">
|
||||
<property name="text">
|
||||
<string>Cell margins</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>mMarginSpinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="mMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Display header</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="mHeaderModeComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>On first frame</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>On all frames</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No header</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Empty tables</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="mEmptyModeComboBox"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="mEmptyMessageLabel">
|
||||
<property name="text">
|
||||
<string>Message to display</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="mEmptyMessageLineEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mShowGridGroupCheckBox">
|
||||
<property name="title">
|
||||
@ -317,13 +378,6 @@
|
||||
<string>Table heading</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Display</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mHeaderHAlignmentComboBox">
|
||||
<property name="sizePolicy">
|
||||
@ -401,25 +455,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="mHeaderModeComboBox">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>On first frame</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>On all frames</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>No header</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -49,12 +49,10 @@ class TestQgsComposerTableV2: public QObject
|
||||
void attributeTableSetAttributes(); //test subset of attributes in table
|
||||
void attributeTableVisibleOnly(); //test displaying only visible attributes
|
||||
void attributeTableRender(); //test rendering attribute table
|
||||
|
||||
void manualColumnWidth(); //test setting manual column widths
|
||||
|
||||
void attributeTableEmpty(); //test empty modes for attribute table
|
||||
void attributeTableExtend();
|
||||
void attributeTableRepeat();
|
||||
|
||||
void attributeTableAtlasSource(); //test attribute table in atlas feature mode
|
||||
void attributeTableRelationSource(); //test attribute table in relation mode
|
||||
|
||||
@ -325,6 +323,33 @@ void TestQgsComposerTableV2::manualColumnWidth()
|
||||
QVERIFY( result );
|
||||
}
|
||||
|
||||
void TestQgsComposerTableV2::attributeTableEmpty()
|
||||
{
|
||||
mComposerAttributeTable->setMaximumNumberOfFeatures( 20 );
|
||||
//hide all features from table
|
||||
mComposerAttributeTable->setFeatureFilter( QString( "1=2" ) );
|
||||
mComposerAttributeTable->setFilterFeatures( true );
|
||||
|
||||
mComposerAttributeTable->setEmptyTableBehaviour( QgsComposerTableV2::HeadersOnly );
|
||||
QgsCompositionChecker checker( "composerattributetable_headersonly", mComposition );
|
||||
QVERIFY( checker.testComposition( mReport, 0 ) );
|
||||
|
||||
mComposerAttributeTable->setEmptyTableBehaviour( QgsComposerTableV2::HideTable );
|
||||
QgsCompositionChecker checker2( "composerattributetable_hidetable", mComposition );
|
||||
QVERIFY( checker2.testComposition( mReport, 0 ) );
|
||||
|
||||
mComposerAttributeTable->setEmptyTableBehaviour( QgsComposerTableV2::DrawEmptyCells );
|
||||
QgsCompositionChecker checker3( "composerattributetable_drawempty", mComposition );
|
||||
QVERIFY( checker3.testComposition( mReport, 0 ) );
|
||||
|
||||
mComposerAttributeTable->setEmptyTableBehaviour( QgsComposerTableV2::ShowMessage );
|
||||
mComposerAttributeTable->setEmptyTableMessage( "no rows" );
|
||||
QgsCompositionChecker checker4( "composerattributetable_showmessage", mComposition );
|
||||
QVERIFY( checker4.testComposition( mReport, 0 ) );
|
||||
|
||||
mComposerAttributeTable->setFilterFeatures( false );
|
||||
}
|
||||
|
||||
void TestQgsComposerTableV2::attributeTableExtend()
|
||||
{
|
||||
//test that adding and removing frames automatically does not result in a crash
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Loading…
x
Reference in New Issue
Block a user