Skip to content
Permalink
Browse files

Remove use of special columns for composition/atlas

$atlasfeature/$atlasgeometry/$feature/etc have all been ported
to variables
  • Loading branch information
nyalldawson committed Sep 7, 2015
1 parent 183f401 commit 05c2e4de84bf902265840873efccba4fd880e4f7
@@ -1622,7 +1622,7 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
{
return;
}
atlasMap->setFilenamePattern( "'output_'||$feature" );
atlasMap->setFilenamePattern( "'output_'||@atlas_featurenumber" );
}

QSettings myQSettings;
@@ -2034,7 +2034,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
{
return;
}
atlasMap->setFilenamePattern( "'output_'||$feature" );
atlasMap->setFilenamePattern( "'output_'||@atlas_featurenumber" );
}

QSettings myQSettings;
@@ -2335,7 +2335,7 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
{
return;
}
atlasMap->setFilenamePattern( "'output_'||$feature" );
atlasMap->setFilenamePattern( "'output_'||@atlas_featurenumber" );
}

QSettings myQSettings;
@@ -33,7 +33,7 @@ QgsAtlasComposition::QgsAtlasComposition( QgsComposition* composition )
: mComposition( composition )
, mEnabled( false )
, mHideCoverage( false )
, mFilenamePattern( "'output_'||$feature" )
, mFilenamePattern( "'output_'||@atlas_featurenumber" )
, mCoverageLayer( 0 )
, mSingleFile( false )
, mSortFeatures( false )
@@ -42,15 +42,6 @@ QgsAtlasComposition::QgsAtlasComposition( QgsComposition* composition )
, mFilterFeatures( false )
{

// declare special columns with a default value
QgsExpression::setSpecialColumn( "$page", QVariant(( int )1 ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )1 ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$atlasfeatureid", QVariant(( int )0 ) );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( QgsFeature() ) );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( QgsGeometry() ) );

//listen out for layer removal
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersWillBeRemoved( QStringList ) ), this, SLOT( removeLayers( QStringList ) ) );
}
@@ -99,20 +90,6 @@ void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer )
}

mCoverageLayer = layer;

// update the number of features
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );

// Grab the first feature so that user can use it to test the style in rules.
if ( layer )
{
QgsFeature fet;
layer->getFeatures().nextFeature( fet );
QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.constGeometry() ) );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( fet ) );
}

emit coverageLayerChanged( layer );
}

@@ -291,7 +268,6 @@ int QgsAtlasComposition::updateFeatures()
qSort( mFeatureIds.begin(), mFeatureIds.end(), sorter );
}

QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );
emit numberFeaturesChanged( mFeatureIds.size() );

//jump to first feature if currently using an atlas preview
@@ -325,10 +301,6 @@ bool QgsAtlasComposition::beginRender()
return false;
}

// special columns for expressions
QgsExpression::setSpecialColumn( "$numpages", QVariant( mComposition->numPages() ) );
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) );

return true;
}

@@ -453,11 +425,6 @@ bool QgsAtlasComposition::prepareForFeature( const int featureI, const bool upda

QgsExpressionContext expressionContext = createExpressionContext();

QgsExpression::setSpecialColumn( "$atlasfeatureid", mCurrentFeature.id() );
QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *mCurrentFeature.constGeometry() ) );
QgsExpression::setSpecialColumn( "$atlasfeature", QVariant::fromValue( mCurrentFeature ) );
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );

// generate filename for current feature
if ( !evalFeatureFilename( expressionContext ) )
{
@@ -835,7 +802,7 @@ QgsExpressionContext QgsAtlasComposition::createExpressionContext()
if ( mComposition )
expressionContext << QgsExpressionContextUtils::compositionScope( mComposition );

expressionContext << new QgsExpressionContextScope( "Atlas" );
expressionContext.appendScope( QgsExpressionContextUtils::atlasScope( this ) );
if ( mCoverageLayer )
expressionContext.lastScope()->setFields( mCoverageLayer->fields() );
if ( mComposition && mComposition->atlasMode() != QgsComposition::AtlasOff )
@@ -297,7 +297,6 @@ QString QgsComposerLabel::displayText() const
QString displayText = mText;
replaceDateText( displayText );
QMap<QString, QVariant> subs = mSubstitutions;
subs[ "$page" ] = QVariant(( int )mComposition->itemPageNumber( this ) + 1 );

QScopedPointer<QgsExpressionContext> context( createExpressionContext() );
//overwrite layer/feature if they have been set via setExpressionContext
@@ -428,9 +428,6 @@ void QgsComposition::setNumPages( const int pages )
}
}

