Skip to content

Commit

Permalink
[FEATURE][composer] Vertical alignment control for attribute tables
Browse files Browse the repository at this point in the history
Sponsored by City of Uster
  • Loading branch information
nyalldawson committed Aug 18, 2015
1 parent 372534e commit 759f842
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 45 deletions.
20 changes: 20 additions & 0 deletions python/core/composer/qgscomposertablecolumn.sip
Expand Up @@ -65,6 +65,7 @@ class QgsComposerTableColumn: QObject
* @returns horizontal alignment.
* @note added in 2.3
* @see setHAlignment
* @see vAlignment
*/
Qt::AlignmentFlag hAlignment() const;

Expand All @@ -73,9 +74,28 @@ class QgsComposerTableColumn: QObject
* @param alignment horizontal alignment for cell.
* @note added in 2.3
* @see hAlignment
* @see setVAlignment
*/
void setHAlignment( Qt::AlignmentFlag alignment );

/** Returns the vertical alignment for a column, which controls the alignment
* used for drawing column values within cells.
* @returns vertical alignment.
* @note added in 2.12
* @see setVAlignment
* @see hAlignment
*/
Qt::AlignmentFlag vAlignment() const;

/** Sets the vertical alignment for a column, which controls the alignment
* used for drawing column values within cells.
* @param alignment vertical alignment for cell.
* @note added in 2.12
* @see vAlignment
* @see setHAlignment
*/
void setVAlignment( Qt::AlignmentFlag alignment );

