Quantum GIS API Documentation  1.7.4
src/core/composer/qgscomposertable.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines