|
QGIS API Documentation
master-6227475
|
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<QgsAttributes> 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 painter->setPen( Qt::SolidLine ); 00060 00061 //now draw the text 00062 double currentX = mGridStrokeWidth; 00063 double currentY; 00064 00065 QMap<int, QString> headerMap = getHeaderLabels(); 00066 QMap<int, QString>::const_iterator columnIt = headerMap.constBegin(); 00067 00068 for ( ; columnIt != headerMap.constEnd(); ++columnIt ) 00069 { 00070 currentY = mGridStrokeWidth; 00071 currentY += mLineTextDistance; 00072 currentY += fontAscentMillimeters( mHeaderFont ); 00073 currentX += mLineTextDistance; 00074 drawText( painter, currentX, currentY, columnIt.value(), mHeaderFont ); 00075 00076 currentY += mLineTextDistance; 00077 currentY += mGridStrokeWidth; 00078 00079 //draw the attribute values 00080 QList<QgsAttributes>::const_iterator attIt = attributeList.begin(); 00081 for ( ; attIt != attributeList.end(); ++attIt ) 00082 { 00083 currentY += fontAscentMillimeters( mContentFont ); 00084 currentY += mLineTextDistance; 00085 00086 QgsAttributes currentAttributeMap = *attIt; 00087 QString str = currentAttributeMap.at( columnIt.key() ).toString(); 00088 drawText( painter, currentX, currentY, str, mContentFont ); 00089 currentY += mLineTextDistance; 00090 currentY += mGridStrokeWidth; 00091 } 00092 00093 currentX += maxColumnWidthMap[columnIt.key()]; 00094 currentX += mLineTextDistance; 00095 currentX += mGridStrokeWidth; 00096 } 00097 00098 //and the borders 00099 if ( mShowGrid ) 00100 { 00101 QPen gridPen; 00102 gridPen.setWidthF( mGridStrokeWidth ); 00103 gridPen.setColor( mGridColor ); 00104 painter->setPen( gridPen ); 00105 drawHorizontalGridLines( painter, attributeList.size() ); 00106 drawVerticalGridLines( painter, maxColumnWidthMap ); 00107 } 00108 00109 //draw frame and selection boxes if necessary 00110 drawFrame( painter ); 00111 if ( isSelected() ) 00112 { 00113 drawSelectionBoxes( painter ); 00114 } 00115 } 00116 00117 void QgsComposerTable::adjustFrameToSize() 00118 { 00119 QList<QgsAttributes> attributes; 00120 if ( !getFeatureAttributes( attributes ) ) 00121 { 00122 return; 00123 } 00124 00125 QMap<int, double> maxWidthMap; 00126 if ( !calculateMaxColumnWidths( maxWidthMap, attributes ) ) 00127 { 00128 return; 00129 } 00130 adaptItemFrame( maxWidthMap, attributes ); 00131 } 00132 00133 bool QgsComposerTable::tableWriteXML( QDomElement& elem, QDomDocument & doc ) const 00134 { 00135 elem.setAttribute( "lineTextDist", QString::number( mLineTextDistance ) ); 00136 elem.setAttribute( "headerFont", mHeaderFont.toString() ); 00137 elem.setAttribute( "contentFont", mContentFont.toString() ); 00138 elem.setAttribute( "gridStrokeWidth", QString::number( mGridStrokeWidth ) ); 00139 elem.setAttribute( "gridColorRed", mGridColor.red() ); 00140 elem.setAttribute( "gridColorGreen", mGridColor.green() ); 00141 elem.setAttribute( "gridColorBlue", mGridColor.blue() ); 00142 elem.setAttribute( "showGrid", mShowGrid ); 00143 return _writeXML( elem, doc ); 00144 } 00145 00146 bool QgsComposerTable::tableReadXML( const QDomElement& itemElem, const QDomDocument& doc ) 00147 { 00148 if ( itemElem.isNull() ) 00149 { 00150 return false; 00151 } 00152 00153 mHeaderFont.fromString( itemElem.attribute( "headerFont", "" ) ); 00154 mContentFont.fromString( itemElem.attribute( "contentFont", "" ) ); 00155 mLineTextDistance = itemElem.attribute( "lineTextDist", "1.0" ).toDouble(); 00156 mGridStrokeWidth = itemElem.attribute( "gridStrokeWidth", "0.5" ).toDouble(); 00157 mShowGrid = itemElem.attribute( "showGrid", "1" ).toInt(); 00158 00159 //grid color 00160 int gridRed = itemElem.attribute( "gridColorRed", "0" ).toInt(); 00161 int gridGreen = itemElem.attribute( "gridColorGreen", "0" ).toInt(); 00162 int gridBlue = itemElem.attribute( "gridColorBlue", "0" ).toInt(); 00163 mGridColor = QColor( gridRed, gridGreen, gridBlue ); 00164 00165 //restore general composer item properties 00166 QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" ); 00167 if ( composerItemList.size() > 0 ) 00168 { 00169 QDomElement composerItemElem = composerItemList.at( 0 ).toElement(); 00170 _readXML( composerItemElem, doc ); 00171 } 00172 return true; 00173 } 00174 00175 bool QgsComposerTable::calculateMaxColumnWidths( QMap<int, double>& maxWidthMap, const QList<QgsAttributes>& attributeList ) const 00176 { 00177 maxWidthMap.clear(); 00178 QMap<int, QString> headerMap = getHeaderLabels(); 00179 QMap<int, QString>::const_iterator headerIt = headerMap.constBegin(); 00180 for ( ; headerIt != headerMap.constEnd(); ++headerIt ) 00181 { 00182 maxWidthMap.insert( headerIt.key(), textWidthMillimeters( mHeaderFont, headerIt.value() ) ); 00183 } 00184 00185 //go through all the attributes and adapt the max width values 00186 QList<QgsAttributes>::const_iterator attIt = attributeList.constBegin(); 00187 00188 QgsAttributeMap currentAttributeMap; 00189 double currentAttributeTextWidth; 00190 00191 for ( ; attIt != attributeList.constEnd(); ++attIt ) 00192 { 00193 for ( int i = 0; i < attIt->size(); ++i ) 00194 { 00195 currentAttributeTextWidth = textWidthMillimeters( mContentFont, attIt->at( i ).toString() ); 00196 if ( currentAttributeTextWidth > maxWidthMap[i] ) 00197 { 00198 maxWidthMap[i] = currentAttributeTextWidth; 00199 } 00200 } 00201 } 00202 return true; 00203 } 00204 00205 00206 00207 00208 00209 void QgsComposerTable::adaptItemFrame( const QMap<int, double>& maxWidthMap, const QList<QgsAttributes>& attributeList ) 00210 { 00211 //calculate height 00212 double totalHeight = fontAscentMillimeters( mHeaderFont ) + attributeList.size() * fontAscentMillimeters( mContentFont ) 00213 + ( attributeList.size() + 1 ) * mLineTextDistance * 2 + ( attributeList.size() + 2 ) * mGridStrokeWidth; 00214 00215 //adapt frame to total width 00216 double totalWidth = 0; 00217 QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin(); 00218 for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt ) 00219 { 00220 totalWidth += maxColWidthIt.value(); 00221 } 00222 totalWidth += ( 2 * maxWidthMap.size() * mLineTextDistance ); 00223 totalWidth += ( maxWidthMap.size() + 1 ) * mGridStrokeWidth; 00224 QTransform t = transform(); 00225 QgsComposerItem::setSceneRect( QRectF( t.dx(), t.dy(), totalWidth, totalHeight ) ); 00226 } 00227 00228 void QgsComposerTable::drawHorizontalGridLines( QPainter* p, int nAttributes ) 00229 { 00230 //horizontal lines 00231 double halfGridStrokeWidth = mGridStrokeWidth / 2.0; 00232 double currentY = halfGridStrokeWidth; 00233 p->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( rect().width() - halfGridStrokeWidth, currentY ) ); 00234 currentY += mGridStrokeWidth; 00235 currentY += ( fontAscentMillimeters( mHeaderFont ) + 2 * mLineTextDistance ); 00236 for ( int i = 0; i < nAttributes; ++i ) 00237 { 00238 p->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( rect().width() - halfGridStrokeWidth, currentY ) ); 00239 currentY += mGridStrokeWidth; 00240 currentY += ( fontAscentMillimeters( mContentFont ) + 2 * mLineTextDistance ); 00241 } 00242 p->drawLine( QPointF( halfGridStrokeWidth, currentY ), QPointF( rect().width() - halfGridStrokeWidth, currentY ) ); 00243 } 00244 00245 void QgsComposerTable::drawVerticalGridLines( QPainter* p, const QMap<int, double>& maxWidthMap ) 00246 { 00247 //vertical lines 00248 double halfGridStrokeWidth = mGridStrokeWidth / 2.0; 00249 double currentX = halfGridStrokeWidth; 00250 p->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, rect().height() - halfGridStrokeWidth ) ); 00251 currentX += mGridStrokeWidth; 00252 QMap<int, double>::const_iterator maxColWidthIt = maxWidthMap.constBegin(); 00253 for ( ; maxColWidthIt != maxWidthMap.constEnd(); ++maxColWidthIt ) 00254 { 00255 currentX += ( maxColWidthIt.value() + 2 * mLineTextDistance ); 00256 p->drawLine( QPointF( currentX, halfGridStrokeWidth ), QPointF( currentX, rect().height() - halfGridStrokeWidth ) ); 00257 currentX += mGridStrokeWidth; 00258 } 00259 } 00260 00261 00262