/** Returns the attribute name or expression used for the column's values. This property
* is only used when the column is part of a QgsComposerAttributeTable.
* @returns attribute name or expression text for column
Expand Down
48 changes: 16 additions & 32 deletions src/app/composer/qgsattributeselectiondialog.cpp
Expand Up @@ -48,9 +48,20 @@ QWidget* QgsComposerColumnAlignmentDelegate::createEditor( QWidget* parent, cons

//create a combo box showing alignment options
QComboBox *comboBox = new QComboBox( parent );
QStringList alignments;
alignments << tr( "Left" ) << tr( "Center" ) << tr( "Right" );
comboBox->addItems( alignments );

comboBox->addItem( tr( "Top left" ), int( Qt::AlignTop | Qt::AlignLeft ) );
comboBox->addItem( tr( "Top center" ), int( Qt::AlignTop | Qt::AlignHCenter ) );
comboBox->addItem( tr( "Top right" ), int( Qt::AlignTop | Qt::AlignRight ) );
comboBox->addItem( tr( "Middle left" ), int( Qt::AlignVCenter | Qt::AlignLeft ) );
comboBox->addItem( tr( "Middle center" ), int( Qt::AlignVCenter | Qt::AlignHCenter ) );
comboBox->addItem( tr( "Middle right" ), int( Qt::AlignVCenter | Qt::AlignRight ) );
comboBox->addItem( tr( "Bottom left" ), int( Qt::AlignBottom | Qt::AlignLeft ) );
comboBox->addItem( tr( "Bottom center" ), int( Qt::AlignBottom | Qt::AlignHCenter ) );
comboBox->addItem( tr( "Bottom right" ), int( Qt::AlignBottom | Qt::AlignRight ) );

Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag )index.model()->data( index, Qt::EditRole ).toInt();
comboBox->setCurrentIndex( comboBox->findData( alignment ) );

return comboBox;
}

Expand All @@ -60,40 +71,13 @@ void QgsComposerColumnAlignmentDelegate::setEditorData( QWidget* editor, const Q

//set the value for the combobox
QComboBox *comboBox = static_cast<QComboBox*>( editor );
switch ( alignment )
{
case Qt::AlignHCenter:
comboBox->setCurrentIndex( 1 );
break;
case Qt::AlignRight:
comboBox->setCurrentIndex( 2 );
break;
case Qt::AlignLeft:
default:
comboBox->setCurrentIndex( 0 );
break;
}
comboBox->setCurrentIndex( comboBox->findData( alignment ) );
}

void QgsComposerColumnAlignmentDelegate::setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const
{
QComboBox *comboBox = static_cast<QComboBox*>( editor );
int value = comboBox->currentIndex();
Qt::AlignmentFlag alignment;
switch ( value )
{
case 1:
alignment = Qt::AlignHCenter;
break;
case 2:
alignment = Qt::AlignRight;
break;
case 0:
default:
alignment = Qt::AlignLeft;
break;
}

Qt::AlignmentFlag alignment = ( Qt::AlignmentFlag ) comboBox->itemData( comboBox->currentIndex() ).toInt();
model->setData( index, alignment, Qt::EditRole );
}

Expand Down
35 changes: 30 additions & 5 deletions src/core/composer/qgscomposerattributetablemodel.cpp
Expand Up @@ -105,18 +105,42 @@ QVariant QgsComposerAttributeTableColumnModel::data( const QModelIndex &index, i
switch ( column->hAlignment() )
{
case Qt::AlignHCenter:
return tr( "Center" );
switch ( column->vAlignment() )
{
case Qt::AlignTop:
return tr( "Top center" );
case Qt::AlignBottom:
return tr( "Bottom center" );
default:
return tr( "Middle center" );
}
case Qt::AlignRight:
return tr( "Right" );
switch ( column->vAlignment() )
{
case Qt::AlignTop:
return tr( "Top right" );
case Qt::AlignBottom:
return tr( "Bottom right" );
default:
return tr( "Middle right" );
}
case Qt::AlignLeft:
default:
return tr( "Left" );
switch ( column->vAlignment() )
{
case Qt::AlignTop:
return tr( "Top left" );
case Qt::AlignBottom:
return tr( "Bottom left" );
default:
return tr( "Middle left" );
}
}
}
else
{
//edit role
return column->hAlignment();
return int( column->hAlignment() | column->vAlignment() );
}
}

Expand Down Expand Up @@ -198,7 +222,8 @@ bool QgsComposerAttributeTableColumnModel::setData( const QModelIndex& index, co
emit dataChanged( index, index );
return true;
case 2:
column->setHAlignment(( Qt::AlignmentFlag )value.toInt() );
column->setHAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignHorizontal_Mask ) );
column->setVAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignVertical_Mask ) );
emit dataChanged( index, index );
return true;
default:
Expand Down
35 changes: 30 additions & 5 deletions src/core/composer/qgscomposerattributetablemodelv2.cpp
Expand Up @@ -105,18 +105,42 @@ QVariant QgsComposerAttributeTableColumnModelV2::data( const QModelIndex &index,
switch ( column->hAlignment() )
{
case Qt::AlignHCenter:
return tr( "Center" );
switch ( column->vAlignment() )
{
case Qt::AlignTop:
return tr( "Top center" );
case Qt::AlignBottom:
return tr( "Bottom center" );
default:
return tr( "Middle center" );
}
case Qt::AlignRight:
return tr( "Right" );
switch ( column->vAlignment() )
{
case Qt::AlignTop:
return tr( "Top right" );
case Qt::AlignBottom:
return tr( "Bottom right" );
default:
return tr( "Middle right" );
}
case Qt::AlignLeft:
default:
return tr( "Left" );
switch ( column->vAlignment() )
{
case Qt::AlignTop:
return tr( "Top left" );
case Qt::AlignBottom:
return tr( "Bottom left" );
default:
return tr( "Middle left" );
}
}
}
else
{
//edit role
return column->hAlignment();
return int( column->hAlignment() | column->vAlignment() );
}
}
case 3:
Expand Down Expand Up @@ -212,7 +236,8 @@ bool QgsComposerAttributeTableColumnModelV2::setData( const QModelIndex& index,
emit dataChanged( index, index );
return true;
case 2:
column->setHAlignment(( Qt::AlignmentFlag )value.toInt() );
column->setHAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignHorizontal_Mask ) );
column->setVAlignment( Qt::AlignmentFlag( value.toInt() & Qt::AlignVertical_Mask ) );
emit dataChanged( index, index );
return true;
case 3:
Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgscomposertable.cpp
Expand Up @@ -142,7 +142,7 @@ void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem*

const QgsAttributeMap &currentAttributeMap = *attIt;
QString str = currentAttributeMap[ col ].toString();
QgsComposerUtils::drawText( painter, cell, str, mContentFont, mContentFontColor, ( *columnIt )->hAlignment(), Qt::AlignVCenter, Qt::TextDontClip );
QgsComposerUtils::drawText( painter, cell, str, mContentFont, mContentFontColor, ( *columnIt )->hAlignment(), ( *columnIt )->vAlignment(), Qt::TextDontClip );

currentY += cellBodyHeight;
currentY += mGridStrokeWidth;
Expand Down
4 changes: 4 additions & 0 deletions src/core/composer/qgscomposertablecolumn.cpp
Expand Up @@ -20,6 +20,7 @@
QgsComposerTableColumn::QgsComposerTableColumn( const QString& heading ) :
mBackgroundColor( Qt::transparent ),
mHAlignment( Qt::AlignLeft ),
mVAlignment( Qt::AlignVCenter ),
mHeading( heading ),
mSortByRank( 0 ),
mSortOrder( Qt::AscendingOrder ),
Expand All @@ -45,6 +46,7 @@ bool QgsComposerTableColumn::writeXML( QDomElement& columnElem, QDomDocument& do
columnElem.appendChild( bgColorElem );

columnElem.setAttribute( "hAlignment", mHAlignment );
columnElem.setAttribute( "vAlignment", mVAlignment );

columnElem.setAttribute( "heading", mHeading );
columnElem.setAttribute( "attribute", mAttribute );
Expand All @@ -60,6 +62,7 @@ bool QgsComposerTableColumn::writeXML( QDomElement& columnElem, QDomDocument& do
bool QgsComposerTableColumn::readXML( const QDomElement& columnElem )
{
mHAlignment = ( Qt::AlignmentFlag )columnElem.attribute( "hAlignment", QString::number( Qt::AlignLeft ) ).toInt();
mVAlignment = ( Qt::AlignmentFlag )columnElem.attribute( "vAlignment", QString::number( Qt::AlignVCenter ) ).toInt();
mHeading = columnElem.attribute( "heading", "" );
mAttribute = columnElem.attribute( "attribute", "" );
mSortByRank = columnElem.attribute( "sortByRank", "0" ).toInt();
Expand Down Expand Up @@ -91,6 +94,7 @@ QgsComposerTableColumn* QgsComposerTableColumn::clone()
newColumn->setAttribute( mAttribute );
newColumn->setHeading( mHeading );
newColumn->setHAlignment( mHAlignment );
newColumn->setVAlignment( mVAlignment );
newColumn->setSortByRank( mSortByRank );
newColumn->setSortOrder( mSortOrder );
newColumn->setWidth( mWidth );
Expand Down
21 changes: 21 additions & 0 deletions src/core/composer/qgscomposertablecolumn.h
Expand Up @@ -87,6 +87,7 @@ class CORE_EXPORT QgsComposerTableColumn: public QObject
* @returns horizontal alignment.
* @note added in 2.3
* @see setHAlignment
* @see vAlignment
*/
Qt::AlignmentFlag hAlignment() const { return mHAlignment; }

