Quantum GIS API Documentation  1.8
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 )
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines