Skip to content

Commit

Permalink
[browser] Allow data item providers a chance to implement QGIS project
Browse files Browse the repository at this point in the history
item creation and override default project file handling

If no provider is registered which handles QGIS project files,
then the default behavior is used as a fallback
  • Loading branch information
nyalldawson committed Nov 1, 2018
1 parent 850eae1 commit f0436df
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/core/qgsdataitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -878,14 +878,6 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
QString path = dir.absoluteFilePath( name );
QFileInfo fileInfo( path );

if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 ||
fileInfo.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) == 0 )
{
QgsDataItem *item = new QgsProjectItem( this, fileInfo.completeBaseName(), path );
children.append( item );
continue;
}

if ( fileInfo.suffix().compare( QLatin1String( "zip" ), Qt::CaseInsensitive ) == 0 ||
fileInfo.suffix().compare( QLatin1String( "tar" ), Qt::CaseInsensitive ) == 0 )
{
Expand All @@ -897,6 +889,7 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
}
}

bool createdItem = false;
for ( QgsDataItemProvider *provider : providers )
{
int capabilities = provider->capabilities();
Expand All @@ -911,6 +904,20 @@ QVector<QgsDataItem *> QgsDirectoryItem::createChildren()
if ( item )
{
children.append( item );
createdItem = true;
}
}

if ( !createdItem )
{
// if item is a QGIS project, and no specific item provider has overridden handling of
// project items, then use the default project item behavior
if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 ||
fileInfo.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) == 0 )
{
QgsDataItem *item = new QgsProjectItem( this, fileInfo.completeBaseName(), path );
children.append( item );
continue;
}
}

Expand Down
84 changes: 84 additions & 0 deletions tests/src/core/testqgsdataitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include "qgsmeshlayer.h"
#include "qgsapplication.h"
#include "qgslogger.h"
#include "qgsdataitemprovider.h"
#include "qgsdataitemproviderregistry.h"
#include "qgssettings.h"

/**
Expand All @@ -47,6 +49,7 @@ class TestQgsDataItem : public QObject
void testValid();
void testDirItemChildren();
void testLayerItemType();
void testProjectItemCreation();

private:
QgsDirectoryItem *mDirItem = nullptr;
Expand Down Expand Up @@ -218,8 +221,89 @@ void TestQgsDataItem::testLayerItemType()
QString(), QStringLiteral( "mdal" ) );
QVERIFY( layer->isValid() );
QCOMPARE( QgsLayerItem::typeFromMapLayer( layer.get() ), QgsLayerItem::Mesh );
}


class TestProjectDataItemProvider : public QgsDataItemProvider
{
public:
QString name() override { return QStringLiteral( "project_test" ); }
int capabilities() override { return QgsDataProvider::File; }
QgsDataItem *createDataItem( const QString &path, QgsDataItem *parentItem ) override
{
QFileInfo fileInfo( path );
if ( fileInfo.suffix().compare( QLatin1String( "qgs" ), Qt::CaseInsensitive ) == 0 || fileInfo.suffix().compare( QLatin1String( "qgz" ), Qt::CaseInsensitive ) == 0 )
{
return new QgsDataItem( QgsDataItem::Custom, parentItem, path, path );
}
return nullptr;
}
};

void TestQgsDataItem::testProjectItemCreation()
{
QgsDirectoryItem *dirItem = new QgsDirectoryItem( nullptr, QStringLiteral( "Test" ), mTestDataDir + QStringLiteral( "qgis_server/" ) );
QVector<QgsDataItem *> children = dirItem->createChildren();

// ensure that QgsProjectItem items were created
bool foundQgsProject = false;
bool foundQgzProject = false;
for ( QgsDataItem *child : children )
{
if ( child->type() == QgsDataItem::Project && child->path() == mTestDataDir + QStringLiteral( "qgis_server/test_project.qgs" ) )
{
foundQgsProject = true;
continue;
}
if ( child->type() == QgsDataItem::Project && child->path() == mTestDataDir + QStringLiteral( "qgis_server/test_project.qgz" ) )
{
foundQgzProject = true;
continue;
}
}
QVERIFY( foundQgsProject );
QVERIFY( foundQgzProject );
delete dirItem;

// now, add a specific provider which handles project files
QgsApplication::dataItemProviderRegistry()->addProvider( new TestProjectDataItemProvider() );

dirItem = new QgsDirectoryItem( nullptr, QStringLiteral( "Test" ), mTestDataDir + QStringLiteral( "qgis_server/" ) );
children = dirItem->createChildren();

// ensure that QgsProjectItem items were NOT created -- our test provider should have created custom items instead
foundQgsProject = false;
foundQgzProject = false;
bool foundCustomQgsProject = false;
bool foundCustomQgzProject = false;
for ( QgsDataItem *child : children )
{
if ( child->type() == QgsDataItem::Project && child->path() == mTestDataDir + QStringLiteral( "qgis_server/test_project.qgs" ) )
{
foundQgsProject = true;
continue;
}
if ( child->type() == QgsDataItem::Project && child->path() == mTestDataDir + QStringLiteral( "qgis_server/test_project.qgz" ) )
{
foundQgzProject = true;
continue;
}
if ( child->type() == QgsDataItem::Custom && child->path() == mTestDataDir + QStringLiteral( "qgis_server/test_project.qgs" ) )
{
foundCustomQgsProject = true;
continue;
}
if ( child->type() == QgsDataItem::Custom && child->path() == mTestDataDir + QStringLiteral( "qgis_server/test_project.qgz" ) )
{
foundCustomQgzProject = true;
continue;
}
}
QVERIFY( !foundQgsProject );
QVERIFY( !foundQgzProject );
QVERIFY( foundCustomQgsProject );
QVERIFY( foundCustomQgzProject );
delete dirItem;
}

QGSTEST_MAIN( TestQgsDataItem )
Expand Down

0 comments on commit f0436df

Please sign in to comment.