Expand All @@ -95,9 +96,28 @@ class CORE_EXPORT QgsComposerTableColumn: public QObject
* @param alignment horizontal alignment for cell.
* @note added in 2.3
* @see hAlignment
* @see setVAlignment
*/
void setHAlignment( Qt::AlignmentFlag alignment ) { mHAlignment = alignment; }

/** Returns the vertical alignment for a column, which controls the alignment
* used for drawing column values within cells.
* @returns vertical alignment.
* @note added in 2.12
* @see setVAlignment
* @see hAlignment
*/
Qt::AlignmentFlag vAlignment() const { return mVAlignment; }

/** Sets the vertical alignment for a column, which controls the alignment
* used for drawing column values within cells.
* @param alignment vertical alignment for cell.
* @note added in 2.12
* @see vAlignment
* @see setHAlignment
*/
void setVAlignment( Qt::AlignmentFlag alignment ) { mVAlignment = alignment; }

/** Returns the attribute name or expression used for the column's values. This property
* is only used when the column is part of a QgsComposerAttributeTable.
* @returns attribute name or expression text for column
Expand Down Expand Up @@ -174,6 +194,7 @@ class CORE_EXPORT QgsComposerTableColumn: public QObject

QColor mBackgroundColor; //curently unused
Qt::AlignmentFlag mHAlignment;
Qt::AlignmentFlag mVAlignment;
QString mHeading;
QString mAttribute;
int mSortByRank;
Expand Down
2 changes: 1 addition & 1 deletion src/core/composer/qgscomposertablev2.cpp
Expand Up @@ -473,7 +473,7 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
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(), ( *columnIt )->vAlignment(), textFlag );

currentX += mMaxColumnWidthMap[ col ];
currentX += mCellMargin;
Expand Down
42 changes: 41 additions & 1 deletion tests/src/core/testqgscomposertablev2.cpp
Expand Up @@ -69,8 +69,8 @@ class TestQgsComposerTableV2 : public QObject
void attributeTableRelationSource(); //test attribute table in relation mode
void contentsContainsRow(); //test the contentsContainsRow function
void removeDuplicates(); //test removing duplicate rows

void multiLineText(); //test rendering a table with multiline text
void align(); //test alignment of table cells

private:
QgsComposition* mComposition;
Expand Down Expand Up @@ -663,5 +663,45 @@ void TestQgsComposerTableV2::multiLineText()
delete multiLineLayer;
}

void TestQgsComposerTableV2::align()
{
QgsVectorLayer* multiLineLayer = new QgsVectorLayer( "Point?field=col1:string&field=col2:string&field=col3:string", "multiline", "memory" );
QVERIFY( multiLineLayer->isValid() );
QgsFeature f1( multiLineLayer->dataProvider()->fields(), 1 );
f1.setAttribute( "col1", "multiline\nstring" );
f1.setAttribute( "col2", "singleline string" );
f1.setAttribute( "col3", "singleline" );
QgsFeature f2( multiLineLayer->dataProvider()->fields(), 2 );
f2.setAttribute( "col1", "singleline string" );
f2.setAttribute( "col2", "multiline\nstring" );
f2.setAttribute( "col3", "singleline" );
QgsFeature f3( multiLineLayer->dataProvider()->fields(), 3 );
f3.setAttribute( "col1", "singleline" );
f3.setAttribute( "col2", "singleline" );
f3.setAttribute( "col3", "multiline\nstring" );
QgsFeature f4( multiLineLayer->dataProvider()->fields(), 4 );
f4.setAttribute( "col1", "long triple\nline\nstring" );
f4.setAttribute( "col2", "double\nlinestring" );
f4.setAttribute( "col3", "singleline" );
multiLineLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 << f3 << f4 );

mFrame2->setSceneRect( QRectF( 5, 40, 100, 90 ) );

mComposerAttributeTable->setMaximumNumberOfFeatures( 20 );
mComposerAttributeTable->setVectorLayer( multiLineLayer );

mComposerAttributeTable->columns()->at( 0 )->setHAlignment( Qt::AlignLeft );
mComposerAttributeTable->columns()->at( 0 )->setVAlignment( Qt::AlignTop );
mComposerAttributeTable->columns()->at( 1 )->setHAlignment( Qt::AlignHCenter );
mComposerAttributeTable->columns()->at( 1 )->setVAlignment( Qt::AlignVCenter );
mComposerAttributeTable->columns()->at( 2 )->setHAlignment( Qt::AlignRight );
mComposerAttributeTable->columns()->at( 2 )->setVAlignment( Qt::AlignBottom );
QgsCompositionChecker checker( "composerattributetable_align", mComposition );
bool result = checker.testComposition( mReport );
QVERIFY( result );

delete multiLineLayer;
}

QTEST_MAIN( TestQgsComposerTableV2 )
#include "testqgscomposertablev2.moc"
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 759f842

Please sign in to comment.