[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:
Nyall Dawson 2014-09-22 22:59:30 +10:00
parent c3ec4b9eb0
commit 14690d0716
12 changed files with 367 additions and 78 deletions

View File

@ -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

View File

@ -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.
*/

View File

@ -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() )

View File

@ -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 );

View File

@ -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++;
}
}

View File

@ -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.
*/

View File

@ -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>

View File

@ -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