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