QGIS API Documentation  master-6227475
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<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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines