00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "qgscomposertable.h"
00019 #include "qgslogger.h"
00020 #include <QPainter>
00021
00022 QgsComposerTable::QgsComposerTable( QgsComposition* composition ): QgsComposerItem( composition ), mLineTextDistance( 1.0 ), mShowGrid( true ), mGridStrokeWidth( 0.5 ), mGridColor( QColor( 0, 0, 0 ) )
00023 {
00024
00025 }
00026
00027 QgsComposerTable::~QgsComposerTable()
00028 {
00029
00030 }
00031
00032 void QgsComposerTable::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
00033 {
00034 if ( !painter )
00035 {
00036 return;
00037 }
00038
00039
00040 QList<QgsAttributeMap> attributeList;
00041 if ( !getFeatureAttributes( attributeList ) )
00042 {
00043 return;
00044 }
00045
00046 QMap<int, double> maxColumnWidthMap;
00047
00048 calculateMaxColumnWidths( maxColumnWidthMap, attributeList );
00049
00050 adaptItemFrame( maxColumnWidthMap, attributeList );
00051
00052 drawBackground( painter );
00053
00054
00055 double currentX = mGridStrokeWidth;
00056 double currentY;
00057
00058 QMap<int, QString> headerMap = getHeaderLabels();
00059 QMap<int, QString>::const_iterator columnIt = headerMap.constBegin();
00060
00061 for ( ; columnIt != headerMap.constEnd(); ++columnIt )
00062 {
00063 currentY = mGridStrokeWidth;
00064 currentY += mLineTextDistance;
00065 currentY += fontAscentMillimeters( mHeaderFont );
00066 currentX += mLineTextDistance;
00067 drawText( painter, currentX, currentY, columnIt.value(), mHeaderFont );
00068
00069 currentY += mLineTextDistance;
00070 currentY += mGridStrokeWidth;
00071
00072
00073 QList<QgsAttributeMap>::const_iterator attIt = attributeList.begin();
00074 for ( ; attIt != attributeList.end(); ++attIt )
00075 {
00076 currentY += fontAscentMillimeters( mContentFont );
00077 currentY += mLineTextDistance;
00078
00079 QgsAttributeMap currentAttributeMap = *attIt;
00080 QgsAttributeMap::const_iterator attMapIt = currentAttributeMap.find( columnIt.key() );
00081 if ( attMapIt != currentAttributeMap.constEnd() )
00082 {
00083 drawText( painter, currentX, currentY, attMapIt.value().toString(), mContentFont );
00084 }
00085 currentY += mLineTextDistance;
00086 currentY += mGridStrokeWidth;
00087 }
00088
00089 currentX += maxColumnWidthMap[columnIt.key()];
00090 currentX += mLineTextDistance;
00091 currentX += mGridStrokeWidth;
00092 }
00093
00094
00095 if ( mShowGrid )
00096 {
00097 QPen gridPen;
00098 gridPen.setWidthF( mGridStrokeWidth );
00099 gridPen.setColor( mGridColor );
00100 painter->setPen( gridPen );
00101 drawHorizontalGridLines( painter, attributeList.size() );
00102 drawVerticalGridLines( painter, maxColumnWidthMap );
00103 }
00104
00105
00106 drawFrame( painter );
00107 if ( isSelected() )
00108 {
00109 drawSelectionBoxes( painter );
00110 }
00111 }
00112
00113 void QgsComposerTable::adjustFrameToSize()
00114 {
00115 QList<QgsAttributeMap> attributes;
00116 if ( !getFeatureAttributes( attributes ) )
00117 {
00118 return;
00119 }
00120
00121 QMap<int, double> maxWidthMap;
00122 if ( !calculateMaxColumnWidths( maxWidthMap, attributes ) )
00123 {
00124 return;
00125 }
00126 adaptItemFrame( maxWidthMap, attributes );
00127 }
00128
00129 bool QgsComposerTable::tableWriteXML( QDomElement& elem, QDomDocument & doc ) const
00130 {
00131 elem.setAttribute( "lineTextDist", mLineTextDistance );
00132 elem.setAttribute( "headerFont", mHeaderFont.toString() );
00133 elem.setAttribute( "contentFont", mContentFont.toString() );
00134 elem.setAttribute( "gridStrokeWidth", mGridStrokeWidth );
00135 elem.setAttribute( "gridColorRed", mGridColor.red() );
00136 elem.setAttribute( "gridColorGreen", mGridColor.green() );
00137 elem.setAttribute( "gridColorBlue", mGridColor.blue() );
00138 elem.setAttribute( "showGrid", mShowGrid );
00139 return _writeXML( elem, doc );
00140 }
00141
00142 bool QgsComposerTable::tableReadXML( const QDomElement& itemElem, const QDomDocument& doc )
00143 {
00144 if ( itemElem.isNull() )
00145 {
00146 return false;
00147 }
00148
00149 mHeaderFont.fromString( itemElem.attribute( "headerFont", "" ) );
00150 mContentFont.fromString( itemElem.attribute( "contentFont", "" ) );
00151 mLineTextDistance = itemElem.attribute( "lineTextDist", "1.0" ).toDouble();
00152 mGridStrokeWidth = itemElem.attribute( "gridStrokeWidth", "0.5" ).toDouble();
00153 mShowGrid = itemElem.attribute( "showGrid", "1" ).toInt();
00154
00155
00156 int gridRed = itemElem.attribute( "gridColorRed", "0" ).toInt();
00157 int gridGreen = itemElem.attribute( "gridColorGreen", "0" ).toInt();
00158 int gridBlue = itemElem.attribute( "gridColorBlue", "0" ).toInt();
00159 mGridColor = QColor( gridRed, gridGreen, gridBlue );
00160
00161
00162 QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
00163 if ( composerItemList.size() > 0 )
00164 {
00165 QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
00166 _readXML( composerItemElem, doc );
00167 }
00168 return true;
00169 }
00170
00171 bool QgsComposerTable::calculateMaxColumnWidths( QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeList ) const
00172 {
00173 maxWidthMap.clear();
00174 QMap<int, QString> headerMap = getHeaderLabels();
00175 QMap<int, QString>::const_iterator headerIt = headerMap.constBegin();
00176 for ( ; headerIt != headerMap.constEnd(); ++headerIt )
00177 {
00178 maxWidthMap.insert( headerIt.key(), textWidthMillimeters( mHeaderFont, headerIt.value() ) );
00179 }
00180
00181
00182 QList<QgsAttributeMap>::const_iterator attIt = attributeList.constBegin();
00183
00184 QgsAttributeMap currentAttributeMap;
00185 double currentAttributeTextWidth;
00186
00187 for ( ; attIt != attributeList.constEnd(); ++attIt )
00188 {
00189 currentAttributeMap = *attIt;
00190 QgsAttributeMap::const_iterator attMapIt = currentAttributeMap.constBegin();
00191 for ( ; attMapIt != currentAttributeMap.constEnd(); ++attMapIt )
00192 {
00193 currentAttributeTextWidth = textWidthMillimeters( mContentFont, attMapIt.value().toString() );
00194 if ( currentAttributeTextWidth > maxWidthMap[attMapIt.key()] )
00195 {
00196 maxWidthMap[attMapIt.key()] = currentAttributeTextWidth;
00197 }
00198 }
00199 }
00200 return true;
00201 }
00202
00203
00204
00205
00206
00207 void QgsComposerTable::adaptItemFrame( const QMap<int, double>& maxWidthMap, const QList<QgsAttributeMap>& attributeList )
00208 {
00209
00210 double totalHeight = fontAscentMillimeters( mHeaderFont ) + attributeList.size() * fontAscentMillimeters( mContentFont ) \
00211 + ( attributeList.size() + 1 ) * mLineTextDistance * 2 + ( attributeList.size() + 2 ) * mGridStrokeWidth;
00212
00213
00214 double totalWidth = 0;
00215 QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
00216 for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
00217 {
00218 totalWidth += maxColWidthIt.value();
00219 }
00220 totalWidth += ( 2 * maxWidthMap.size() * mLineTextDistance );
00221 totalWidth += ( maxWidthMap.size() + 1 ) * mGridStrokeWidth;
00222 QTransform t = transform();
00223 QgsComposerItem::setSceneRect( QRectF( t.dx(), t.dy(), totalWidth, totalHeight ) );
00224 }
00225
00226 void QgsComposerTable::drawHorizontalGridLines( QPainter* p, int nAttributes )
00227 {
00228
00229 double halfGridStrokeWidth = mGridStrokeWidth / 2.0;
00230 double currentY = halfGridStrokeWidth;
00231 p->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( rect().width() - halfGridStrokeWidth, currentY ) );
00232 currentY += mGridStrokeWidth;
00233 currentY += ( fontAscentMillimeters( mHeaderFont ) + 2 * mLineTextDistance );
00234 for ( int i = 0; i < nAttributes; ++i )
00235 {
00236 p->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( rect().width() - halfGridStrokeWidth, currentY ) );
00237 currentY += mGridStrokeWidth;
00238 currentY += ( fontAscentMillimeters( mContentFont ) + 2 * mLineTextDistance );
00239 }
00240 p->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( rect().width() - halfGridStrokeWidth, currentY ) );
00241 }
00242
00243 void QgsComposerTable::drawVerticalGridLines( QPainter* p, const QMap<int, double>& maxWidthMap )
00244 {
00245
00246 double halfGridStrokeWidth = mGridStrokeWidth / 2.0;
00247 double currentX = halfGridStrokeWidth;
00248 p->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, rect().height() - halfGridStrokeWidth ) );
00249 currentX += mGridStrokeWidth;
00250 QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin();
00251 for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt )
00252 {
00253 currentX += ( maxColWidthIt.value() + 2 * mLineTextDistance );
00254 p->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, rect().height() - halfGridStrokeWidth ) );
00255 currentX += mGridStrokeWidth;
00256 }
00257 }
00258
00259
00260