[FEATURE][layouts] Add validity check to flag when a map item

has an overview which is not linked to any existing maps
This commit is contained in:
Nyall Dawson 2019-01-10 13:53:54 +10:00
parent b80829ce59
commit fd001bbd4d
4 changed files with 134 additions and 0 deletions

View File

@ -17,8 +17,13 @@
#include "qgslayoutvaliditychecks.h"
#include "qgsvaliditycheckcontext.h"
#include "qgslayoutitemscalebar.h"
#include "qgslayoutitemmap.h"
#include "qgslayout.h"
//
// QgsLayoutScaleBarValidityCheck
//
QgsLayoutScaleBarValidityCheck *QgsLayoutScaleBarValidityCheck::create() const
{
return new QgsLayoutScaleBarValidityCheck();
@ -65,3 +70,59 @@ QList<QgsValidityCheckResult> QgsLayoutScaleBarValidityCheck::runCheck( const Qg
{
return mResults;
}
//
// QgsLayoutOverviewValidityCheck
//
QgsLayoutOverviewValidityCheck *QgsLayoutOverviewValidityCheck::create() const
{
return new QgsLayoutOverviewValidityCheck();
}
QString QgsLayoutOverviewValidityCheck::id() const
{
return QStringLiteral( "layout_overview_check" );
}
int QgsLayoutOverviewValidityCheck::checkType() const
{
return QgsAbstractValidityCheck::TypeLayoutCheck;
}
bool QgsLayoutOverviewValidityCheck::prepareCheck( const QgsValidityCheckContext *context, QgsFeedback * )
{
if ( context->type() != QgsValidityCheckContext::TypeLayoutContext )
return false;
const QgsLayoutValidityCheckContext *layoutContext = static_cast< const QgsLayoutValidityCheckContext * >( context );
if ( !layoutContext )
return false;
QList< QgsLayoutItemMap * > mapItems;
layoutContext->layout->layoutItems( mapItems );
for ( QgsLayoutItemMap *map : qgis::as_const( mapItems ) )
{
for ( int i = 0; i < map->overviews()->size(); ++i )
{
QgsLayoutItemMapOverview *overview = map->overviews()->overview( i );
if ( overview && overview->enabled() && !overview->linkedMap() )
{
QgsValidityCheckResult res;
res.type = QgsValidityCheckResult::Warning;
res.title = QObject::tr( "Overview is not linked to a map" );
const QString name = map->displayName().toHtmlEscaped();
res.detailedDescription = QObject::tr( "The map “%1” includes an overview (“%2”) which is not linked to a map item." ).arg( name, overview->name() );
mResults.append( res );
}
}
}
return true;
}
QList<QgsValidityCheckResult> QgsLayoutOverviewValidityCheck::runCheck( const QgsValidityCheckContext *, QgsFeedback * )
{
return mResults;
}

View File

@ -30,3 +30,17 @@ class APP_EXPORT QgsLayoutScaleBarValidityCheck : public QgsAbstractValidityChec
private:
QList<QgsValidityCheckResult> mResults;
};
class APP_EXPORT QgsLayoutOverviewValidityCheck : public QgsAbstractValidityCheck
{
public:
QgsLayoutOverviewValidityCheck *create() const override;
QString id() const override;
int checkType() const override;
bool prepareCheck( const QgsValidityCheckContext *context, QgsFeedback *feedback ) override;
QList< QgsValidityCheckResult > runCheck( const QgsValidityCheckContext *context, QgsFeedback *feedback ) override;
private:
QList<QgsValidityCheckResult> mResults;
};

View File

@ -1238,6 +1238,7 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
}
QgsApplication::validityCheckRegistry()->addCheck( new QgsLayoutScaleBarValidityCheck() );
QgsApplication::validityCheckRegistry()->addCheck( new QgsLayoutOverviewValidityCheck() );
mSplash->showMessage( tr( "Initializing file filters" ), Qt::AlignHCenter | Qt::AlignBottom );
qApp->processEvents();

View File

@ -45,6 +45,7 @@ class TestQgsLayoutValidityChecks : public QObject
void cleanup() {} // will be called after every testfunction.
void testScaleBarValidity();
void testOverviewValidity();
private:
QString mTestDataDir;
@ -100,6 +101,63 @@ void TestQgsLayoutValidityChecks::testScaleBarValidity()
QCOMPARE( res.size(), 0 );
}
void TestQgsLayoutValidityChecks::testOverviewValidity()
{
QgsProject p;
QgsLayout l( &p );
QgsLayoutItemMap *map1 = new QgsLayoutItemMap( &l );
l.addItem( map1 );
QgsLayoutValidityCheckContext context( &l );
QgsFeedback f;
// no overviews
QgsLayoutOverviewValidityCheck check;
QVERIFY( check.prepareCheck( &context, &f ) );
QList< QgsValidityCheckResult > res = check.runCheck( &context, &f );
QCOMPARE( res.size(), 0 );
// overview not linked to map
map1->overviews()->addOverview( new QgsLayoutItemMapOverview( QStringLiteral( "blah" ), map1 ) );
QgsLayoutOverviewValidityCheck check2;
QVERIFY( check2.prepareCheck( &context, &f ) );
res = check2.runCheck( &context, &f );
QCOMPARE( res.size(), 1 );
QCOMPARE( res.at( 0 ).type, QgsValidityCheckResult::Warning );
map1->overview()->setEnabled( false );
QgsLayoutOverviewValidityCheck check3;
QVERIFY( check3.prepareCheck( &context, &f ) );
res = check3.runCheck( &context, &f );
QCOMPARE( res.size(), 0 );
// now link a map
QgsLayoutItemMap *map2 = new QgsLayoutItemMap( &l );
l.addItem( map2 );
map1->overview()->setLinkedMap( map2 );
map1->overview()->setEnabled( true );
QgsLayoutOverviewValidityCheck check4;
QVERIFY( check4.prepareCheck( &context, &f ) );
res = check4.runCheck( &context, &f );
QCOMPARE( res.size(), 0 );
map1->overviews()->addOverview( new QgsLayoutItemMapOverview( QStringLiteral( "blah2" ), map1 ) );
QgsLayoutOverviewValidityCheck check5;
QVERIFY( check5.prepareCheck( &context, &f ) );
res = check5.runCheck( &context, &f );
QCOMPARE( res.size(), 1 );
QCOMPARE( res.at( 0 ).type, QgsValidityCheckResult::Warning );
map1->overviews()->addOverview( new QgsLayoutItemMapOverview( QStringLiteral( "blah3" ), map1 ) );
QgsLayoutOverviewValidityCheck check6;
QVERIFY( check6.prepareCheck( &context, &f ) );
res = check6.runCheck( &context, &f );
QCOMPARE( res.size(), 2 );
QCOMPARE( res.at( 0 ).type, QgsValidityCheckResult::Warning );
QCOMPARE( res.at( 1 ).type, QgsValidityCheckResult::Warning );
}
QGSTEST_MAIN( TestQgsLayoutValidityChecks )