Quantum GIS API Documentation
1.7.4
|
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 ): 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 //getFeatureAttributes 00040 QList<QgsAttributeMap> attributeList; 00041 if ( !getFeatureAttributes( attributeList ) ) 00042 { 00043 return; 00044 } 00045 00046 QMap<int, double> maxColumnWidthMap; 00047 //check how much space each column needs 00048 calculateMaxColumnWidths( maxColumnWidthMap, attributeList ); 00049 //adapt item frame to max width / height 00050 adaptItemFrame( maxColumnWidthMap, attributeList ); 00051 00052 drawBackground( painter ); 00053 00054 //now draw the text 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 //draw the attribute values 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 //and the borders 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 //draw frame and selection boxes if necessary 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 //grid color 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 //restore general composer item properties 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 //go through all the attributes and adapt the max width values 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 //calculate height 00210 double totalHeight = fontAscentMillimeters( mHeaderFont ) + attributeList.size() * fontAscentMillimeters( mContentFont ) \ 00211 + ( attributeList.size() + 1 ) * mLineTextDistance * 2 + ( attributeList.size() + 2 ) * mGridStrokeWidth; 00212 00213 //adapt frame to total width 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 //horizontal lines 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 //vertical lines 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