@@ -35,6 +35,7 @@ QgsComposerTableV2::QgsComposerTableV2( QgsComposition *composition, bool create
3535 , mGridStrokeWidth( 0.5 )
3636 , mGridColor( Qt::black )
3737 , mBackgroundColor( Qt::white )
38+ , mWrapBehaviour( TruncateText )
3839{
3940
4041 if ( mComposition )
@@ -65,6 +66,7 @@ QgsComposerTableV2::QgsComposerTableV2()
6566 , mGridStrokeWidth( 0.5 )
6667 , mGridColor( Qt::black )
6768 , mBackgroundColor( Qt::white )
69+ , mWrapBehaviour( TruncateText )
6870{
6971
7072}
@@ -91,6 +93,7 @@ bool QgsComposerTableV2::writeXML( QDomElement& elem, QDomDocument & doc, bool i
9193 elem.setAttribute ( " gridColor" , QgsSymbolLayerV2Utils::encodeColor ( mGridColor ) );
9294 elem.setAttribute ( " showGrid" , mShowGrid );
9395 elem.setAttribute ( " backgroundColor" , QgsSymbolLayerV2Utils::encodeColor ( mBackgroundColor ) );
96+ elem.setAttribute ( " wrapBehaviour" , QString::number (( int )mWrapBehaviour ) );
9497
9598 // columns
9699 QDomElement displayColumnsElem = doc.createElement ( " displayColumns" );
@@ -142,6 +145,7 @@ bool QgsComposerTableV2::readXML( const QDomElement &itemElem, const QDomDocumen
142145 mShowGrid = itemElem.attribute ( " showGrid" , " 1" ).toInt ();
143146 mGridColor = QgsSymbolLayerV2Utils::decodeColor ( itemElem.attribute ( " gridColor" , " 0,0,0,255" ) );
144147 mBackgroundColor = QgsSymbolLayerV2Utils::decodeColor ( itemElem.attribute ( " backgroundColor" , " 255,255,255,0" ) );
148+ mWrapBehaviour = QgsComposerTableV2::WrapBehaviour ( itemElem.attribute ( " wrapBehaviour" , " 0" ).toInt () );
145149
146150 // restore column specifications
147151 qDeleteAll ( mColumns );
@@ -459,20 +463,23 @@ void QgsComposerTableV2::render( QPainter *p, const QRectF &, const int frameInd
459463 // currentY = gridSize;
460464 currentX += mCellMargin ;
461465
466+ QVariant cellContents = mTableContents .at ( row ).at ( col );
467+ QString str = cellContents.toString ();
468+
462469 Qt::TextFlag textFlag = ( Qt::TextFlag )0 ;
463- if (( *columnIt )->width () <= 0 )
470+ if (( *columnIt )->width () <= 0 && mWrapBehaviour == TruncateText )
464471 {
465472 // automatic column width, so we use the Qt::TextDontClip flag when drawing contents, as this works nicer for italicised text
466473 // which may slightly exceed the calculated width
467474 // if column size was manually set then we do apply text clipping, to avoid painting text outside of columns width
468475 textFlag = Qt::TextDontClip;
469476 }
477+ else if ( textRequiresWrapping ( str, ( *columnIt )->width (), mContentFont ) )
478+ {
479+ str = wrappedText ( str, ( *columnIt )->width (), mContentFont );
480+ }
470481
471482 cell = QRectF ( currentX, currentY, mMaxColumnWidthMap [col], rowHeight );
472-
473- QVariant cellContents = mTableContents .at ( row ).at ( col );
474- QString str = cellContents.toString ();
475-
476483 QgsComposerUtils::drawText ( p, cell, str, mContentFont , mContentFontColor , ( *columnIt )->hAlignment (), ( *columnIt )->vAlignment (), textFlag );
477484
478485 currentX += mMaxColumnWidthMap [ col ];
@@ -701,6 +708,19 @@ void QgsComposerTableV2::setBackgroundColor( const QColor &color )
701708 emit changed ();
702709}
703710
711+ void QgsComposerTableV2::setWrapBehaviour ( QgsComposerTableV2::WrapBehaviour behaviour )
712+ {
713+ if ( behaviour == mWrapBehaviour )
714+ {
715+ return ;
716+ }
717+
718+ mWrapBehaviour = behaviour;
719+ recalculateTableSize ();
720+
721+ emit changed ();
722+ }
723+
704724void QgsComposerTableV2::setColumns ( QgsComposerTableColumns columns )
705725{
706726 // remove existing columns
@@ -864,8 +884,15 @@ bool QgsComposerTableV2::calculateMaxRowHeights()
864884 col = 0 ;
865885 for ( ; colIt != rowIt->constEnd (); ++colIt )
866886 {
867- // height
868- heights[ row * cols + col ] = QgsComposerUtils::textHeightMM ( mContentFont , ( *colIt ).toString () );
887+ if ( textRequiresWrapping (( *colIt ).toString (), mColumns .at ( col )->width (), mContentFont ) )
888+ {
889+ // contents too wide for cell, need to wrap
890+ heights[ row * cols + col ] = QgsComposerUtils::textHeightMM ( mContentFont , wrappedText (( *colIt ).toString (), mColumns .at ( col )->width (), mContentFont ) );
891+ }
892+ else
893+ {
894+ heights[ row * cols + col ] = QgsComposerUtils::textHeightMM ( mContentFont , ( *colIt ).toString () );
895+ }
869896
870897 col++;
871898 }
@@ -1018,6 +1045,79 @@ void QgsComposerTableV2::drawVerticalGridLines( QPainter *painter, const QMap<in
10181045 drawVerticalGridLines ( painter, maxWidthMap, 100000 , 100000 + numberRows, hasHeader, mergeCells );
10191046}
10201047
1048+ bool QgsComposerTableV2::textRequiresWrapping ( const QString& text, double columnWidth, const QFont &font ) const
1049+ {
1050+ if ( columnWidth == 0 || mWrapBehaviour != WrapText )
1051+ return false ;
1052+
1053+ QStringList multiLineSplit = text.split ( " \n " );
1054+ double currentTextWidth = 0 ;
1055+ Q_FOREACH ( QString line, multiLineSplit )
1056+ {
1057+ currentTextWidth = qMax ( currentTextWidth, QgsComposerUtils::textWidthMM ( font, line ) );
1058+ }
1059+
1060+ return ( currentTextWidth > columnWidth );
1061+ }
1062+
1063+ QString QgsComposerTableV2::wrappedText ( const QString &value, double columnWidth, const QFont &font ) const
1064+ {
1065+ QStringList lines = value.split ( " \n " );
1066+ QStringList outLines;
1067+ Q_FOREACH ( QString line, lines )
1068+ {
1069+ if ( textRequiresWrapping ( line, columnWidth, font ) )
1070+ {
1071+ // first step is to identify words which must be on their own line (too long to fit)
1072+ QStringList words = line.split ( " " );
1073+ QStringList linesToProcess;
1074+ QString wordsInCurrentLine;
1075+ Q_FOREACH ( QString word, words )
1076+ {
1077+ if ( textRequiresWrapping ( word, columnWidth, font ) )
1078+ {
1079+ // too long to fit
1080+ if ( !wordsInCurrentLine.isEmpty () )
1081+ linesToProcess << wordsInCurrentLine;
1082+ wordsInCurrentLine.clear ();
1083+ linesToProcess << word;
1084+ }
1085+ else
1086+ {
1087+ if ( !wordsInCurrentLine.isEmpty () )
1088+ wordsInCurrentLine.append ( " " );
1089+ wordsInCurrentLine.append ( word );
1090+ }
1091+ }
1092+ if ( !wordsInCurrentLine.isEmpty () )
1093+ linesToProcess << wordsInCurrentLine;
1094+
1095+ Q_FOREACH ( QString line, linesToProcess )
1096+ {
1097+ QString remainingText = line;
1098+ int lastPos = remainingText.lastIndexOf ( " " );
1099+ while ( lastPos > -1 )
1100+ {
1101+ if ( !textRequiresWrapping ( remainingText.left ( lastPos ), columnWidth, font ) )
1102+ {
1103+ outLines << remainingText.left ( lastPos );
1104+ remainingText = remainingText.mid ( lastPos + 1 );
1105+ lastPos = 0 ;
1106+ }
1107+ lastPos = remainingText.lastIndexOf ( " " , lastPos - 1 );
1108+ }
1109+ outLines << remainingText;
1110+ }
1111+ }
1112+ else
1113+ {
1114+ outLines << line;
1115+ }
1116+ }
1117+
1118+ return outLines.join ( " \n " );
1119+ }
1120+
10211121void QgsComposerTableV2::drawVerticalGridLines ( QPainter *painter, const QMap<int , double > &maxWidthMap, int firstRow, int lastRow, bool hasHeader, bool mergeCells ) const
10221122{
10231123 // vertical lines
0 commit comments