void QgsComposerAttributeTableV2::setSource( const QgsComposerAttributeTableV2::ContentSource source ) { if ( source == mSource ) { return; } QgsVectorLayer* prevLayer = sourceLayer(); mSource = source; QgsVectorLayer* newLayer = sourceLayer(); if ( newLayer != prevLayer ) { //disconnect from previous layer if ( prevLayer ) { disconnect( prevLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); } //connect to new layer connect( newLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); if ( mSource == QgsComposerAttributeTableV2::AtlasFeature ) { mCurrentAtlasLayer = newLayer; } //layer has changed as a result of the source change, so reset column list resetColumns(); } refreshAttributes(); emit changed(); }
void QgsComposerAttributeTableV2::setRelationId( const QString relationId ) { if ( relationId == mRelationId ) { //no change return; } QgsVectorLayer* prevLayer = sourceLayer(); mRelationId = relationId; QgsRelation relation = QgsProject::instance()->relationManager()->relation( mRelationId ); QgsVectorLayer* newLayer = relation.referencingLayer(); if ( mSource == QgsComposerAttributeTableV2::RelationChildren && newLayer != prevLayer ) { if ( prevLayer ) { //disconnect from previous layer disconnect( prevLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); } //rebuild column list to match all columns from layer resetColumns(); //listen for modifications to layer and refresh table when they occur connect( newLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); } refreshAttributes(); emit changed(); }
void QgsComposerAttributeTableV2::setVectorLayer( QgsVectorLayer* layer ) { if ( layer == mVectorLayer ) { //no change return; } QgsVectorLayer* prevLayer = sourceLayer(); mVectorLayer = layer; if ( mSource == QgsComposerAttributeTableV2::LayerAttributes && layer != prevLayer ) { if ( prevLayer ) { //disconnect from previous layer disconnect( prevLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); } //rebuild column list to match all columns from layer resetColumns(); //listen for modifications to layer and refresh table when they occur connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); } refreshAttributes(); emit changed(); }
void QgsComposerAttributeTableV2::setDisplayedFields( const QStringList& fields, bool refresh ) { QgsVectorLayer* source = sourceLayer(); if ( !source ) { return; } //rebuild columns list, taking only fields contained in supplied list qDeleteAll( mColumns ); mColumns.clear(); QgsFields layerFields = source->fields(); if ( !fields.isEmpty() ) { Q_FOREACH ( const QString& field, fields ) { int attrIdx = layerFields.lookupField( field ); if ( attrIdx < 0 ) continue; QString currentAlias = source->attributeDisplayName( attrIdx ); QgsComposerTableColumn* col = new QgsComposerTableColumn; col->setAttribute( layerFields.at( attrIdx ).name() ); col->setHeading( currentAlias ); mColumns.append( col ); }
void QgsComposerAttributeTableV2::resetColumns() { QgsVectorLayer *source = sourceLayer(); if ( !source ) { return; } //remove existing columns qDeleteAll( mColumns ); mColumns.clear(); //rebuild columns list from vector layer fields int idx = 0; const QgsFields sourceFields = source->fields(); for ( const auto &field : sourceFields ) { QString currentAlias = source->attributeDisplayName( idx ); QgsComposerTableColumn *col = new QgsComposerTableColumn; col->setAttribute( field.name() ); col->setHeading( currentAlias ); mColumns.append( col ); idx++; } }
void QgsComposerAttributeTableV2::setDisplayAttributes( const QSet<int>& attr, bool refresh ) { QgsVectorLayer* source = sourceLayer(); if ( !source ) { return; } //rebuild columns list, taking only attributes with index in supplied QSet qDeleteAll( mColumns ); mColumns.clear(); const QgsFields& fields = source->pendingFields(); if ( !attr.empty() ) { QSet<int>::const_iterator attIt = attr.constBegin(); for ( ; attIt != attr.constEnd(); ++attIt ) { int attrIdx = ( *attIt ); if ( !fields.exists( attrIdx ) ) { continue; } QString currentAlias = source->attributeDisplayName( attrIdx ); QgsComposerTableColumn* col = new QgsComposerTableColumn; col->setAttribute( fields[attrIdx].name() ); col->setHeading( currentAlias ); mColumns.append( col ); } } else { //resetting, so add all attributes to columns for ( int idx = 0; idx < fields.count(); ++idx ) { QString currentAlias = source->attributeDisplayName( idx ); QgsComposerTableColumn* col = new QgsComposerTableColumn; col->setAttribute( fields[idx].name() ); col->setHeading( currentAlias ); mColumns.append( col ); } } if ( refresh ) { refreshAttributes(); } }
void QgsComposerAttributeTableV2::restoreFieldAliasMap( const QMap<int, QString>& map ) { QgsVectorLayer* source = sourceLayer(); if ( !source ) { return; } QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin(); for ( ; columnIt != mColumns.constEnd(); ++columnIt ) { int attrIdx = source->fieldNameIndex(( *columnIt )->attribute() ); if ( map.contains( attrIdx ) ) { ( *columnIt )->setHeading( map.value( attrIdx ) ); } else { ( *columnIt )->setHeading( source->attributeDisplayName( attrIdx ) ); } } }
bool QgsComposerAttributeTableV2::readXML( const QDomElement& itemElem, const QDomDocument& doc, bool ignoreFrames ) { if ( itemElem.isNull() ) { return false; } //read general table properties if ( !QgsComposerTableV2::readXML( itemElem, doc, ignoreFrames ) ) { return false; } QgsVectorLayer* prevLayer = sourceLayer(); if ( prevLayer ) { //disconnect from previous layer disconnect( prevLayer, SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); } mSource = QgsComposerAttributeTableV2::ContentSource( itemElem.attribute( "source", "0" ).toInt() ); mRelationId = itemElem.attribute( "relationId", "" ); if ( mSource == QgsComposerAttributeTableV2::AtlasFeature ) { mCurrentAtlasLayer = mComposition->atlasComposition().coverageLayer(); } mShowUniqueRowsOnly = itemElem.attribute( "showUniqueRowsOnly", "0" ).toInt(); mShowOnlyVisibleFeatures = itemElem.attribute( "showOnlyVisibleFeatures", "1" ).toInt(); mFilterToAtlasIntersection = itemElem.attribute( "filterToAtlasIntersection", "0" ).toInt(); mFilterFeatures = itemElem.attribute( "filterFeatures", "false" ) == "true" ? true : false; mFeatureFilter = itemElem.attribute( "featureFilter", "" ); mMaximumNumberOfFeatures = itemElem.attribute( "maxFeatures", "5" ).toInt(); //composer map int composerMapId = itemElem.attribute( "composerMap", "-1" ).toInt(); if ( composerMapId == -1 ) { mComposerMap = 0; } if ( composition() ) { mComposerMap = composition()->getComposerMapById( composerMapId ); } else { mComposerMap = 0; } if ( mComposerMap ) { //if we have found a valid map item, listen out to extent changes on it and refresh the table connect( mComposerMap, SIGNAL( extentChanged() ), this, SLOT( refreshAttributes() ) ); } //vector layer QString layerId = itemElem.attribute( "vectorLayer", "not_existing" ); if ( layerId == "not_existing" ) { mVectorLayer = 0; } else { QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( layerId ); if ( ml ) { mVectorLayer = dynamic_cast<QgsVectorLayer*>( ml ); } } //connect to new layer connect( sourceLayer(), SIGNAL( layerModified() ), this, SLOT( refreshAttributes() ) ); refreshAttributes(); emit changed(); return true; }
bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &contents ) { contents.clear(); if (( mSource == QgsComposerAttributeTableV2::AtlasFeature || mSource == QgsComposerAttributeTableV2::RelationChildren ) && !mComposition->atlasComposition().enabled() ) { //source mode requires atlas, but atlas disabled return false; } QgsVectorLayer* layer = sourceLayer(); if ( !layer ) { //no source layer return false; } //prepare filter expression std::auto_ptr<QgsExpression> filterExpression; bool activeFilter = false; if ( mFilterFeatures && !mFeatureFilter.isEmpty() ) { filterExpression = std::auto_ptr<QgsExpression>( new QgsExpression( mFeatureFilter ) ); if ( !filterExpression->hasParserError() ) { activeFilter = true; } } QgsRectangle selectionRect; if ( mComposerMap && mShowOnlyVisibleFeatures ) { selectionRect = *mComposerMap->currentMapExtent(); if ( layer && mComposition->mapSettings().hasCrsTransformEnabled() ) { //transform back to layer CRS QgsCoordinateTransform coordTransform( layer->crs(), mComposition->mapSettings().destinationCrs() ); try { selectionRect = coordTransform.transformBoundingBox( selectionRect, QgsCoordinateTransform::ReverseTransform ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); return false; } } } QgsFeatureRequest req; if ( mSource == QgsComposerAttributeTableV2::RelationChildren ) { QgsRelation relation = QgsProject::instance()->relationManager()->relation( mRelationId ); QgsFeature* atlasFeature = mComposition->atlasComposition().currentFeature(); if ( atlasFeature ) { req = relation.getRelatedFeaturesRequest( *atlasFeature ); } else { //no atlas feature, so empty table return true; } } if ( !selectionRect.isEmpty() ) req.setFilterRect( selectionRect ); req.setFlags( mShowOnlyVisibleFeatures ? QgsFeatureRequest::ExactIntersect : QgsFeatureRequest::NoFlags ); if ( mSource == QgsComposerAttributeTableV2::AtlasFeature && mComposition->atlasComposition().enabled() ) { //source mode is current atlas feature QgsFeature* atlasFeature = mComposition->atlasComposition().currentFeature(); if ( atlasFeature ) { req.setFilterFid( atlasFeature->id() ); } else { //no atlas feature, so empty table return true; } } QgsFeature f; int counter = 0; QgsFeatureIterator fit = layer->getFeatures( req ); while ( fit.nextFeature( f ) && counter < mMaximumNumberOfFeatures ) { //check feature against filter if ( activeFilter ) { QVariant result = filterExpression->evaluate( &f, layer->pendingFields() ); // skip this feature if the filter evaluation is false if ( !result.toBool() ) { continue; } } //check against atlas feature intersection if ( mFilterToAtlasIntersection ) { if ( !f.geometry() || ! mComposition->atlasComposition().enabled() ) { continue; } QgsFeature* atlasFeature = mComposition->atlasComposition().currentFeature(); if ( !atlasFeature || !atlasFeature->geometry() || !f.geometry()->intersects( atlasFeature->geometry() ) ) { //feature falls outside current atlas feature continue; } } QgsComposerTableRow currentRow; QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin(); for ( ; columnIt != mColumns.constEnd(); ++columnIt ) { int idx = layer->fieldNameIndex(( *columnIt )->attribute() ); if ( idx != -1 ) { currentRow << f.attributes()[idx]; } else { // Lets assume it's an expression QgsExpression* expression = new QgsExpression(( *columnIt )->attribute() ); expression->setCurrentRowNumber( counter + 1 ); expression->prepare( layer->pendingFields() ); QVariant value = expression->evaluate( f ) ; currentRow << value; } } if ( !mShowUniqueRowsOnly || !contentsContainsRow( contents, currentRow ) ) { contents << currentRow; ++counter; } } //sort the list, starting with the last attribute QgsComposerAttributeTableCompareV2 c; QList< QPair<int, bool> > sortColumns = sortAttributes(); for ( int i = sortColumns.size() - 1; i >= 0; --i ) { c.setSortColumn( sortColumns.at( i ).first ); c.setAscending( sortColumns.at( i ).second ); qStableSort( contents.begin(), contents.end(), c ); } recalculateTableSize(); return true; }