//update the corresponding variable
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )numPages() ) );

QgsProject::instance()->dirty( true );
updateBounds();

@@ -2617,15 +2614,12 @@ void QgsComposition::addPaperItem()
addItem( paperItem );
paperItem->setZValue( 0 );
mPages.push_back( paperItem );

QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )mPages.size() ) );
}

void QgsComposition::removePaperItems()
{
qDeleteAll( mPages );
mPages.clear();
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
}

void QgsComposition::deleteAndRemoveMultiFrames()
@@ -869,6 +869,77 @@ static QVariant fcnMapId( const QVariantList&, const QgsExpressionContext* conte
Q_NOWARN_DEPRECATED_POP
}

static QVariant fcnComposerNumPages( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "layout_numpages" ) )
return context->variable( "layout_numpages" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$numpages" );
Q_NOWARN_DEPRECATED_POP
}

static QVariant fcnComposerPage( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "layout_page" ) )
return context->variable( "layout_page" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$page" );
Q_NOWARN_DEPRECATED_POP
}

static QVariant fcnAtlasFeature( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "atlas_featurenumber" ) )
return context->variable( "atlas_featurenumber" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$feature" );
Q_NOWARN_DEPRECATED_POP
}

static QVariant fcnAtlasFeatureId( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "atlas_featureid" ) )
return context->variable( "atlas_featureid" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$atlasfeatureid" );
Q_NOWARN_DEPRECATED_POP
}


static QVariant fcnAtlasCurrentFeature( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "atlas_feature" ) )
return context->variable( "atlas_feature" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$atlasfeature" );
Q_NOWARN_DEPRECATED_POP
}

static QVariant fcnAtlasCurrentGeometry( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "atlas_geometry" ) )
return context->variable( "atlas_geometry" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$atlasgeometry" );
Q_NOWARN_DEPRECATED_POP
}

static QVariant fcnAtlasNumFeatures( const QVariantList&, const QgsExpressionContext* context, QgsExpression* )
{
if ( context && context->hasVariable( "atlas_totalfeatures" ) )
return context->variable( "atlas_totalfeatures" );

Q_NOWARN_DEPRECATED_PUSH
return QgsExpression::specialColumn( "$numfeatures" );
Q_NOWARN_DEPRECATED_POP
}

#define FEAT_FROM_CONTEXT(c, f) if (!c || !c->hasVariable(QgsExpressionContext::EXPR_FEATURE)) return QVariant(); \
QgsFeature f = qvariant_cast<QgsFeature>( c->variable( QgsExpressionContext::EXPR_FEATURE ) );

@@ -1982,6 +2053,13 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )
<< new StaticFunction( "$scale", 0, fcnScale, "Record" )
<< new StaticFunction( "$map", 0, fcnMapId, "deprecated" )
<< new StaticFunction( "$numpages", 0, fcnComposerNumPages, "deprecated" )
<< new StaticFunction( "$page", 0, fcnComposerPage, "deprecated" )
<< new StaticFunction( "$feature", 0, fcnAtlasFeature, "deprecated" )
<< new StaticFunction( "$atlasfeatureid", 0, fcnAtlasFeatureId, "deprecated" )
<< new StaticFunction( "$atlasfeature", 0, fcnAtlasCurrentFeature, "deprecated" )
<< new StaticFunction( "$atlasgeometry", 0, fcnAtlasCurrentGeometry, "deprecated" )
<< new StaticFunction( "$numfeatures", 0, fcnAtlasNumFeatures, "deprecated" )
<< new StaticFunction( "uuid", 0, fcnUuid, "Record", QString(), false, QStringList(), false, QStringList() << "$uuid" )
<< new StaticFunction( "get_feature", 3, fcnGetFeature, "Record", QString(), false, QStringList(), false, QStringList() << "getFeature" )
<< new StaticFunction( "layer_property", 2, fcnGetLayerProperty, "General" )
@@ -2047,33 +2125,6 @@ QVariant QgsExpression::specialColumn( const QString& name )

