00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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, false, true );
00136 }
00137 else
00138 {
00139 mVectorLayer->select( mDisplayAttributes.toList(), selectionRect, false, true );
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
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->getLayerID() )
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->getLayerID() );
00235 }
00236
00237
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
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
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
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
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
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
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
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 return tableReadXML( itemElem, doc );
00366 }