Quantum GIS API Documentation
1.7.4
|
00001 /*************************************************************************** 00002 qgscomposerattributetable.cpp 00003 ----------------------------- 00004 begin : April 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 "qgscomposerattributetable.h" 00019 #include "qgscomposermap.h" 00020 #include "qgsmaplayerregistry.h" 00021 #include "qgsvectorlayer.h" 00022 00023 QgsComposerAttributeTableCompare::QgsComposerAttributeTableCompare(): mCurrentSortColumn( 0 ), mAscending( true ) 00024 { 00025 } 00026 00027 00028 bool QgsComposerAttributeTableCompare::operator()( const QgsAttributeMap& m1, const QgsAttributeMap& m2 ) 00029 { 00030 QVariant v1 = m1[mCurrentSortColumn]; 00031 QVariant v2 = m2[mCurrentSortColumn]; 00032 00033 bool less = false; 00034 if ( v1.type() == QVariant::String && v2.type() == QVariant::String ) 00035 { 00036 less = v1.toString() < v2.toString(); 00037 } 00038 else 00039 { 00040 less = v1.toDouble() < v2.toDouble(); 00041 } 00042 return ( mAscending ? less : !less ); 00043 } 00044 00045 00046 QgsComposerAttributeTable::QgsComposerAttributeTable( QgsComposition* composition ): QgsComposerTable( composition ), mVectorLayer( 0 ), mComposerMap( 0 ), \ 00047 mMaximumNumberOfFeatures( 5 ), mShowOnlyVisibleFeatures( true ) 00048 { 00049 //set first vector layer from layer registry as default one 00050 QMap<QString, QgsMapLayer*> layerMap = QgsMapLayerRegistry::instance()->mapLayers(); 00051 QMap<QString, QgsMapLayer*>::const_iterator mapIt = layerMap.constBegin(); 00052 for ( ; mapIt != layerMap.constEnd(); ++mapIt ) 00053 { 00054 QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( mapIt.value() ); 00055 if ( vl ) 00056 { 00057 mVectorLayer = vl; 00058 break; 00059 } 00060 } 00061 connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( removeLayer( const QString& ) ) ); 00062 } 00063 00064 QgsComposerAttributeTable::~QgsComposerAttributeTable() 00065 { 00066 00067 } 00068 00069 void QgsComposerAttributeTable::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget ) 00070 { 00071 if ( mComposerMap && mComposerMap->isDrawing() ) 00072 { 00073 return; 00074 } 00075 QgsComposerTable::paint( painter, itemStyle, pWidget ); 00076 } 00077 00078 void QgsComposerAttributeTable::initializeAliasMap() 00079 { 00080 mFieldAliasMap.clear(); 00081 if ( mVectorLayer ) 00082 { 00083 QgsFieldMap fieldMap = mVectorLayer->pendingFields(); 00084 QgsFieldMap::const_iterator it = fieldMap.constBegin(); 00085 for ( ; it != fieldMap.constEnd(); ++it ) 00086 { 00087 QString currentAlias = mVectorLayer->attributeAlias( it.key() ); 00088 if ( !currentAlias.isEmpty() ) 00089 { 00090 mFieldAliasMap.insert( it.key(), currentAlias ); 00091 } 00092 } 00093 } 00094 } 00095 00096 void QgsComposerAttributeTable::setVectorLayer( QgsVectorLayer* vl ) 00097 { 00098 if ( vl != mVectorLayer ) 00099 { 00100 mDisplayAttributes.clear(); 00101 mVectorLayer = vl; 00102 initializeAliasMap(); 00103 } 00104 } 00105 00106 void QgsComposerAttributeTable::setComposerMap( const QgsComposerMap* map ) 00107 { 00108 if ( mComposerMap ) 00109 { 00110 QObject::disconnect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) ); 00111 } 00112 mComposerMap = map; 00113 if ( mComposerMap ) 00114 { 00115 QObject::connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( repaint() ) ); 00116 } 00117 } 00118 00119 bool QgsComposerAttributeTable::getFeatureAttributes( QList<QgsAttributeMap>& attributes ) 00120 { 00121 if ( !mVectorLayer ) 00122 { 00123 return false; 00124 } 00125 attributes.clear(); 00126 00127 QgsRectangle selectionRect; 00128 if ( mComposerMap && mShowOnlyVisibleFeatures ) 00129 { 00130 selectionRect = mComposerMap->extent(); 00131 } 00132 00133 if ( mDisplayAttributes.size() < 1 ) 00134 { 00135 mVectorLayer->select( mVectorLayer->pendingAllAttributesList(), selectionRect, mShowOnlyVisibleFeatures, mShowOnlyVisibleFeatures ); 00136 } 00137 else 00138 { 00139 mVectorLayer->select( mDisplayAttributes.toList(), selectionRect, mShowOnlyVisibleFeatures, mShowOnlyVisibleFeatures ); 00140 } 00141 QgsFeature f; 00142 int counter = 0; 00143 while ( mVectorLayer->nextFeature( f ) && counter < mMaximumNumberOfFeatures ) 00144 { 00145 attributes.push_back( f.attributeMap() ); 00146 ++counter; 00147 } 00148 00149 //sort the list, starting with the last attribute 00150 QgsComposerAttributeTableCompare c; 00151 for ( int i = mSortInformation.size() - 1; i >= 0; --i ) 00152 { 00153 c.setSortColumn( mSortInformation.at( i ).first ); 00154 c.setAscending( mSortInformation.at( i ).second ); 00155 qStableSort( attributes.begin(), attributes.end(), c ); 00156 } 00157 return true; 00158 } 00159 00160 QMap<int, QString> QgsComposerAttributeTable::getHeaderLabels() const 00161 { 00162 QMap<int, QString> header; 00163 if ( mVectorLayer ) 00164 { 00165 QgsFieldMap vectorFields = mVectorLayer->pendingFields(); 00166 QgsFieldMap::const_iterator fieldIt = vectorFields.constBegin(); 00167 for ( ; fieldIt != vectorFields.constEnd(); ++fieldIt ) 00168 { 00169 if ( mDisplayAttributes.size() > 0 && !mDisplayAttributes.contains( fieldIt.key() ) ) 00170 { 00171 continue; 00172 } 00173 header.insert( fieldIt.key(), attributeDisplayName( fieldIt.key(), fieldIt.value().name() ) ); 00174 } 00175 } 00176 return header; 00177 } 00178 00179 QString QgsComposerAttributeTable::attributeDisplayName( int attributeIndex, const QString& name ) const 00180 { 00181 QMap<int, QString>::const_iterator it = mFieldAliasMap.find( attributeIndex ); 00182 if ( it != mFieldAliasMap.constEnd() ) 00183 { 00184 return it.value(); 00185 } 00186 else 00187 { 00188 return name; 00189 } 00190 } 00191 00192 void QgsComposerAttributeTable::removeLayer( QString layerId ) 00193 { 00194 if ( mVectorLayer ) 00195 { 00196 if ( layerId == mVectorLayer->id() ) 00197 { 00198 mVectorLayer = 0; 00199 } 00200 } 00201 } 00202 00203 void QgsComposerAttributeTable::setSceneRect( const QRectF& rectangle ) 00204 { 00205 double titleHeight = 2 * mGridStrokeWidth + 2 * mLineTextDistance + fontAscentMillimeters( mHeaderFont ); 00206 double attributeHeight = mGridStrokeWidth + 2 * mLineTextDistance + fontAscentMillimeters( mContentFont ); 00207 if (( rectangle.height() - titleHeight ) > 0 ) 00208 { 00209 mMaximumNumberOfFeatures = ( rectangle.height() - titleHeight ) / attributeHeight; 00210 } 00211 else 00212 { 00213 mMaximumNumberOfFeatures = 0; 00214 } 00215 QgsComposerItem::setSceneRect( rectangle ); 00216 emit maximumNumerOfFeaturesChanged( mMaximumNumberOfFeatures ); 00217 } 00218 00219 bool QgsComposerAttributeTable::writeXML( QDomElement& elem, QDomDocument & doc ) const 00220 { 00221 QDomElement composerTableElem = doc.createElement( "ComposerAttributeTable" ); 00222 composerTableElem.setAttribute( "showOnlyVisibleFeatures", mShowOnlyVisibleFeatures ); 00223 00224 if ( mComposerMap ) 00225 { 00226 composerTableElem.setAttribute( "composerMap", mComposerMap->id() ); 00227 } 00228 else 00229 { 00230 composerTableElem.setAttribute( "composerMap", -1 ); 00231 } 00232 if ( mVectorLayer ) 00233 { 00234 composerTableElem.setAttribute( "vectorLayer", mVectorLayer->id() ); 00235 } 00236 00237 //display attributes 00238 QDomElement displayAttributesElem = doc.createElement( "displayAttributes" ); 00239 QSet<int>::const_iterator attIt = mDisplayAttributes.constBegin(); 00240 for ( ; attIt != mDisplayAttributes.constEnd(); ++attIt ) 00241 { 00242 QDomElement attributeIndexElem = doc.createElement( "attributeEntry" ); 00243 attributeIndexElem.setAttribute( "index", *attIt ); 00244 displayAttributesElem.appendChild( attributeIndexElem ); 00245 } 00246 composerTableElem.appendChild( displayAttributesElem ); 00247 00248 //alias map 00249 QDomElement aliasMapElem = doc.createElement( "attributeAliasMap" ); 00250 QMap<int, QString>::const_iterator aliasIt = mFieldAliasMap.constBegin(); 00251 for ( ; aliasIt != mFieldAliasMap.constEnd(); ++aliasIt ) 00252 { 00253 QDomElement mapEntryElem = doc.createElement( "aliasEntry" ); 00254 mapEntryElem.setAttribute( "key", aliasIt.key() ); 00255 mapEntryElem.setAttribute( "value", aliasIt.value() ); 00256 aliasMapElem.appendChild( mapEntryElem ); 00257 } 00258 composerTableElem.appendChild( aliasMapElem ); 00259 00260 //sort info 00261 QDomElement sortColumnsElem = doc.createElement( "sortColumns" ); 00262 QList< QPair<int, bool> >::const_iterator sortIt = mSortInformation.constBegin(); 00263 for ( ; sortIt != mSortInformation.constEnd(); ++sortIt ) 00264 { 00265 QDomElement columnElem = doc.createElement( "column" ); 00266 columnElem.setAttribute( "index", QString::number( sortIt->first ) ); 00267 columnElem.setAttribute( "ascending", sortIt->second == true ? "true" : "false" ); 00268 sortColumnsElem.appendChild( columnElem ); 00269 } 00270 composerTableElem.appendChild( sortColumnsElem ); 00271 elem.appendChild( composerTableElem ); 00272 bool ok = tableWriteXML( composerTableElem, doc ); 00273 return ok; 00274 } 00275 00276 bool QgsComposerAttributeTable::readXML( const QDomElement& itemElem, const QDomDocument& doc ) 00277 { 00278 if ( itemElem.isNull() ) 00279 { 00280 return false; 00281 } 00282 00283 mMaximumNumberOfFeatures = itemElem.attribute( "maxFeatures", "5" ).toInt(); 00284 mShowOnlyVisibleFeatures = itemElem.attribute( "showOnlyVisibleFeatures", "1" ).toInt(); 00285 00286 //composer map 00287 int composerMapId = itemElem.attribute( "composerMap", "-1" ).toInt(); 00288 if ( composerMapId == -1 ) 00289 { 00290 mComposerMap = 0; 00291 } 00292 00293 if ( composition() ) 00294 { 00295 mComposerMap = composition()->getComposerMapById( composerMapId ); 00296 } 00297 else 00298 { 00299 mComposerMap = 0; 00300 } 00301 00302 //vector layer 00303 QString layerId = itemElem.attribute( "vectorLayer", "not_existing" ); 00304 if ( layerId == "not_existing" ) 00305 { 00306 mVectorLayer = 0; 00307 } 00308 else 00309 { 00310 QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); 00311 if ( ml ) 00312 { 00313 mVectorLayer = dynamic_cast<QgsVectorLayer*>( ml ); 00314 } 00315 } 00316 00317 //restore display attribute map 00318 mDisplayAttributes.clear(); 00319 QDomNodeList displayAttributeList = itemElem.elementsByTagName( "displayAttributes" ); 00320 if ( displayAttributeList.size() > 0 ) 00321 { 00322 QDomElement displayAttributesElem = displayAttributeList.at( 0 ).toElement(); 00323 QDomNodeList attributeEntryList = displayAttributesElem.elementsByTagName( "attributeEntry" ); 00324 for ( int i = 0; i < attributeEntryList.size(); ++i ) 00325 { 00326 QDomElement attributeEntryElem = attributeEntryList.at( i ).toElement(); 00327 int index = attributeEntryElem.attribute( "index", "-1" ).toInt(); 00328 if ( index != -1 ) 00329 { 00330 mDisplayAttributes.insert( index ); 00331 } 00332 } 00333 } 00334 00335 //restore alias map 00336 mFieldAliasMap.clear(); 00337 QDomNodeList aliasMapNodeList = itemElem.elementsByTagName( "attributeAliasMap" ); 00338 if ( aliasMapNodeList.size() > 0 ) 00339 { 00340 QDomElement attributeAliasMapElem = aliasMapNodeList.at( 0 ).toElement(); 00341 QDomNodeList aliasMepEntryList = attributeAliasMapElem.elementsByTagName( "aliasEntry" ); 00342 for ( int i = 0; i < aliasMepEntryList.size(); ++i ) 00343 { 00344 QDomElement aliasEntryElem = aliasMepEntryList.at( i ).toElement(); 00345 int key = aliasEntryElem.attribute( "key", "-1" ).toInt(); 00346 QString value = aliasEntryElem.attribute( "value", "" ); 00347 mFieldAliasMap.insert( key, value ); 00348 } 00349 } 00350 00351 //restore sort columns 00352 mSortInformation.clear(); 00353 QDomElement sortColumnsElem = itemElem.firstChildElement( "sortColumns" ); 00354 if ( !sortColumnsElem.isNull() ) 00355 { 00356 QDomNodeList columns = sortColumnsElem.elementsByTagName( "column" ); 00357 for ( int i = 0; i < columns.size(); ++i ) 00358 { 00359 QDomElement columnElem = columns.at( i ).toElement(); 00360 int attribute = columnElem.attribute( "index" ).toInt(); 00361 bool ascending = columnElem.attribute( "ascending" ) == "true" ? true : false; 00362 mSortInformation.push_back( qMakePair( attribute, ascending ) ); 00363 } 00364 } 00365 bool success = tableReadXML( itemElem, doc ); 00366 emit itemChanged(); 00367 return success; 00368 }