bool QgsExpression::hasSpecialColumn( const QString& name )
{
static bool initialized = false;
if ( !initialized )
{
// Pre-register special columns that will exist within QGIS so that expressions that may use them are parsed correctly.
// This is really sub-optimal, we should get rid of the special columns and instead have contexts in which some values
// are defined and some are not ($rownum makes sense only in field calculator, $scale only when rendering, $page only for composer etc.)

//pairs of column name to group name
QList< QPair<QString, QString> > lst;
lst << qMakePair( QString( "$page" ), QString( "Composer" ) );
lst << qMakePair( QString( "$feature" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$numpages" ), QString( "Composer" ) );
lst << qMakePair( QString( "$numfeatures" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$atlasfeatureid" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$atlasgeometry" ), QString( "Atlas" ) );
lst << qMakePair( QString( "$atlasfeature" ), QString( "Atlas" ) );

QList< QPair<QString, QString> >::const_iterator it = lst.constBegin();
for ( ; it != lst.constEnd(); ++it )
{
setSpecialColumn(( *it ).first, QVariant() );
gmSpecialColumnGroups[( *it ).first ] = ( *it ).second;
}

initialized = true;
}

if ( functionIndex( name ) != -1 )
return false;
return gmSpecialColumns.contains( name );
@@ -732,6 +732,7 @@ QgsExpressionContextScope* QgsExpressionContextUtils::atlasScope( const QgsAtlas
scope->setFeature( atlasFeature );
scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_feature", QVariant::fromValue( atlasFeature ), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_featureid", atlasFeature.id(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( "atlas_geometry", atlasFeature.constGeometry(), true ) );
}

return scope;
@@ -763,6 +764,7 @@ QgsExpressionContextScope *QgsExpressionContextUtils::composerItemScope( const Q
//add known composer item context variables
scope->addVariable( QgsExpressionContextScope::StaticVariable( "item_id", composerItem->id(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( "item_uuid", composerItem->uuid(), true ) );
scope->addVariable( QgsExpressionContextScope::StaticVariable( "layout_page", composerItem->page(), true ) );

return scope;
}
@@ -201,7 +201,7 @@ void TestQgsAtlasComposition::init()
// feature number label
mLabel2 = new QgsComposerLabel( mComposition );
mComposition->addComposerLabel( mLabel2 );
mLabel2->setText( "# [%$feature || ' / ' || $numfeatures%]" );
mLabel2->setText( "# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]" );
mLabel2->setFont( QgsFontUtils::getStandardTestFont() );
mLabel2->setSceneRect( QRectF( 150, 200, 60, 15 ) );

@@ -217,7 +217,7 @@ void TestQgsAtlasComposition::cleanup()

void TestQgsAtlasComposition::filename()
{
mAtlas->setFilenamePattern( "'output_' || $feature" );
mAtlas->setFilenamePattern( "'output_' || @atlas_featurenumber" );
mAtlas->beginRender();
for ( int fi = 0; fi < mAtlas->numFeatures(); ++fi )
{
@@ -48,7 +48,7 @@ class TestQgsComposerLabel : public QObject
void evaluation();
// test expression evaluation when a feature is set
void feature_evaluation();
// test "$page" expressions
// test page expressions
void page_evaluation();

void marginMethods(); //tests getting/setting margins
@@ -182,7 +182,7 @@ void TestQgsComposerLabel::page_evaluation()
{
mComposition->setNumPages( 2 );
{
mComposerLabel->setText( "[%$page||'/'||$numpages%]" );
mComposerLabel->setText( "[%@layout_page||'/'||@layout_numpages%]" );
QString evaluated = mComposerLabel->displayText();
QString expected = "1/2";
QCOMPARE( evaluated, expected );

0 comments on commit 05c2e4d

Please sign in to comment.
You can’t perform that action at this time.